diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index e832e28f..4e041653 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -16,10 +16,10 @@ concurrency: jobs: library: name: Build and Run Unit Tests - runs-on: macos-13 + runs-on: macos-14 strategy: matrix: - xcode: ['14.3.1', '15.1'] + xcode: ['15.2', '15.4', '16.0'] config: ['debug', 'release'] steps: - uses: actions/checkout@v3 @@ -28,7 +28,7 @@ jobs: - name: Run ${{ matrix.config }} tests run: make CONFIG=${{ matrix.config }} test-library - - uses: kishikawakatsumi/xcresulttool@v1 + - uses: conradev/xcresulttool@v1.8.0 with: path: TestResults.xcresult if: success() || failure() diff --git a/Makefile b/Makefile index 7be00a64..1234344f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ CONFIG = debug -PLATFORM_IOS = iOS Simulator,name=iPhone 14 +PLATFORM_IOS = iOS Simulator,id=$(call udid_for,iOS,iPhone \d\+ Pro [^M]) + default: test-all @@ -15,3 +16,7 @@ test-library: -scheme klaviyo-swift-sdk-Package \ -destination platform="$$platform" || exit 1; \ done; + +define udid_for +$(shell xcrun simctl list devices available '$(1)' | grep '$(2)' | sort -r | head -1 | awk -F '[()]' '{ print $$(NF-3) }') +endef diff --git a/Sources/KlaviyoSwift/StateManagement/StateManagement.swift b/Sources/KlaviyoSwift/StateManagement/StateManagement.swift index 7ec9ea68..8d8a6764 100644 --- a/Sources/KlaviyoSwift/StateManagement/StateManagement.swift +++ b/Sources/KlaviyoSwift/StateManagement/StateManagement.swift @@ -320,7 +320,7 @@ struct KlaviyoReducer: ReducerProtocol { state.flushing = false return .none } - return .task { .sendRequest } + return .task { .sendRequest }.cancellable(id: RequestId.self) case .sendRequest: guard case .initialized = state.initalizationState else { diff --git a/Tests/KlaviyoCoreTests/TestUtils.swift b/Tests/KlaviyoCoreTests/TestUtils.swift index 4f1c0c78..bdcd86b4 100644 --- a/Tests/KlaviyoCoreTests/TestUtils.swift +++ b/Tests/KlaviyoCoreTests/TestUtils.swift @@ -62,10 +62,10 @@ let TEST_FAILURE_JSON_INVALID_EMAIL = """ """ let SAMPLE_PROPERTIES = [ - "blob": "blob", - "stuff": 2, - "hello": [ - "sub": "dict" + "Blob": "blob", + "Stuff": 2, + "Hello": [ + "Sub": "dict" ] ] as [String: Any] @@ -142,7 +142,7 @@ extension NetworkSession { } } -class TestJSONDecoder: JSONDecoder { +class TestJSONDecoder: JSONDecoder, @unchecked Sendable { override func decode(_: T.Type, from _: Data) throws -> T where T: Decodable { AppLifeCycleEvents.test as! T } diff --git a/Tests/KlaviyoCoreTests/__Snapshots__/EncodableTests/testEventPayload.1.json b/Tests/KlaviyoCoreTests/__Snapshots__/EncodableTests/testEventPayload.1.json index b7b9dc63..bc3bc2aa 100644 --- a/Tests/KlaviyoCoreTests/__Snapshots__/EncodableTests/testEventPayload.1.json +++ b/Tests/KlaviyoCoreTests/__Snapshots__/EncodableTests/testEventPayload.1.json @@ -25,19 +25,19 @@ "App ID" : "com.klaviyo.fooapp", "App Name" : "FooApp", "App Version" : "1.2.3", - "blob" : "blob", + "Blob" : "blob", "Device ID" : "fe-fi-fo-fum", "Device Manufacturer" : "Orange", "Device Model" : "jPhone 1,1", - "hello" : { - "sub" : "dict" + "Hello" : { + "Sub" : "dict" }, "OS Name" : "iOS", "OS Version" : "1.1.1", "Push Token" : "", "SDK Name" : "swift", "SDK Version" : "4.0.0", - "stuff" : 2 + "Stuff" : 2 }, "time" : "2009-02-13T23:31:30Z", "unique_id" : "00000000-0000-0000-0000-000000000001" diff --git a/Tests/KlaviyoSwiftTests/KlaviyoTestUtils.swift b/Tests/KlaviyoSwiftTests/KlaviyoTestUtils.swift index 7fc8f603..da58ba59 100644 --- a/Tests/KlaviyoSwiftTests/KlaviyoTestUtils.swift +++ b/Tests/KlaviyoSwiftTests/KlaviyoTestUtils.swift @@ -56,13 +56,13 @@ extension KlaviyoEnvironment { } } -class TestJSONDecoder: JSONDecoder { +class TestJSONDecoder: JSONDecoder, @unchecked Sendable { override func decode(_: T.Type, from _: Data) throws -> T where T: Decodable { KlaviyoState.test as! T } } -class InvalidJSONDecoder: JSONDecoder { +class InvalidJSONDecoder: JSONDecoder, @unchecked Sendable { override func decode(_: T.Type, from _: Data) throws -> T where T: Decodable { throw KlaviyoDecodingError.invalidType } diff --git a/Tests/KlaviyoSwiftTests/StateManagementEdgeCaseTests.swift b/Tests/KlaviyoSwiftTests/StateManagementEdgeCaseTests.swift index 11cdddc6..c684432f 100644 --- a/Tests/KlaviyoSwiftTests/StateManagementEdgeCaseTests.swift +++ b/Tests/KlaviyoSwiftTests/StateManagementEdgeCaseTests.swift @@ -154,6 +154,7 @@ class StateManagementEdgeCaseTests: XCTestCase { } } + @MainActor func testSetEmptyEmail() async throws { let initialState = INITIALIZED_TEST_STATE() let store = TestStore(initialState: initialState, reducer: KlaviyoReducer()) @@ -161,6 +162,7 @@ class StateManagementEdgeCaseTests: XCTestCase { _ = await store.send(.setEmail("")) } + @MainActor func testSetEmailWithWhiteSpace() async throws { let initialState = INITIALIZED_TEST_STATE() let store = TestStore(initialState: initialState, reducer: KlaviyoReducer()) @@ -199,6 +201,7 @@ class StateManagementEdgeCaseTests: XCTestCase { } } + @MainActor func testSetEmptyExternalId() async throws { let initialState = INITIALIZED_TEST_STATE() let store = TestStore(initialState: initialState, reducer: KlaviyoReducer()) @@ -206,6 +209,7 @@ class StateManagementEdgeCaseTests: XCTestCase { _ = await store.send(.setExternalId("")) } + @MainActor func testSetExternalIdWithWhiteSpaces() async throws { let initialState = INITIALIZED_TEST_STATE() let store = TestStore(initialState: initialState, reducer: KlaviyoReducer()) @@ -243,6 +247,7 @@ class StateManagementEdgeCaseTests: XCTestCase { } } + @MainActor func testSetEmptyPhoneNumber() async throws { let initialState = INITIALIZED_TEST_STATE() let store = TestStore(initialState: initialState, reducer: KlaviyoReducer()) @@ -250,6 +255,7 @@ class StateManagementEdgeCaseTests: XCTestCase { _ = await store.send(.setPhoneNumber("")) } + @MainActor func testSetPhoneNumberWithWhiteSpaces() async throws { let initialState = INITIALIZED_TEST_STATE() let store = TestStore(initialState: initialState, reducer: KlaviyoReducer()) @@ -414,6 +420,7 @@ class StateManagementEdgeCaseTests: XCTestCase { await fulfillment(of: [expection]) } + @MainActor func testSetProfileWithEmptyStringIdentifiers() async throws { let initialState = KlaviyoState( apiKey: TEST_API_KEY,