@@ -26,6 +26,8 @@ final class KlaviyoInternalTests: XCTestCase {
2626 KlaviyoInternal . resetProfileDataSubject ( )
2727 KlaviyoInternal . resetEventSubject ( )
2828 KlaviyoInternal . clearEventBuffer ( )
29+ IdentityStore . shared. update ( ProfileData ( ) )
30+ SDKConfigStore . shared. update ( KlaviyoConfig ( ) )
2931 }
3032
3133 // MARK: - Profile Data Tests
@@ -806,6 +808,71 @@ final class KlaviyoInternalTests: XCTestCase {
806808 XCTAssertEqual ( currentState. queue. count, 0 , " Queue should remain empty " )
807809 }
808810
811+ // MARK: - Shared store wiring
812+
813+ @MainActor
814+ func testSetupSharedStoresPushesIdentityOnChange( ) throws {
815+ let testStore = Store ( initialState: . test, reducer: KlaviyoReducer ( ) )
816+ klaviyoSwiftEnvironment. statePublisher = { testStore. state. eraseToAnyPublisher ( ) }
817+
818+ KlaviyoInternal . setupSharedStores ( )
819+
820+ _ = testStore. send ( . setEmail( " wired@example.com " ) )
821+
822+ let expectation = XCTestExpectation ( description: " IdentityStore reflects email " )
823+ DispatchQueue . main. async {
824+ XCTAssertEqual ( IdentityStore . shared. current. email, " wired@example.com " )
825+ expectation. fulfill ( )
826+ }
827+ wait ( for: [ expectation] , timeout: 1.0 )
828+ }
829+
830+ @MainActor
831+ func testSetupSharedStoresPushesAPIKeyOnChange( ) throws {
832+ // `.test` state is already `.initialized` with apiKey "foo".
833+ let testStore = Store ( initialState: . test, reducer: KlaviyoReducer ( ) )
834+ klaviyoSwiftEnvironment. statePublisher = { testStore. state. eraseToAnyPublisher ( ) }
835+
836+ let expectation = XCTestExpectation ( description: " SDKConfigStore reflects api key " )
837+ SDKConfigStore . shared. publisher
838+ . dropFirst ( ) // skip the CurrentValueSubject's initial emission
839+ . sink { config in
840+ if config. apiKey == " foo " { expectation. fulfill ( ) }
841+ }
842+ . store ( in: & cancellables)
843+
844+ KlaviyoInternal . setupSharedStores ( )
845+
846+ wait ( for: [ expectation] , timeout: 1.0 )
847+ XCTAssertEqual ( SDKConfigStore . shared. current. apiKey, " foo " )
848+ }
849+
850+ @MainActor
851+ func testResetClearsSharedStores( ) throws {
852+ // `.test` state is `.initialized` with apiKey "foo"; mirror it into the stores.
853+ let testStore = Store ( initialState: . test, reducer: KlaviyoReducer ( ) )
854+ klaviyoSwiftEnvironment. statePublisher = { testStore. state. eraseToAnyPublisher ( ) }
855+
856+ KlaviyoInternal . setupSharedStores ( )
857+ _ = testStore. send ( . setEmail( " wired@example.com " ) )
858+
859+ // Confirm the stores hold real data before resetting.
860+ let propagated = XCTestExpectation ( description: " identity mirrored before reset " )
861+ DispatchQueue . main. async {
862+ XCTAssertEqual ( IdentityStore . shared. current. email, " wired@example.com " )
863+ XCTAssertEqual ( SDKConfigStore . shared. current. apiKey, " foo " )
864+ propagated. fulfill ( )
865+ }
866+ wait ( for: [ propagated] , timeout: 1.0 )
867+
868+ KlaviyoInternal . resetProfileDataSubject ( )
869+
870+ XCTAssertEqual ( IdentityStore . shared. current, ProfileData ( ) ,
871+ " reset must clear identity back to empty " )
872+ XCTAssertNil ( SDKConfigStore . shared. current. apiKey,
873+ " reset must clear the API key " )
874+ }
875+
809876 @MainActor
810877 func testCreateGeofenceEvent_enqueuesEventWhenAPIKeyMatches( ) async throws {
811878 // Given: SDK is initialized with matching API key
0 commit comments