diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+ClientBehaviour.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+ClientBehaviour.swift index 92435992b7..2ddc96fb27 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+ClientBehaviour.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+ClientBehaviour.swift @@ -18,30 +18,34 @@ import UIKit import AppKit #endif -extension AWSPinpointPushNotificationsPlugin { - public func identifyUser(userId: String, userProfile: UserProfile?) async throws { +public extension AWSPinpointPushNotificationsPlugin { + func identifyUser(userId: String, userProfile: UserProfile?) async throws { var currentEndpointProfile = await pinpoint.currentEndpointProfile() currentEndpointProfile.addUserId(userId) - if let userProfile = userProfile { + if let userProfile { currentEndpointProfile.addUserProfile(userProfile) } - try await pinpoint.updateEndpoint(with: currentEndpointProfile, - source: .pushNotifications) + try await pinpoint.updateEndpoint( + with: currentEndpointProfile, + source: .pushNotifications + ) } - public func registerDevice(apnsToken: Data) async throws { + func registerDevice(apnsToken: Data) async throws { var currentEndpointProfile = await pinpoint.currentEndpointProfile() currentEndpointProfile.setAPNsToken(apnsToken) do { - try await pinpoint.updateEndpoint(with: currentEndpointProfile, - source: .pushNotifications) + try await pinpoint.updateEndpoint( + with: currentEndpointProfile, + source: .pushNotifications + ) } catch { throw error.pushNotificationsError } } - public func recordNotificationReceived(_ userInfo: Notifications.Push.UserInfo) async throws { - let applicationState = await self.applicationState + func recordNotificationReceived(_ userInfo: Notifications.Push.UserInfo) async throws { + let applicationState = await applicationState await recordNotification( userInfo, applicationState: applicationState, @@ -50,8 +54,8 @@ extension AWSPinpointPushNotificationsPlugin { } #if !os(tvOS) - public func recordNotificationOpened(_ response: UNNotificationResponse) async throws { - let applicationState = await self.applicationState + func recordNotificationOpened(_ response: UNNotificationResponse) async throws { + let applicationState = await applicationState await recordNotification( response.notification.request.content.userInfo, applicationState: applicationState, @@ -63,14 +67,16 @@ extension AWSPinpointPushNotificationsPlugin { /// Retrieves the escape hatch to perform actions directly on PinpointClient. /// /// - Returns: PinpointClientProtocol instance - public func getEscapeHatch() -> PinpointClientProtocol { + func getEscapeHatch() -> PinpointClientProtocol { pinpoint.pinpointClient } - private func recordNotification(_ userInfo: [String: Any], - applicationState: ApplicationState, - action: PushNotification.Action) async { - let userInfo: PushNotification.UserInfo = Dictionary(uniqueKeysWithValues: userInfo.map({($0, $1)})) + private func recordNotification( + _ userInfo: [String: Any], + applicationState: ApplicationState, + action: PushNotification.Action + ) async { + let userInfo: PushNotification.UserInfo = Dictionary(uniqueKeysWithValues: userInfo.map {($0, $1)}) await recordNotification( userInfo, applicationState: applicationState, @@ -78,9 +84,11 @@ extension AWSPinpointPushNotificationsPlugin { ) } - private func recordNotification(_ userInfo: PushNotification.UserInfo, - applicationState: ApplicationState, - action: PushNotification.Action) async { + private func recordNotification( + _ userInfo: PushNotification.UserInfo, + applicationState: ApplicationState, + action: PushNotification.Action + ) async { // Retrieve the payload from the notification guard let payload = userInfo.payload else { log.error( @@ -99,8 +107,10 @@ extension AWSPinpointPushNotificationsPlugin { // Add application state let applicationStateAttribute = applicationState.pinpointAttribute - pushNotificationEvent.addAttribute(applicationStateAttribute.value, - forKey: applicationStateAttribute.key) + pushNotificationEvent.addAttribute( + applicationStateAttribute.value, + forKey: applicationStateAttribute.key + ) // Set global remote attributes await pinpoint.setRemoteGlobalAttributes(payload.attributes) diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Configure.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Configure.swift index 7066e83b28..3a4f9e04de 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Configure.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Configure.swift @@ -31,7 +31,8 @@ extension AWSPinpointPushNotificationsPlugin { pluginConfiguration = AWSPinpointPluginConfiguration( appId: notifications.amazonPinpointAppId, - region: notifications.awsRegion) + region: notifications.awsRegion + ) } else if let config = configuration as? JSONValue { pluginConfiguration = try AWSPinpointPluginConfiguration(config) } else { @@ -51,8 +52,10 @@ extension AWSPinpointPushNotificationsPlugin { region: configuration.region ) - configure(pinpoint: pinpoint, - remoteNotificationsHelper: .default) + configure( + pinpoint: pinpoint, + remoteNotificationsHelper: .default + ) } private func requestNotificationsPermissions(using helper: RemoteNotificationsBehaviour) async { @@ -70,8 +73,10 @@ extension AWSPinpointPushNotificationsPlugin { // MARK: Internal /// Internal configure method to set the properties of the plugin - func configure(pinpoint: AWSPinpointBehavior, - remoteNotificationsHelper: RemoteNotificationsBehaviour) { + func configure( + pinpoint: AWSPinpointBehavior, + remoteNotificationsHelper: RemoteNotificationsBehaviour + ) { self.pinpoint = pinpoint Task { await remoteNotificationsHelper.registerForRemoteNotifications() diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Reset.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Reset.swift index caaf0c6705..7505951be0 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Reset.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Reset.swift @@ -7,8 +7,8 @@ import Foundation -extension AWSPinpointPushNotificationsPlugin { - public func reset() async { +public extension AWSPinpointPushNotificationsPlugin { + func reset() async { if pinpoint != nil { pinpoint = nil } diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Types.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Types.swift index 38949b0850..2dd17a37d1 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Types.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/AWSPinpointPushNotificationsPlugin+Types.swift @@ -8,13 +8,13 @@ import AmplifyUtilsNotifications import Foundation -extension AWSPinpointPushNotificationsPlugin { +public extension AWSPinpointPushNotificationsPlugin { #if !os(tvOS) /// Service Extension that can handle AWS Pinpoint rich notifications. - public typealias ServiceExtension = AUNotificationService + typealias ServiceExtension = AUNotificationService #endif /// A protocol that can be used to customize the expeded payload that the ServiceExtension can handle. - public typealias NotificationPayload = AUNotificationPayload + typealias NotificationPayload = AUNotificationPayload } diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/CommonRunTimeError+PushNotificationsErrorConvertible.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/CommonRunTimeError+PushNotificationsErrorConvertible.swift index 0c07856389..516df2cd96 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/CommonRunTimeError+PushNotificationsErrorConvertible.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/CommonRunTimeError+PushNotificationsErrorConvertible.swift @@ -5,9 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify import AwsCommonRuntimeKit +import Foundation @_spi(InternalAWSPinpoint) import InternalAWSPinpoint extension CommonRunTimeError: PushNotificationsErrorConvertible { diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/Pinpoint+PushNotificationsErrorConvertible.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/Pinpoint+PushNotificationsErrorConvertible.swift index 9c3aaf2749..bc1613b139 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/Pinpoint+PushNotificationsErrorConvertible.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/Pinpoint+PushNotificationsErrorConvertible.swift @@ -5,11 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import AWSClientRuntime import AWSPinpoint import ClientRuntime -import AWSClientRuntime +import Foundation private func recoverySuggestion(for error: ClientRuntime.ModeledError) -> String { type(of: error).isRetryable diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/PushNotificationsErrorConvertible.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/PushNotificationsErrorConvertible.swift index 3043828e1b..1bfdc0ef27 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/PushNotificationsErrorConvertible.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Error/PushNotificationsErrorConvertible.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import Foundation import Amplify +import Foundation protocol PushNotificationsErrorConvertible { var pushNotificationsError: PushNotificationsError { get } diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Extensions/PushNotificationUserInfo+Pinpoint.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Extensions/PushNotificationUserInfo+Pinpoint.swift index af90834fd5..3b489021cf 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Extensions/PushNotificationUserInfo+Pinpoint.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Extensions/PushNotificationUserInfo+Pinpoint.swift @@ -11,7 +11,8 @@ import Foundation extension PushNotification.UserInfo { private var root: [String: Any]? { guard let data = self[Constants.Keys.data] as? [String: Any], - let root = data[Constants.Keys.pinpoint] as? [String: Any] else { + let root = data[Constants.Keys.pinpoint] as? [String: Any] + else { return nil } @@ -19,7 +20,7 @@ extension PushNotification.UserInfo { } var payload: PushNotification.Payload? { - guard let root = root else { + guard let root else { return nil } @@ -42,8 +43,8 @@ extension PushNotification.UserInfo { } extension PushNotification.UserInfo { - private struct Constants { - struct Keys { + private enum Constants { + enum Keys { static let data = "data" static let pinpoint = "pinpoint" static let campaing = "campaign" diff --git a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Support/Constants/PushNotificationsPluginErrorConstants.swift b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Support/Constants/PushNotificationsPluginErrorConstants.swift index 2a1c5ff29a..1e98b1a305 100644 --- a/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Support/Constants/PushNotificationsPluginErrorConstants.swift +++ b/AmplifyPlugins/Notifications/Push/Sources/AWSPinpointPushNotificationsPlugin/Support/Constants/PushNotificationsPluginErrorConstants.swift @@ -10,7 +10,7 @@ import Foundation typealias PushNotificationsPluginErrorString = (errorDescription: ErrorDescription, recoverySuggestion: RecoverySuggestion) -struct PushNotificationsPluginErrorConstants { +enum PushNotificationsPluginErrorConstants { static let decodeConfigurationError: PushNotificationsPluginErrorString = ( "Unable to decode configuration", "Make sure the plugin configuration is JSONValue" diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginAmplifyVersionableTests.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginAmplifyVersionableTests.swift index 4036dd4f97..229612eb2f 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginAmplifyVersionableTests.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginAmplifyVersionableTests.swift @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 // -import XCTest import AWSPinpointPushNotificationsPlugin +import XCTest class AWSPinpointPushNotificationsPluginAmplifyVersionableTests: AWSPinpointPushNotificationsPluginTestBase { func testVersion_shouldReturnNotNil() { diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginClientBehaviourTests.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginClientBehaviourTests.swift index 5a0925bf8c..4da8c608b8 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginClientBehaviourTests.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginClientBehaviourTests.swift @@ -7,22 +7,24 @@ import Amplify import AWSPinpoint -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint -@testable import AWSPinpointPushNotificationsPlugin import UserNotifications import XCTest +@testable import AWSPinpointPushNotificationsPlugin +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint class AWSPinpointPushNotificationsPluginClientBehaviourTests: AWSPinpointPushNotificationsPluginTestBase { override func setUp() async throws { try await super.setUp() - plugin.configure(pinpoint: mockPinpoint, - remoteNotificationsHelper: mockRemoteNotifications) + plugin.configure( + pinpoint: mockPinpoint, + remoteNotificationsHelper: mockRemoteNotifications + ) } - + // MARK: - Identify User tests func testIdentifyUser_shouldUpdateUserId() async throws { try await plugin.identifyUser(userId: "newUserId", userProfile: nil) - + XCTAssertEqual(mockPinpoint.currentEndpointProfileCount, 1) XCTAssertEqual(mockPinpoint.updateEndpointCount, 1) let updatedEndpoint = try XCTUnwrap(mockPinpoint.updatedPinpointEndpointProfile) @@ -139,82 +141,82 @@ class AWSPinpointPushNotificationsPluginClientBehaviourTests: AWSPinpointPushNot updatedEndpoint = try XCTUnwrap(mockPinpoint.updatedPinpointEndpointProfile) XCTAssertTrue(updatedEndpoint.isOptOut) } - + // MARK: - Register Device tests func testRegisterDevice_shouldUpdateDeviceToken() async throws { let apnsToken = Data("apnsToken".utf8) try await plugin.registerDevice(apnsToken: apnsToken) - + XCTAssertEqual(mockPinpoint.currentEndpointProfileCount, 1) XCTAssertEqual(mockPinpoint.updateEndpointCount, 1) let updatedEndpoint = try XCTUnwrap(mockPinpoint.updatedPinpointEndpointProfile) XCTAssertEqual(updatedEndpoint.deviceToken, apnsToken.asHexString()) } - + // MARK: - Record Notification received tests func testRecordNotificationReceived_withValidCampaignPayload_shouldRecordEvent() async throws { try await plugin.recordNotificationReceived(createUserInfo(for: .campaign)) - + XCTAssertEqual(mockPinpoint.createEventCount, 1) XCTAssertTrue(mockPinpoint.mockedCreatedEvent!.eventType.starts(with: "_campaign.received_")) XCTAssertEqual(mockPinpoint.setRemoteGlobalAttributesCount, 1) XCTAssertEqual(mockPinpoint.recordCount, 1) } - + func testRecordNotificationReceived_withValidJourneyPayload_shouldRecordEvent() async throws { try await plugin.recordNotificationReceived(createUserInfo(for: .journey)) - + XCTAssertEqual(mockPinpoint.createEventCount, 1) XCTAssertTrue(mockPinpoint.mockedCreatedEvent!.eventType.starts(with: "_journey.received_")) XCTAssertEqual(mockPinpoint.setRemoteGlobalAttributesCount, 1) XCTAssertEqual(mockPinpoint.recordCount, 1) } - + func testRecordNotificationReceived_withInvalidPayload_shouldRecordEvent() async throws { let userInfo: Notifications.Push.UserInfo = [ "invalid": "payload" ] try await plugin.recordNotificationReceived(userInfo) - + XCTAssertEqual(mockPinpoint.createEventCount, 0) XCTAssertNil(mockPinpoint.mockedCreatedEvent?.eventType) XCTAssertEqual(mockPinpoint.setRemoteGlobalAttributesCount, 0) XCTAssertEqual(mockPinpoint.recordCount, 0) } - + // MARK: - Record Notification opened tests #if !os(tvOS) func testRecordNotificationOpened_withValidCampaignPayload_shouldRecordEvent() async throws { let response = UNNotificationResponse(coder: createCoder(for: .campaign))! try await plugin.recordNotificationOpened(response) - + XCTAssertEqual(mockPinpoint.createEventCount, 1) XCTAssertEqual(mockPinpoint.mockedCreatedEvent?.eventType, "_campaign.opened_notification") XCTAssertEqual(mockPinpoint.setRemoteGlobalAttributesCount, 1) XCTAssertEqual(mockPinpoint.recordCount, 1) } - + func testRecordNotificationOpened_withValidJourneyPayload_shouldRecordEvent() async throws { let response = UNNotificationResponse(coder: createCoder(for: .journey))! try await plugin.recordNotificationOpened(response) - + XCTAssertEqual(mockPinpoint.createEventCount, 1) XCTAssertEqual(mockPinpoint.mockedCreatedEvent?.eventType, "_journey.opened_notification") XCTAssertEqual(mockPinpoint.setRemoteGlobalAttributesCount, 1) XCTAssertEqual(mockPinpoint.recordCount, 1) } - + func testRecordNotificationOpened_withInvalidPayload_shouldRecordEvent() async throws { let response = UNNotificationResponse(coder: MockedKeyedArchiver(requiringSecureCoding: false))! try await plugin.recordNotificationOpened(response) - + XCTAssertEqual(mockPinpoint.createEventCount, 0) XCTAssertNil(mockPinpoint.mockedCreatedEvent?.eventType) XCTAssertEqual(mockPinpoint.setRemoteGlobalAttributesCount, 0) XCTAssertEqual(mockPinpoint.recordCount, 0) } #endif - + // - MARK: Escape Hatch tests /// Given: A configured AWSPinpointPushNotificationsPlugin instance /// When: The getEscapeHatch API is invoked @@ -224,10 +226,10 @@ class AWSPinpointPushNotificationsPluginClientBehaviourTests: AWSPinpointPushNot XCTFail("Unable to retrieve PinpointClient") return } - + XCTAssertTrue(escapeHatch === (mockPinpoint.pinpointClient as? PinpointClient)) } - + private func createUserInfo(for source: PushNotification.Source) -> Notifications.Push.UserInfo { return [ "data": [ @@ -239,31 +241,33 @@ class AWSPinpointPushNotificationsPluginClientBehaviourTests: AWSPinpointPushNot ] ] } - + private func createCoder(for source: PushNotification.Source) -> NSKeyedArchiver { let archiver = MockedKeyedArchiver(requiringSecureCoding: false) archiver.userInfo = createUserInfo(for: source) return archiver } - + private class MockedKeyedArchiver: NSKeyedArchiver { var userInfo: Notifications.Push.UserInfo = [:] - + override func decodeObject(forKey key: String) -> Any { switch key { case "notification": return UNNotification(coder: self) as Any case "request": - return UNNotificationRequest(identifier: "identifier", - content: UNNotificationContent(coder: self)!, - trigger: nil) + return UNNotificationRequest( + identifier: "identifier", + content: UNNotificationContent(coder: self)!, + trigger: nil + ) case "userInfo": return userInfo default: return "" } } - + override func decodeInt64(forKey _: String) -> Int64 { 0 } override func decodeBool(forKey _: String) -> Bool { true } override func containsValue(forKey _: String) -> Bool { false } diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginConfigureTests.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginConfigureTests.swift index 2c3ce8461c..a4a2103247 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginConfigureTests.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginConfigureTests.swift @@ -5,16 +5,17 @@ // SPDX-License-Identifier: Apache-2.0 // +import XCTest @_spi(InternalAmplifyConfiguration) @testable import Amplify @testable import AmplifyTestCommon -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint @testable import AWSPinpointPushNotificationsPlugin -import XCTest +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint class AWSPinpointPushNotificationsPluginConfigureTests: AWSPinpointPushNotificationsPluginTestBase { private var hubPlugin: HubCategoryPlugin { guard let plugin = try? Amplify.Hub.getPlugin(for: "awsHubPlugin"), - plugin.key == "awsHubPlugin" else { + plugin.key == "awsHubPlugin" + else { fatalError("Could not access awsHubPlugin") } return plugin @@ -141,7 +142,8 @@ class AWSPinpointPushNotificationsPluginConfigureTests: AWSPinpointPushNotificat if payload.eventName == HubPayload.EventName.Notifications.Push.requestNotificationsPermissions { eventWasReported.fulfill() guard let error = payload.data as? PushNotificationsError, - case .service(let errorDescription, let recoverySuggestion, _) = error else { + case .service(let errorDescription, let recoverySuggestion, _) = error + else { XCTFail("Expected Push Notification error") return } @@ -161,7 +163,8 @@ class AWSPinpointPushNotificationsPluginConfigureTests: AWSPinpointPushNotificat XCTFail("Push Notifications configuration should not succeed") } catch { guard let pluginError = error as? PluginError, - case .pluginConfigurationError = pluginError else { + case .pluginConfigurationError = pluginError + else { XCTFail("Should throw invalidConfiguration exception. But received \(error) ") return } @@ -175,7 +178,7 @@ class AWSPinpointPushNotificationsPluginConfigureTests: AWSPinpointPushNotificat let pinpointConfiguration = JSONValue( dictionaryLiteral: (AWSPinpointPluginConfiguration.appIdConfigKey, appId), - (AWSPinpointPluginConfiguration.regionConfigKey, region) + (AWSPinpointPluginConfiguration.regionConfigKey, region) ) return pinpointConfiguration @@ -185,6 +188,7 @@ class AWSPinpointPushNotificationsPluginConfigureTests: AWSPinpointPushNotificat .init(notifications: .init( awsRegion: testRegion, amazonPinpointAppId: testAppId, - channels: [.apns])) + channels: [.apns] + )) } } diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginResetTests.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginResetTests.swift index bd262d6a56..d540010f1e 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginResetTests.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginResetTests.swift @@ -6,8 +6,8 @@ // import Amplify -@testable import AWSPinpointPushNotificationsPlugin import XCTest +@testable import AWSPinpointPushNotificationsPlugin class AWSPinpointPushNotificationsPluginResetTests: AWSPinpointPushNotificationsPluginTestBase { func testReset_shouldResetValues() async { diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginTestBase.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginTestBase.swift index 047d8501d0..606116273a 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginTestBase.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/AWSPinpointPushNotificationsPluginTestBase.swift @@ -5,26 +5,26 @@ // SPDX-License-Identifier: Apache-2.0 // -@testable import Amplify -@testable import AWSPinpointPushNotificationsPlugin import UserNotifications import XCTest +@testable import Amplify +@testable import AWSPinpointPushNotificationsPlugin class AWSPinpointPushNotificationsPluginTestBase: XCTestCase { var plugin: AWSPinpointPushNotificationsPlugin! var mockPinpoint: MockAWSPinpoint! var mockRemoteNotifications: MockRemoteNotifications! - + let testAppId = "56e6f06fd4f244c6b202bc1234567890" let testRegion = "us-east-1" let authorizationOptions: UNAuthorizationOptions = [.badge] - + override func setUp() async throws { plugin = AWSPinpointPushNotificationsPlugin(options: authorizationOptions) mockPinpoint = MockAWSPinpoint() mockRemoteNotifications = MockRemoteNotifications() } - + override func tearDown() async throws { let resettable = plugin as Resettable await resettable.reset() diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/ErrorPushNotificationsTests.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/ErrorPushNotificationsTests.swift index fd5c80a93e..309a93a76f 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/ErrorPushNotificationsTests.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/ErrorPushNotificationsTests.swift @@ -5,18 +5,18 @@ // SPDX-License-Identifier: Apache-2.0 // -@testable import Amplify import AWSPinpoint -@testable import AWSPinpointPushNotificationsPlugin import Foundation import XCTest +@testable import Amplify +@testable import AWSPinpointPushNotificationsPlugin class ErrorPushNotificationsTests: XCTestCase { /// Given: A NSError error /// When: pushNotificationsError is invoked /// Then: An .unknown error is returned func testPushNotificationsError_withUnknownError_shouldReturnUnknownError() { - let error = NSError(domain: "MyError", code: 1234) + let error = NSError(domain: "MyError", code: 1_234) let pushNotificationsError = error.pushNotificationsError switch pushNotificationsError { case .unknown(let errorDescription, let underlyingError): @@ -81,7 +81,8 @@ extension ErrorPushNotificationsTests { /// Then: A .unknown error is returned func testPushNotificationError_withUnknownAWSHTTPServiceError_shouldReturnUnknownError() { let error = UnknownAWSHTTPServiceError( - httpResponse: .init(body: .empty, statusCode: .accepted), message: "UnknownAWSHTTPServiceError", requestID: nil, typeName: nil) + httpResponse: .init(body: .empty, statusCode: .accepted), message: "UnknownAWSHTTPServiceError", requestID: nil, typeName: nil + ) let pushNotificationsError = error.pushNotificationsError switch pushNotificationsError { case .unknown(let errorDescription, let underlyingError): @@ -104,7 +105,7 @@ extension ErrorPushNotificationsTests { /// When: pushNotificationsError is invoked /// Then: A .unknown error is returned func testPushNotificationError_withCommonRunTimeError_shouldReturnUnknownError() { - let error = CommonRunTimeError.crtError(.init(code: 12345)) + let error = CommonRunTimeError.crtError(.init(code: 12_345)) let pushNotificationsError = error.pushNotificationsError switch pushNotificationsError { case .unknown(let errorDescription, let underlyingError): diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockAWSPinpoint.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockAWSPinpoint.swift index 4bac908f59..0064daa992 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockAWSPinpoint.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockAWSPinpoint.swift @@ -7,9 +7,9 @@ import Amplify import AWSPinpoint +import XCTest @testable import AWSPinpointPushNotificationsPlugin @_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint -import XCTest class MockAWSPinpoint: AWSPinpointBehavior { var pinpointClient: PinpointClientProtocol = try! PinpointClient(region: "us-east-1") @@ -27,7 +27,7 @@ class MockAWSPinpoint: AWSPinpointBehavior { } var setRemoteGlobalAttributesCount = 0 - func setRemoteGlobalAttributes(_ attributes: [String : String]) async { + func setRemoteGlobalAttributes(_ attributes: [String: String]) async { setRemoteGlobalAttributesCount += 1 } @@ -48,8 +48,10 @@ class MockAWSPinpoint: AWSPinpointBehavior { var updateEndpointCount = 0 var updatedPinpointEndpointProfile: PinpointEndpointProfile? - func updateEndpoint(with endpointProfile: PinpointEndpointProfile, - source: AWSPinpointSource) async throws { + func updateEndpoint( + with endpointProfile: PinpointEndpointProfile, + source: AWSPinpointSource + ) async throws { updateEndpointCount += 1 updatedPinpointEndpointProfile = endpointProfile } diff --git a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockRemoteNotifications.swift b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockRemoteNotifications.swift index 6f3565fa7c..aee3ca987d 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockRemoteNotifications.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/AWSPinpointPushNotificationsPluginUnitTests/Mocks/MockRemoteNotifications.swift @@ -6,9 +6,9 @@ // import Foundation -@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint import UserNotifications import XCTest +@_spi(InternalAWSPinpoint) @testable import InternalAWSPinpoint class MockRemoteNotifications: RemoteNotificationsBehaviour { var isRegisteredForRemoteNotifications: Bool = true diff --git a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/ContentView.swift b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/ContentView.swift index 41e72a36c7..cccf158f7f 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/ContentView.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/ContentView.swift @@ -4,13 +4,12 @@ // // SPDX-License-Identifier: Apache-2.0 // - -import SwiftUI import Amplify import AWSCognitoAuthPlugin -import AWSPinpointPushNotificationsPlugin import AWSPinpointAnalyticsPlugin +import AWSPinpointPushNotificationsPlugin +import SwiftUI let amplifyConfigurationFilePath = "testconfiguration/AWSPushNotificationPluginIntegrationTest-amplifyconfiguration" let amplifyOutputsFilePath = "testconfiguration/AWSPushNotificationPluginIntegrationTest-amplify_outputs" @@ -32,17 +31,17 @@ struct ContentView: View { ScrollView { VStack { Button("Init Amplify", action: initAmplify) - + Button("Identify User", action: identifyUser) .alert(isPresented: $showIdentifyUserDone) { Alert(title: Text("Identified User")) } - + Button("Register Device", action: registerDevice) .alert(isPresented: $showRegisterTokenDone) { Alert(title: Text("Registered Device")) } - + Text(hubEvents.joined(separator: "\n")) Spacer() } @@ -72,13 +71,13 @@ struct ContentView: View { func listenHubEvent() { pushNotificationHubSubscription = Amplify.Hub.listen(to: .pushNotifications) { payload in if payload.eventName == HubPayload.EventName.Notifications.Push.requestNotificationsPermissions { - self.hubEvents.append(payload.eventDescription) + hubEvents.append(payload.eventDescription) } } analyticsHubSubscription = Amplify.Hub.listen(to: .analytics) { payload in if payload.eventName == HubPayload.EventName.Analytics.flushEvents { - self.hubEvents.append(payload.eventDescription) + hubEvents.append(payload.eventDescription) } } } @@ -87,7 +86,7 @@ struct ContentView: View { Task { do { try await Amplify.Notifications.Push.identifyUser(userId: UUID().uuidString) - self.showIdentifyUserDone = true + showIdentifyUserDone = true } catch { print(#function, "Failed to identify user", error) } @@ -99,7 +98,7 @@ struct ContentView: View { Task { do { try await Amplify.Notifications.Push.registerDevice(apnsToken: randomDeviceToken) - self.showRegisterTokenDone = true + showRegisterTokenDone = true } catch { print(#function, "Failed to register device token", error) } @@ -109,7 +108,7 @@ struct ContentView: View { extension HubPayload { var eventDescription: String { - "\(self.eventName) = \(String(describing: self.data))" + "\(eventName) = \(String(describing: data))" } } diff --git a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/PushNotificationHostAppApp.swift b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/PushNotificationHostAppApp.swift index 022b486500..4ecfcc168e 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/PushNotificationHostAppApp.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/PushNotificationHostAppApp.swift @@ -4,11 +4,11 @@ // // SPDX-License-Identifier: Apache-2.0 // - -import SwiftUI import Amplify +import SwiftUI import UserNotifications + #if os(watchOS) typealias ApplicationDelegateAdaptor = WKApplicationDelegateAdaptor typealias Application = WKApplication @@ -39,30 +39,30 @@ extension AppDelegate: ApplicationDelegate { func applicationDidFinishLaunching() { UNUserNotificationCenter.current().delegate = self } - + func didRegisterForRemoteNotifications(withDeviceToken deviceToken: Data) { registerDevice(deviceToken) } - + func didFailToRegisterForRemoteNotificationsWithError(_ error: Error) { print(#function, "Failed to register for remote notification", error) } #else func application( _ application: Application, - didFinishLaunchingWithOptions launchOptions: [Application.LaunchOptionsKey : Any]? = nil + didFinishLaunchingWithOptions launchOptions: [Application.LaunchOptionsKey: Any]? = nil ) -> Bool { UNUserNotificationCenter.current().delegate = self return true } - + func application( _ application: Application, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { registerDevice(deviceToken) } - + func application( _ application: Application, didFailToRegisterForRemoteNotificationsWithError error: Error @@ -73,12 +73,12 @@ extension AppDelegate: ApplicationDelegate { func application( _ application: Application, - didReceiveRemoteNotification userInfo: [AnyHashable : Any] + didReceiveRemoteNotification userInfo: [AnyHashable: Any] ) async -> BackgroundFetchResult { await recordNotificationReceived(userInfo) return .noData } - + private func registerDevice(_ deviceToken: Data) { Task { do { @@ -89,8 +89,8 @@ extension AppDelegate: ApplicationDelegate { } } } - - private func recordNotificationReceived(_ userInfo: [AnyHashable : Any]) async { + + private func recordNotificationReceived(_ userInfo: [AnyHashable: Any]) async { do { try await Amplify.Notifications.Push.recordNotificationReceived(userInfo) Amplify.Analytics.flushEvents() diff --git a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/TestConfigHelper.swift b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/TestConfigHelper.swift index 45c1977d71..2cbd448603 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/TestConfigHelper.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostApp/TestConfigHelper.swift @@ -4,7 +4,6 @@ // // SPDX-License-Identifier: Apache-2.0 // - import Foundation @testable import Amplify diff --git a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/LocalServer.swift b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/LocalServer.swift index 03dc306481..142e2db461 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/LocalServer.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/LocalServer.swift @@ -4,7 +4,6 @@ // // SPDX-License-Identifier: Apache-2.0 // - import Foundation @@ -52,12 +51,12 @@ extension LocalServer { } var urlRequest: URLRequest { - var request = URLRequest(url: URL(string: Self.endpoint + self.path)!) - request.httpMethod = self.httpMethod - request.httpBody = self.payload - additionalRequestHeaders?.forEach({ key, value in + var request = URLRequest(url: URL(string: Self.endpoint + path)!) + request.httpMethod = httpMethod + request.httpBody = payload + additionalRequestHeaders?.forEach { key, value in request.addValue(value, forHTTPHeaderField: key) - }) + } return request } } diff --git a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/Notification.swift b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/Notification.swift index 1d47aab5d7..597faad324 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/Notification.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/Notification.swift @@ -4,7 +4,6 @@ // // SPDX-License-Identifier: Apache-2.0 // - import Foundation diff --git a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/PushNotificationHostAppUITests.swift b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/PushNotificationHostAppUITests.swift index 21729ac2e1..7533bf6abb 100644 --- a/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/PushNotificationHostAppUITests.swift +++ b/AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/PushNotificationHostAppUITests/PushNotificationHostAppUITests.swift @@ -4,7 +4,6 @@ // // SPDX-License-Identifier: Apache-2.0 // - import XCTest @@ -78,8 +77,7 @@ final class PushNotificationHostAppUITests: XCTestCase { let firstAlert = firstAlertElement() if !firstAlert.waitForExistence(timeout: timeout) || - !anyElementContains(text: "Identified User", scope: firstAlert).waitForExistence(timeout: timeout) - { + !anyElementContains(text: "Identified User", scope: firstAlert).waitForExistence(timeout: timeout) { XCTFail("Failed to identify user") } } @@ -103,8 +101,7 @@ final class PushNotificationHostAppUITests: XCTestCase { let firstAlert = firstAlertElement() if !firstAlert.waitForExistence(timeout: timeout) || - !anyElementContains(text: "Registered Device", scope: firstAlert).waitForExistence(timeout: timeout) - { + !anyElementContains(text: "Registered Device", scope: firstAlert).waitForExistence(timeout: timeout) { XCTFail("Failed to register device") } } @@ -276,7 +273,7 @@ final class PushNotificationHostAppUITests: XCTestCase { #endif } } - + private func firstAlertElement() -> XCUIElement { #if os(watchOS) // `SwiftUI.View.alert(isPresented:)` views re matched as tables in watchOS 🤷‍♂️ @@ -285,7 +282,7 @@ final class PushNotificationHostAppUITests: XCTestCase { return app.alerts.firstMatch #endif } - + private func notificationElement() -> XCUIElement { #if os(watchOS) return XCUIApplication.homeScreen.otherElements["PushNotificationsWatchApp"] @@ -387,7 +384,7 @@ extension XCUIRemote { isEndReached = true } } - + print("Element \(element) was found and has been focused, pressing SELECT") press(.select) } @@ -404,7 +401,7 @@ extension XCUIApplication { XCUIApplication(bundleIdentifier: "com.apple.Carousel") #endif } - + var focusedElement: XCUIElement { descendants(matching: .any).element(matching: NSPredicate(format: "hasFocus == true")) }