Skip to content

Commit 8da7fb4

Browse files
authored
chore: kickoff release
2 parents 7e8bc10 + b584331 commit 8da7fb4

File tree

11 files changed

+311
-111
lines changed

11 files changed

+311
-111
lines changed

.github/workflows/integ_test.yml

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -55,46 +55,44 @@ jobs:
5555
project_path: ./AmplifyPlugins/Analytics/Tests/AnalyticsHostApp
5656
scheme: AWSPinpointAnalyticsPluginIntegrationTests
5757

58-
# Disabling these tests because they do not currently work in CI. We will create a ticket to track
59-
# getting resolving this. In the meantime, they can be run locally.
60-
#
61-
# push-notification-integration-test:
62-
# needs: prepare-for-test
63-
# runs-on: macos-12
64-
# environment: IntegrationTest
65-
# steps:
66-
# - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
67-
# with:
68-
# persist-credentials: false
69-
70-
# - name: Make directory
71-
# run: mkdir -p ~/.aws-amplify/amplify-ios/testconfiguration/
72-
73-
# - name: Copy integration test resouces
74-
# uses: ./.github/composite_actions/download_test_configuration
75-
# with:
76-
# resource_subfolder: push-notification
77-
# aws_role_to_assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
78-
# aws_region: ${{ secrets.AWS_REGION }}
79-
# aws_s3_bucket: ${{ secrets.AWS_S3_BUCKET_INTEG_V2 }}
80-
81-
# - name: Set up node
82-
# uses: actions/setup-node@v3
83-
# with:
84-
# node-version: 16.x
85-
86-
# - name: Run Local Server
87-
# run: |
88-
# cd ./AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/LocalServer
89-
# npm install
90-
# npm start &
91-
# shell: bash
92-
93-
# - name: Run Integration test
94-
# uses: ./.github/composite_actions/run_xcodebuild_test
95-
# with:
96-
# project_path: ./AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp
97-
# scheme: PushNotificationHostApp
58+
59+
push-notification-integration-test:
60+
needs: prepare-for-test
61+
runs-on: macos-12
62+
environment: IntegrationTest
63+
steps:
64+
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
65+
with:
66+
persist-credentials: false
67+
68+
- name: Make directory
69+
run: mkdir -p ~/.aws-amplify/amplify-ios/testconfiguration/
70+
71+
- name: Copy integration test resouces
72+
uses: ./.github/composite_actions/download_test_configuration
73+
with:
74+
resource_subfolder: push-notification
75+
aws_role_to_assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
76+
aws_region: ${{ secrets.AWS_REGION }}
77+
aws_s3_bucket: ${{ secrets.AWS_S3_BUCKET_INTEG_V2 }}
78+
79+
- name: Set up node
80+
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
81+
with:
82+
node-version: 16.x
83+
84+
- name: Run Local Server
85+
run: |
86+
cd ./AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp/LocalServer
87+
npm install
88+
npm start &
89+
shell: bash
90+
91+
- name: Run Integration test
92+
uses: ./.github/composite_actions/run_xcodebuild_test
93+
with:
94+
project_path: ./AmplifyPlugins/Notifications/Push/Tests/PushNotificationHostApp
95+
scheme: PushNotificationHostApp
9896

9997
auth-integration-test:
10098
needs: prepare-for-test
@@ -173,4 +171,4 @@ jobs:
173171
uses: ./.github/composite_actions/run_xcodebuild_test
174172
with:
175173
project_path: ./AmplifyPlugins/Storage/Tests/StorageHostApp/
176-
scheme: AWSS3StoragePluginIntegrationTests
174+
scheme: AWSS3StoragePluginIntegrationTests

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthDeleteUserTask.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ class AWSAuthDeleteUserTask: AuthDeleteUserTask, DefaultLogger {
3131
let accessToken = try await taskHelper.getAccessToken()
3232

3333
do {
34-
try await deleteUser(with: accessToken)
34+
try await deleteUser(with: accessToken)
3535
log.verbose("Received Success")
3636
} catch {
3737
log.verbose("Delete user failed, reconfiguring auth state. \(error)")
3838
await waitForReConfigure()
39+
await signOutIfUserWasNotFound(with: error)
3940
throw error
4041
}
4142
}
@@ -66,6 +67,18 @@ class AWSAuthDeleteUserTask: AuthDeleteUserTask, DefaultLogger {
6667
}
6768
}
6869

