Skip to content

Commit a6bb418

Browse files
authored
test: Auth integration test for signUp, signIn, fetchSession (#479)
* Added basic integration test for signIn, signUp and session apis * Fixed operation that does not cancel when cancel is called * Changed the integration test target from UITest to UnitTest so that keychain access works correctly.
1 parent c33bf1b commit a6bb418

File tree

14 files changed

+995
-284
lines changed

14 files changed

+995
-284
lines changed

AmplifyPlugins/Auth/AWSCognitoAuthPlugin.xcodeproj/project.pbxproj

Lines changed: 307 additions & 251 deletions
Large diffs are not rendered by default.

AmplifyPlugins/Auth/AWSCognitoAuthPlugin.xcodeproj/xcshareddata/xcschemes/AWSCognitoAuthPluginIntegrationTests.xcscheme

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,18 @@
1010
buildConfiguration = "Debug"
1111
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
1212
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
13-
shouldUseLaunchSchemeArgsEnv = "YES">
13+
shouldUseLaunchSchemeArgsEnv = "YES"
14+
codeCoverageEnabled = "YES"
15+
onlyGenerateCoverageForSpecifiedTargets = "YES">
16+
<CodeCoverageTargets>
17+
<BuildableReference
18+
BuildableIdentifier = "primary"
19+
BlueprintIdentifier = "B43DC7442410572400D40275"
20+
BuildableName = "AWSCognitoAuthPlugin.framework"
21+
BlueprintName = "AWSCognitoAuthPlugin"
22+
ReferencedContainer = "container:AWSCognitoAuthPlugin.xcodeproj">
23+
</BuildableReference>
24+
</CodeCoverageTargets>
1425
<Testables>
1526
<TestableReference
1627
skipped = "NO">

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Operations/AWSAuthConfirmSignUpOperation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public class AWSAuthConfirmSignUpOperation: AmplifyOperation<
4646
defer {
4747
self.finish()
4848
}
49+
50+
if self.isCancelled {
51+
return
52+
}
53+
4954
switch result {
5055
case .failure(let error):
5156
self.dispatch(error)

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Operations/AWSAuthResendSignUpCodeOperation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public class AWSAuthResendSignUpCodeOperation: AmplifyOperation<
4646
defer {
4747
self.finish()
4848
}
49+
50+
if self.isCancelled {
51+
return
52+
}
53+
4954
switch result {
5055
case .failure(let error):
5156
self.dispatch(error)

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Operations/AWSAuthSignInOperation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public class AWSAuthSignInOperation: AmplifyOperation<
4545
defer {
4646
self.finish()
4747
}
48+
49+
if self.isCancelled {
50+
return
51+
}
52+
4853
switch result {
4954
case .failure(let error):
5055
self.dispatch(error)

AmplifyPlugins/Auth/AWSCognitoAuthPluginIntegrationTests/AWSAuthBaseTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import AWSCognitoAuthPlugin
1111

1212
class AWSAuthBaseTest: XCTestCase {
1313

14-
let networkTimeout = TimeInterval(180) // 180 seconds to wait before network timeouts
14+
let networkTimeout = TimeInterval(10)
1515

1616
func initializeAmplify() {
1717

AmplifyPlugins/Auth/AWSCognitoAuthPluginIntegrationTests/AuthSessionTests/SignedInAuthSessionTests.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,27 @@ class SignedInAuthSessionTests: AWSAuthBaseTest {
2323
}
2424

2525
func testSuccessfulSessionFetch() {
26+
let username = "integTest\(UUID().uuidString)"
27+
let password = "P123@\(UUID().uuidString)"
28+
let signInExpectation = expectation(description: "SignIn operation should complete")
29+
AuthSignInHelper.registerAndSignInUser(username: username, password: password) { didSucceed, error in
30+
signInExpectation.fulfill()
31+
XCTAssertTrue(didSucceed, "SignIn operation failed - \(String(describing: error))")
32+
}
33+
wait(for: [signInExpectation], timeout: networkTimeout)
34+
2635
let authSessionExpectation = expectation(description: "Received event result from fetchAuth")
27-
_ = Amplify.Auth.fetchAuthSession { _ in
28-
authSessionExpectation.fulfill()
36+
_ = Amplify.Auth.fetchAuthSession { result in
37+
defer {
38+
authSessionExpectation.fulfill()
39+
}
40+
switch result {
41+
case .success(let session):
42+
XCTAssertTrue(session.isSignedIn, "Session state should be signed In")
43+
case .failure(let error):
44+
XCTFail("Should not receive error \(error)")
45+
}
2946
}
30-
wait(for: [authSessionExpectation], timeout: 500)
47+
wait(for: [authSessionExpectation], timeout: networkTimeout)
3148
}
3249
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import XCTest
9+
@testable import Amplify
10+
import AWSCognitoAuthPlugin
11+
12+
class AuthUsernamePasswordSignInTests: AWSAuthBaseTest {
13+
14+
override func setUp() {
15+
super.setUp()
16+
initializeAmplify()
17+
}
18+
19+
override func tearDown() {
20+
super.tearDown()
21+
Amplify.reset()
22+
sleep(2)
23+
}
24+
25+
/// Test successful signIn of a valid user
26+
///
27+
/// - Given: A user registered in Cognito user pool
28+
/// - When:
29+
/// - I invoke Amplify.Auth.signIn with the username password
30+
/// - Then:
31+
/// - I should get a completed signIn flow.
32+
///
33+
func testSuccessfulSignIn() {
34+
35+
let username = "integTest\(UUID().uuidString)"
36+
let password = "P123@\(UUID().uuidString)"
37+
38+
let signUpExpectation = expectation(description: "SignUp operation should complete")
39+
AuthSignInHelper.signUpUser(username: username, password: password) { didSucceed, error in
40+
signUpExpectation.fulfill()
41+
XCTAssertTrue(didSucceed, "Signup operation failed - \(String(describing: error))")
42+
}
43+
wait(for: [signUpExpectation], timeout: networkTimeout)
44+
45+
let operationExpectation = expectation(description: "Operation should complete")
46+
let operation = Amplify.Auth.signIn(username: username, password: password) { result in
47+
defer {
48+
operationExpectation.fulfill()
49+
}
50+
switch result {
51+
case .success(let signInResult):
52+
XCTAssertTrue(signInResult.isSignedIn, "SignIn should be complete")
53+
case .failure(let error):
54+
XCTFail("SignIn with a valid username/password should not fail \(error)")
55+
}
56+
}
57+
XCTAssertNotNil(operation, "SignIn operation should not be nil")
58+
wait(for: [operationExpectation], timeout: networkTimeout)
59+
}
60+
61+
/// Test if user not found error is returned for signIn with unknown user
62+
///
63+
/// - Given: Amplify Auth plugin in signedout state
64+
/// - When:
65+
/// - I try to signIn with an unknown user
66+
/// - Then:
67+
/// - I should get a user not found error
68+
///
69+
func testSignInWithInvalidUser() {
70+
let operationExpectation = expectation(description: "Operation should complete")
71+
let operation = Amplify.Auth.signIn(username: "username-doesnot-exist", password: "password") { result in
72+
defer {
73+
operationExpectation.fulfill()
74+
}
75+
switch result {
76+
case .success:
77+
XCTFail("SignIn with unknown user should not succeed")
78+
case .failure(let error):
79+
guard let cognitoError = error.underlyingError as? AWSCognitoAuthError,
80+
case .userNotFound = cognitoError else {
81+
XCTFail("Should return userNotFound error")
82+
return
83+
}
84+
}
85+
}
86+
XCTAssertNotNil(operation, "SignIn operation should not be nil")
87+
wait(for: [operationExpectation], timeout: networkTimeout)
88+
}
89+
90+
/// Test if signIn to an already signedIn session returns error
91+
///
92+
/// - Given: Amplify Auth plugin in signedIn state
93+
/// - When:
94+
/// - I try to signIn again
95+
/// - Then:
96+
/// - I should get a invalid state error
97+
///
98+
func testSignInWhenAlreadySignedIn() {
99+
let username = "integTest\(UUID().uuidString)"
100+
let password = "P123@\(UUID().uuidString)"
101+
102+
let firstSignInExpectation = expectation(description: "SignIn operation should complete")
103+
AuthSignInHelper.registerAndSignInUser(username: username, password: password) { didSucceed, error in
104+
firstSignInExpectation.fulfill()
105+
XCTAssertTrue(didSucceed, "SignIn operation failed - \(String(describing: error))")
106+
}
107+
wait(for: [firstSignInExpectation], timeout: networkTimeout)
108+
109+
let secondSignInExpectation = expectation(description: "SignIn operation should complete")
110+
AuthSignInHelper.signInUser(username: username, password: password) { didSucceed, error in
111+
defer {
112+
secondSignInExpectation.fulfill()
113+
}
114+
XCTAssertFalse(didSucceed, "Second signIn should fail")
115+
guard case .invalidState(_, _, _) = error else {
116+
XCTFail("Should return invalid state \(String(describing: error))")
117+
return
118+
}
119+
120+
}
121+
wait(for: [secondSignInExpectation], timeout: networkTimeout)
122+
}
123+
124+
/// Test if signIn return validation error
125+
///
126+
/// - Given: An invalid input to signIn like empty username
127+
/// - When:
128+
/// - I invoke signIn with empty username
129+
/// - Then:
130+
/// - I should get validation error.
131+
///
132+
func testSignInValidation() {
133+
let operationExpectation = expectation(description: "Operation should complete")
134+
let operation = Amplify.Auth.signIn(username: "", password: "password") { result in
135+
defer {
136+
operationExpectation.fulfill()
137+
}
138+
switch result {
139+
case .success:
140+
XCTFail("SignIn with empty user should not succeed")
141+
case .failure(let error):
142+
guard case .validation(_, _, _, _) = error else {
143+
XCTFail("Should return validation error")
144+
return
145+
}
146+
}
147+
}
148+
XCTAssertNotNil(operation, "SignIn operation should not be nil")
149+
wait(for: [operationExpectation], timeout: networkTimeout)
150+
}
151+
152+
/// Calling cancel in signIn operation should cancel
153+
///
154+
/// - Given: A valid username and password
155+
/// - When:
156+
/// - I invoke signIn with the username password and then call cancel
157+
/// - Then:
158+
/// - I should not get any result back
159+
///
160+
func testCancelSignInOperation() {
161+
let username = "integTest\(UUID().uuidString)"
162+
let password = "P123@\(UUID().uuidString)"
163+
let operationExpectation = expectation(description: "Operation should not complete")
164+
operationExpectation.isInverted = true
165+
let operation = Amplify.Auth.signIn(username: username, password: password) { result in
166+
XCTFail("Received result \(result)")
167+
operationExpectation.fulfill()
168+
}
169+
XCTAssertNotNil(operation, "signIn operations should not be nil")
170+
operation.cancel()
171+
wait(for: [operationExpectation], timeout: networkTimeout)
172+
}
173+
174+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import XCTest
9+
@testable import Amplify
10+
import AWSCognitoAuthPlugin
11+
12+
class AuthConfirmSignUpTests: AWSAuthBaseTest {
13+
14+
override func setUp() {
15+
super.setUp()
16+
initializeAmplify()
17+
}
18+
19+
override func tearDown() {
20+
super.tearDown()
21+
Amplify.reset()
22+
sleep(2)
23+
}
24+
25+
/// Test if confirmSignUp returns userNotFound error for a non existing user
26+
///
27+
/// - Given: A user which is not registered to the configured user pool
28+
/// - When:
29+
/// - I invoke confirmSignUp with the user
30+
/// - Then:
31+
/// - I should get a userNotFound error.
32+
///
33+
func testUserNotFoundConfirmSignUp() {
34+
let confirmSignUpExpectation = expectation(description: "Received event result from confirmSignUp")
35+
_ = Amplify.Auth.confirmSignUp(for: "user-non-exists", confirmationCode: "232") { result in
36+
switch result {
37+
case .success:
38+
XCTFail("Confirm signUp with non existing user should not return result")
39+
case .failure(let error):
40+
guard let cognitoError = error.underlyingError as? AWSCognitoAuthError,
41+
case .userNotFound = cognitoError else {
42+
XCTFail("Should return userNotFound")
43+
return
44+
}
45+
46+
}
47+
confirmSignUpExpectation.fulfill()
48+
}
49+
wait(for: [confirmSignUpExpectation], timeout: networkTimeout)
50+
}
51+
52+
/// Test confirmSignUp return validation error
53+
///
54+
/// - Given: An invalid input to confirmSignUp like empty code
55+
/// - When:
56+
/// - I invoke confirmSignUp with empty code
57+
/// - Then:
58+
/// - I should get validation error.
59+
///
60+
func testConfirmSignUpValidation() {
61+
let username = "integTest\(UUID().uuidString)"
62+
63+
let operationExpectation = expectation(description: "Operation should complete")
64+
let operation = Amplify.Auth.confirmSignUp(for: username,
65+
confirmationCode: "") { result in
66+
defer {
67+
operationExpectation.fulfill()
68+
}
69+
switch result {
70+
case .success:
71+
XCTFail("confirmSignUp with validation error should not succeed")
72+
case .failure(let error):
73+
guard case .validation(_, _, _, _) = error else {
74+
XCTFail("Should return validation error")
75+
return
76+
}
77+
}
78+
}
79+
XCTAssertNotNil(operation, "confirmSignUp operations should not be nil")
80+
wait(for: [operationExpectation], timeout: networkTimeout)
81+
}
82+
83+
/// Calling cancel in confirmSignUp operation should cancel
84+
///
85+
/// - Given: A valid username and code
86+
/// - When:
87+
/// - I invoke confirmSignUp with the username and confirmatioCode and then call cancel
88+
/// - Then:
89+
/// - I should not get any result back
90+
///
91+
func testCancelConfirmSignUpOperation() {
92+
let username = "integTest\(UUID().uuidString)"
93+
94+
let operationExpectation = expectation(description: "Operation should not complete")
95+
operationExpectation.isInverted = true
96+
let operation = Amplify.Auth.confirmSignUp(for: username,
97+
confirmationCode: "123") { result in
98+
operationExpectation.fulfill()
99+
XCTFail("Received result \(result)")
100+
}
101+
XCTAssertNotNil(operation, "confirmSignUp operations should not be nil")
102+
operation.cancel()
103+
wait(for: [operationExpectation], timeout: networkTimeout)
104+
}
105+
}

0 commit comments

Comments
 (0)