@@ -147,6 +147,10 @@ final class MainTabBarControllerTests: XCTestCase {
147147 let statusUpdates = PassthroughSubject < ProductImageUploadErrorInfo , Never > ( )
148148 let productImageUploader = MockProductImageUploader ( errors: statusUpdates. eraseToAnyPublisher ( ) )
149149
150+ let siteID : Int64 = 134
151+ stores. updateDefaultStore ( storeID: siteID)
152+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteID) )
153+
150154 guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
151155 return MainTabBarController ( coder: coder,
152156 noticePresenter: noticePresenter,
@@ -177,6 +181,10 @@ final class MainTabBarControllerTests: XCTestCase {
177181 let statusUpdates = PassthroughSubject < ProductImageUploadErrorInfo , Never > ( )
178182 let productImageUploader = MockProductImageUploader ( errors: statusUpdates. eraseToAnyPublisher ( ) )
179183
184+ let siteID : Int64 = 134
185+ stores. updateDefaultStore ( storeID: siteID)
186+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteID) )
187+
180188 guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
181189 return MainTabBarController ( coder: coder,
182190 noticePresenter: noticePresenter,
@@ -206,6 +214,10 @@ final class MainTabBarControllerTests: XCTestCase {
206214 let statusUpdates = PassthroughSubject < ProductImageUploadErrorInfo , Never > ( )
207215 let productImageUploader = MockProductImageUploader ( errors: statusUpdates. eraseToAnyPublisher ( ) )
208216
217+ let siteID : Int64 = 134
218+ stores. updateDefaultStore ( storeID: siteID)
219+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteID) )
220+
209221 guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
210222 return MainTabBarController ( coder: coder,
211223 noticePresenter: noticePresenter,
@@ -235,6 +247,10 @@ final class MainTabBarControllerTests: XCTestCase {
235247 let statusUpdates = PassthroughSubject < ProductImageUploadErrorInfo , Never > ( )
236248 let productImageUploader = MockProductImageUploader ( errors: statusUpdates. eraseToAnyPublisher ( ) )
237249
250+ let siteID : Int64 = 134
251+ stores. updateDefaultStore ( storeID: siteID)
252+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteID) )
253+
238254 guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
239255 return MainTabBarController ( coder: coder,
240256 noticePresenter: noticePresenter,
@@ -276,6 +292,10 @@ final class MainTabBarControllerTests: XCTestCase {
276292 let statusUpdates = PassthroughSubject < ProductImageUploadErrorInfo , Never > ( )
277293 let productImageUploader = MockProductImageUploader ( errors: statusUpdates. eraseToAnyPublisher ( ) )
278294
295+ let siteID : Int64 = 134
296+ stores. updateDefaultStore ( storeID: siteID)
297+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteID) )
298+
279299 guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
280300 return MainTabBarController ( coder: coder,
281301 noticePresenter: noticePresenter,
@@ -318,6 +338,10 @@ final class MainTabBarControllerTests: XCTestCase {
318338 let statusUpdates = PassthroughSubject < ProductImageUploadErrorInfo , Never > ( )
319339 let productImageUploader = MockProductImageUploader ( errors: statusUpdates. eraseToAnyPublisher ( ) )
320340
341+ let siteID : Int64 = 134
342+ stores. updateDefaultStore ( storeID: siteID)
343+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteID) )
344+
321345 guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
322346 return MainTabBarController ( coder: coder,
323347 noticePresenter: noticePresenter,
@@ -596,6 +620,96 @@ final class MainTabBarControllerTests: XCTestCase {
596620 assertEqual ( true , analyticsProvider. receivedProperties [ safe: indexOfEvent] ? [ " is_visible " ] as? Bool )
597621 }
598622
623+ func test_initial_tabs_visibility_is_set_from_cache( ) throws {
624+ // Given
625+ let siteID : Int64 = 1126
626+ let mockPOSEligibilityService = MockPOSEligibilityService ( )
627+ mockPOSEligibilityService. cachedTabVisibility [ siteID] = true
628+
629+ let userDefaults = UserDefaults ( suiteName: #function) !
630+ userDefaults. removePersistentDomain ( forName: #function)
631+ userDefaults. cacheBookingsTabVisibility ( siteID: siteID, isVisible: true )
632+
633+ let stores = MockStoresManager ( sessionManager: . makeForTesting( authenticated: true ) )
634+
635+ guard let tabBarController = UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
636+ return MainTabBarController ( coder: coder,
637+ stores: stores,
638+ posEligibilityService: mockPOSEligibilityService,
639+ userDefaults: userDefaults)
640+ } ) else {
641+ XCTFail ( " Failed to instantiate MainTabBarController " )
642+ return
643+ }
644+
645+ // When
646+ stores. updateDefaultStore ( storeID: siteID)
647+ XCTAssertNotNil ( tabBarController. view) // This triggers viewDidLoad
648+
649+ // Then
650+ let expectedTabs : [ WooTab ] = [ . myStore, . orders, . products, . bookings, . pointOfSale, . hubMenu]
651+ let visibleTabs = WooTab . visibleTabs ( isPOSTabVisible: true , isBookingsTabVisible: true )
652+ XCTAssertEqual ( tabBarController. viewControllers? . count, expectedTabs. count)
653+ XCTAssertEqual ( visibleTabs, expectedTabs)
654+ }
655+
656+ func test_switching_sites_applies_cached_tab_visibility( ) throws {
657+ // Arrange
658+ let siteA_ID : Int64 = 101
659+ let siteB_ID : Int64 = 202
660+
661+ // Site A: POS visible, Bookings not visible
662+ let mockPOSEligibilityService = MockPOSEligibilityService ( )
663+ mockPOSEligibilityService. cachedTabVisibility [ siteA_ID] = true
664+ mockPOSEligibilityService. cachedTabVisibility [ siteB_ID] = false
665+
666+ let userDefaults = UserDefaults ( suiteName: #function) !
667+ userDefaults. removePersistentDomain ( forName: #function)
668+ userDefaults. cacheBookingsTabVisibility ( siteID: siteA_ID, isVisible: false )
669+ userDefaults. cacheBookingsTabVisibility ( siteID: siteB_ID, isVisible: true )
670+
671+ let stores = MockStoresManager ( sessionManager: . makeForTesting( authenticated: true ) )
672+
673+ let tabBarController = try XCTUnwrap ( UIStoryboard ( name: " Main " , bundle: nil ) . instantiateInitialViewController ( creator: { coder in
674+ MainTabBarController ( coder: coder,
675+ stores: stores,
676+ posTabVisibilityCheckerFactory: { site in
677+ POSTabVisibilityChecker ( site: site, eligibilityService: mockPOSEligibilityService)
678+ } ,
679+ posEligibilityService: mockPOSEligibilityService,
680+ bookingsEligibilityCheckerFactory: { site in
681+ BookingsTabEligibilityChecker ( site: site, userDefaults: userDefaults)
682+ } ,
683+ userDefaults: userDefaults)
684+ } ) )
685+
686+ // Trigger viewDidLoad
687+ XCTAssertNotNil ( tabBarController. view)
688+
689+ // Action 1: Switch to Site A
690+ stores. updateDefaultStore ( storeID: siteA_ID)
691+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteA_ID) )
692+
693+ // Assert 1: Site A should have POS, but not Bookings.
694+ XCTAssertEqual ( tabBarController. viewControllers? . count, 5 , " There should be 5 tabs for Site A " )
695+ XCTAssertFalse ( tabBarController. tabRootViewControllers. contains ( where: { $0 is BookingsTabViewHostingController } ) ,
696+ " Bookings tab should not be visible for Site A " )
697+ XCTAssertTrue ( tabBarController. tabRootViewControllers. contains ( where: { $0 is POSTabViewController } ) ,
698+ " POS tab should be visible for Site A " )
699+
700+
701+ // Action 2: Switch to Site B
702+ stores. updateDefaultStore ( storeID: siteB_ID)
703+ stores. updateDefaultStore ( . fake( ) . copy ( siteID: siteB_ID) )
704+
705+ // Assert 2: Site B should have Bookings, but not POS.
706+ XCTAssertEqual ( tabBarController. viewControllers? . count, 5 , " There should be 5 tabs for Site B " )
707+ XCTAssertTrue ( tabBarController. tabRootViewControllers. contains ( where: { $0 is BookingsTabViewHostingController } ) ,
708+ " Bookings tab should be visible for Site B " )
709+ XCTAssertFalse ( tabBarController. tabRootViewControllers. contains ( where: { $0 is POSTabViewController } ) ,
710+ " POS tab should not be visible for Site B " )
711+ }
712+
599713 func test_bookings_tab_becomes_invisible_after_being_selected_when_initially_visible_then_eligibility_changes( ) throws {
600714 // Given
601715 let mockBookingsEligibilityChecker = MockAsyncBookingsEligibilityChecker ( )
0 commit comments