70+
private func signOutIfUserWasNotFound(with error: Error) async {
71+
guard case AuthError.service(_, _, let underlyingError) = error,
72+
case .userNotFound = (underlyingError as? AWSCognitoAuthError) else {
73+
return
74+
}
75+
log.verbose("User not found, signing out")
76+
let signOutData = SignOutEventData(globalSignOut: true)
77+
let event = AuthenticationEvent(eventType: .signOutRequested(signOutData))
78+
await authStateMachine.send(event)
79+
_ = await taskHelper.didSignOut()
80+
}
81+
6982
private func waitForReConfigure() async {
7083

7184
let event = AuthEvent(eventType: .reconfigure(configuration))

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthSignOutTask.swift

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class AWSAuthSignOutTask: AuthSignOutTask, DefaultLogger {
3535
if isValidAuthNStateToStart(authNState) {
3636
log.verbose("Sending signOut event")
3737
await sendSignOutEvent()
38-
return await doSignOut()
38+
return await taskHelper.didSignOut()
3939
} else if case .federatedToIdentityPool = authNState {
4040
let invalidStateError = AuthError.invalidState(
4141
"The user is currently federated to identity pool. You must call clearFederationToIdentityPool to clear credentials.",
@@ -47,40 +47,6 @@ class AWSAuthSignOutTask: AuthSignOutTask, DefaultLogger {
4747

4848
}
4949

50-
private func doSignOut() async -> AuthSignOutResult {
51-
52-
let stateSequences = await authStateMachine.listen()
53-
log.verbose("Waiting for signOut completion")
54-
for await state in stateSequences {
55-
guard case .configured(let authNState, _) = state else {
56-
return invalidStateResult()
57-
}
58-
59-
switch authNState {
60-
case .signedOut(let data):
61-
if data.revokeTokenError != nil ||
62-
data.globalSignOutError != nil ||
63-
data.hostedUIError != nil {
64-
return AWSCognitoSignOutResult.partial(
65-
revokeTokenError: data.revokeTokenError,
66-
globalSignOutError: data.globalSignOutError,
67-
hostedUIError: data.hostedUIError)
68-
}
69-
return AWSCognitoSignOutResult.complete
70-
case .signingIn:
71-
log.verbose("Cancel if a signIn is in progress")
72-
await authStateMachine.send(AuthenticationEvent.init(eventType: .cancelSignIn))
73-
case .signingOut(let state):
74-
if case .error(let error) = state {
75-
return AWSCognitoSignOutResult.failed(error.authError)
76-
}
77-
default:
78-
continue
79-
}
80-
}
81-
fatalError()
82-
}
83-
8450
func isValidAuthNStateToStart(_ authNState: AuthenticationState) -> Bool {
8551
switch authNState {
8652
case .signedIn, .signedOut:

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/Helpers/AWSAuthTaskHelper.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,40 @@ class AWSAuthTaskHelper: DefaultLogger {
3131
}
3232
}
3333

34+
func didSignOut() async -> AuthSignOutResult {
35+
let stateSequences = await authStateMachine.listen()
36+
log.verbose("Waiting for signOut completion")
37+
for await state in stateSequences {
38+
guard case .configured(let authNState, _) = state else {
39+
let error = AuthError.invalidState("Auth State not in a valid state", AuthPluginErrorConstants.invalidStateError, nil)
40+
return AWSCognitoSignOutResult.failed(error)
41+
}
42+
43+
switch authNState {
44+
case .signedOut(let data):
45+
if data.revokeTokenError != nil ||
46+
data.globalSignOutError != nil ||
47+
data.hostedUIError != nil {
48+
return AWSCognitoSignOutResult.partial(
49+
revokeTokenError: data.revokeTokenError,
50+
globalSignOutError: data.globalSignOutError,
51+
hostedUIError: data.hostedUIError)
52+
}
53+
return AWSCognitoSignOutResult.complete
54+
case .signingIn:
55+
log.verbose("Cancel if a signIn is in progress")
56+
await authStateMachine.send(AuthenticationEvent.init(eventType: .cancelSignIn))
57+
case .signingOut(let state):
58+
if case .error(let error) = state {
59+
return AWSCognitoSignOutResult.failed(error.authError)
60+
}
61+
default:
62+
continue
63+
}
64+
}
65+
fatalError()
66+
}
67+
3468
func getAccessToken() async throws -> String {
3569

3670
let session = try await fetchAuthSessionHelper.fetch(authStateMachine)

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/AuthenticationProviderDeleteUserTests.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,35 @@ class AuthenticationProviderDeleteUserTests: BasePluginTest {
3636
}
3737
}
3838

39+
/// Test a deleteUser when sign out failed
40+
///
41+
/// - Given: Given an auth plugin with mocked service. Mocked service should mock a
42+
/// sign out failure
43+
///
44+
/// - When:
45+
/// - I invoke deleteUser
46+
/// - Then:
47+
/// - I should still be able to get a success for delete user
48+
///
49+
func testSignOutFailureWhenDeleteUserIsSuccess() async {
50+
mockIdentityProvider = MockIdentityProvider(
51+
mockRevokeTokenResponse: { _ in
52+
throw RevokeTokenOutputError.unsupportedTokenTypeException(.init())
53+
}, mockGlobalSignOutResponse: { _ in
54+
throw GlobalSignOutOutputError.internalErrorException(.init())
55+
},
56+
mockDeleteUserOutputResponse: { _ in
57+
try DeleteUserOutputResponse(httpResponse: .init(body: .empty, statusCode: .ok))
58+
}
59+
)
60+
do {
61+
try await plugin.deleteUser()
62+
print("Delete user success")
63+
} catch {
64+
XCTFail("Received failure with error \(error)")
65+
}
66+
}
67+
3968

4069
/// Test a deleteUser with network error from service
4170
///
@@ -374,6 +403,7 @@ class AuthenticationProviderDeleteUserTests: BasePluginTest {
374403
/// - I invoke deleteUser
375404
/// - Then:
376405
/// - I should get a .service error with .userNotFound error
406+
/// AuthN should be in signedOut state
377407
///
378408
func testDeleteUserWithUserNotFoundException() async {
379409
mockIdentityProvider = MockIdentityProvider(
@@ -397,6 +427,19 @@ class AuthenticationProviderDeleteUserTests: BasePluginTest {
397427
return
398428
}
399429
}
430+
431+
switch await plugin.authStateMachine.currentState {
432+
case .configured(let authNState, let authZState):
433+
switch (authNState, authZState) {
434+
case (.signedOut, .configured):
435+
print("AuthN and AuthZ are in a valid state")
436+
default:
437+
XCTFail("AuthN should be in signed out state")
438+
}
439+
default:
440+
XCTFail("Auth should be in configured state")
441+
442+
}
400443
}
401444

402445
// TODO: ENABLE TESTS after adding hosted UI feature

AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Storage/SQLite/QueryPredicate+SQLite.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,28 @@ import SQLite
1111

1212
extension QueryOperator {
1313

14-
var sqlOperation: String {
14+
func sqlOperation(column: String) -> String {
1515
switch self {
1616
case .notEqual(let value):
17-
return value == nil ? "is not null" : "<> ?"
17+
return value == nil ? "\(column) is not null" : "\(column) <> ?"
1818
case .equals(let value):
19-
return value == nil ? "is null" : "= ?"
19+
return value == nil ? "\(column) is null" : "\(column) = ?"
2020
case .lessOrEqual:
21-
return "<= ?"
21+
return "\(column) <= ?"
2222
case .lessThan:
23-
return "< ?"
23+
return "\(column) < ?"
2424
case .greaterOrEqual:
25-
return ">= ?"
25+
return "\(column) >= ?"
2626
case .greaterThan:
27-
return "> ?"
27+
return "\(column) > ?"
2828
case .between:
29-
return "between ? and ?"
30-
case .beginsWith, .contains:
31-
return "like ?"
29+
return "\(column) between ? and ?"
30+
case .beginsWith:
31+
return "instr(\(column), ?) = 1"
32+
case .contains:
33+
return "instr(\(column), ?) > 0"
3234
case .notContains:
33-
return "not like ?"
35+
return "instr(\(column), ?) = 0"
3436
}
3537
}
3638

@@ -45,12 +47,10 @@ extension QueryOperator {
4547
.greaterOrEqual(let value),
4648
.greaterThan(let value):
4749
return [value.asBinding()]
48-
case .contains(let value):
49-
return ["%\(value)%"]
50-
case .beginsWith(let value):
51-
return ["\(value)%"]
52-
case .notContains(let value):
53-
return ["%\(value)%"]
50+
case .contains(let value),
51+
.beginsWith(let value),
52+
.notContains(let value):
53+
return [value.asBinding()]
5454
}
5555
}
5656
}

AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Storage/SQLite/SQLStatement+Condition.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ private func translateQueryPredicate(from modelSchema: ModelSchema,
3131
if let operation = pred as? QueryPredicateOperation {
3232
let column = resolveColumn(operation)
3333
if predicateIndex == 0 {
34-
sql.append("\(indent)\(column) \(operation.operator.sqlOperation)")
34+
sql.append("\(indent)\(operation.operator.sqlOperation(column: column))")
3535
} else {
36-
sql.append("\(indent)\(groupType.rawValue) \(column) \(operation.operator.sqlOperation)")
36+
sql.append("\(indent)\(groupType.rawValue) \(operation.operator.sqlOperation(column: column))")
3737
}
3838

3939
bindings.append(contentsOf: operation.operator.bindings)

0 commit comments

Comments
 (0)