Skip to content

Commit

Permalink
adding integration tests wave 1
Browse files Browse the repository at this point in the history
  • Loading branch information
harsh62 committed Oct 3, 2024
1 parent fedf82a commit 18a8c70
Show file tree
Hide file tree
Showing 5 changed files with 469 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@
485CB5C027B61F1E006CCEC7 /* SignedOutAuthSessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485CB5BC27B61F1D006CCEC7 /* SignedOutAuthSessionTests.swift */; };
485CB5C127B61F1E006CCEC7 /* AuthSignOutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485CB5BD27B61F1D006CCEC7 /* AuthSignOutTests.swift */; };
485CB5C227B61F1E006CCEC7 /* AuthSRPSignInTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485CB5BE27B61F1D006CCEC7 /* AuthSRPSignInTests.swift */; };
487C40232CACF303009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487C40222CACF2FD009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift */; };
487C40242CACF303009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487C40222CACF2FD009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift */; };
487C40252CACF303009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487C40222CACF2FD009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift */; };
487C40382CACFD50009CF221 /* AWSAPIPlugin in Frameworks */ = {isa = PBXBuildFile; productRef = 487C40372CACFD50009CF221 /* AWSAPIPlugin */; };
487C403F2CADE8DA009CF221 /* EmailMFAOnlyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487C403E2CADE88F009CF221 /* EmailMFAOnlyTests.swift */; };
487C40402CADE8DA009CF221 /* EmailMFAOnlyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487C403E2CADE88F009CF221 /* EmailMFAOnlyTests.swift */; };
487C40412CADE8DA009CF221 /* EmailMFAOnlyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487C403E2CADE88F009CF221 /* EmailMFAOnlyTests.swift */; };
48916F382A412B2800E3E1B1 /* TOTPSetupWhenAuthenticatedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48916F372A412B2800E3E1B1 /* TOTPSetupWhenAuthenticatedTests.swift */; };
48916F3A2A412CEE00E3E1B1 /* TOTPHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48916F392A412CEE00E3E1B1 /* TOTPHelper.swift */; };
48916F3C2A42333E00E3E1B1 /* MFAPreferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48916F3B2A42333E00E3E1B1 /* MFAPreferenceTests.swift */; };
Expand Down Expand Up @@ -196,6 +203,8 @@
485CB5BC27B61F1D006CCEC7 /* SignedOutAuthSessionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignedOutAuthSessionTests.swift; sourceTree = "<group>"; };
485CB5BD27B61F1D006CCEC7 /* AuthSignOutTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthSignOutTests.swift; sourceTree = "<group>"; };
485CB5BE27B61F1D006CCEC7 /* AuthSRPSignInTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthSRPSignInTests.swift; sourceTree = "<group>"; };
487C40222CACF2FD009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailMFAWithAllMFATypesRequiredTests.swift; sourceTree = "<group>"; };
487C403E2CADE88F009CF221 /* EmailMFAOnlyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailMFAOnlyTests.swift; sourceTree = "<group>"; };
48916F372A412B2800E3E1B1 /* TOTPSetupWhenAuthenticatedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TOTPSetupWhenAuthenticatedTests.swift; sourceTree = "<group>"; };
48916F392A412CEE00E3E1B1 /* TOTPHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TOTPHelper.swift; sourceTree = "<group>"; };
48916F3B2A42333E00E3E1B1 /* MFAPreferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFAPreferenceTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -232,6 +241,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
487C40382CACFD50009CF221 /* AWSAPIPlugin in Frameworks */,
B4B9F45828F47C0A004F346F /* Amplify in Frameworks */,
B4B9F45A28F47C0A004F346F /* AWSCognitoAuthPlugin in Frameworks */,
);
Expand Down Expand Up @@ -432,9 +442,19 @@
name = Packages;
sourceTree = "<group>";
};
487C403D2CADBC37009CF221 /* EmailMFATests */ = {
isa = PBXGroup;
children = (
487C403E2CADE88F009CF221 /* EmailMFAOnlyTests.swift */,
487C40222CACF2FD009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift */,
);
path = EmailMFATests;
sourceTree = "<group>";
};
48916F362A412AF800E3E1B1 /* MFATests */ = {
isa = PBXGroup;
children = (
487C403D2CADBC37009CF221 /* EmailMFATests */,
48916F372A412B2800E3E1B1 /* TOTPSetupWhenAuthenticatedTests.swift */,
48916F3B2A42333E00E3E1B1 /* MFAPreferenceTests.swift */,
48599D492A429893009DE21C /* MFASignInTests.swift */,
Expand Down Expand Up @@ -534,6 +554,7 @@
packageProductDependencies = (
B4B9F45728F47C0A004F346F /* Amplify */,
B4B9F45928F47C0A004F346F /* AWSCognitoAuthPlugin */,
487C40372CACFD50009CF221 /* AWSAPIPlugin */,
);
productName = AuthHostApp;
productReference = 485CB53A27B614CE006CCEC7 /* AuthHostApp.app */;
Expand Down Expand Up @@ -819,6 +840,7 @@
21F762B22BD6B1AA0048845A /* SignedOutAuthSessionTests.swift in Sources */,
21F762B32BD6B1AA0048845A /* AuthSignInHelper.swift in Sources */,
21F762B42BD6B1AA0048845A /* FederatedSessionTests.swift in Sources */,
487C40402CADE8DA009CF221 /* EmailMFAOnlyTests.swift in Sources */,
21F762B52BD6B1AA0048845A /* AuthCustomSignInTests.swift in Sources */,
21F762B62BD6B1AA0048845A /* AuthEventIntegrationTests.swift in Sources */,
21F762B72BD6B1AA0048845A /* AuthEnvironmentHelper.swift in Sources */,
Expand All @@ -832,6 +854,7 @@
21F762BF2BD6B1AA0048845A /* MFASignInTests.swift in Sources */,
21F762C02BD6B1AA0048845A /* SignedInAuthSessionTests.swift in Sources */,
21F762C12BD6B1AA0048845A /* AuthSignUpTests.swift in Sources */,
487C40252CACF303009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift in Sources */,
21F762C22BD6B1AA0048845A /* AuthConfirmResetPasswordTests.swift in Sources */,
21F762C32BD6B1AA0048845A /* AuthDeleteUserTests.swift in Sources */,
);
Expand All @@ -851,6 +874,7 @@
buildActionMask = 2147483647;
files = (
485CB5B927B61F10006CCEC7 /* AuthSessionHelper.swift in Sources */,
487C403F2CADE8DA009CF221 /* EmailMFAOnlyTests.swift in Sources */,
681DFEAB28E747B80000C36A /* AsyncTesting.swift in Sources */,
485CB5C227B61F1E006CCEC7 /* AuthSRPSignInTests.swift in Sources */,
9737C7502880BFD600DA0D2B /* AuthForgetDeviceTests.swift in Sources */,
Expand All @@ -863,6 +887,7 @@
48E3AB3128E52590004EE395 /* GetCurrentUserTests.swift in Sources */,
48916F3A2A412CEE00E3E1B1 /* TOTPHelper.swift in Sources */,
21CFD7C62C7524570071C70F /* AppSyncSignerTests.swift in Sources */,
487C40232CACF303009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift in Sources */,
485CB5B127B61EAC006CCEC7 /* AWSAuthBaseTest.swift in Sources */,
485CB5C027B61F1E006CCEC7 /* SignedOutAuthSessionTests.swift in Sources */,
485CB5BA27B61F10006CCEC7 /* AuthSignInHelper.swift in Sources */,
Expand Down Expand Up @@ -914,6 +939,7 @@
681B76AC2A3CBBAE004B59D9 /* AWSAuthBaseTest.swift in Sources */,
681B76AD2A3CBBAE004B59D9 /* SignedOutAuthSessionTests.swift in Sources */,
681B76AE2A3CBBAE004B59D9 /* AuthSignInHelper.swift in Sources */,
487C40412CADE8DA009CF221 /* EmailMFAOnlyTests.swift in Sources */,
681B76AF2A3CBBAE004B59D9 /* FederatedSessionTests.swift in Sources */,
681B76B02A3CBBAE004B59D9 /* AuthCustomSignInTests.swift in Sources */,
681B76B12A3CBBAE004B59D9 /* AuthEventIntegrationTests.swift in Sources */,
Expand All @@ -927,6 +953,7 @@
681B76B92A3CBBAE004B59D9 /* SignedInAuthSessionTests.swift in Sources */,
681B76BA2A3CBBAE004B59D9 /* AuthSignUpTests.swift in Sources */,
681B76BB2A3CBBAE004B59D9 /* AuthConfirmResetPasswordTests.swift in Sources */,
487C40242CACF303009CF221 /* EmailMFAWithAllMFATypesRequiredTests.swift in Sources */,
48BCE8942A54564C0012C3CD /* MFASignInTests.swift in Sources */,
681B76BC2A3CBBAE004B59D9 /* AuthDeleteUserTests.swift in Sources */,
);
Expand Down Expand Up @@ -1479,6 +1506,10 @@
/* End XCConfigurationList section */

/* Begin XCSwiftPackageProductDependency section */
487C40372CACFD50009CF221 /* AWSAPIPlugin */ = {
isa = XCSwiftPackageProductDependency;
productName = AWSAPIPlugin;
};
681B76992A3CBA97004B59D9 /* Amplify */ = {
isa = XCSwiftPackageProductDependency;
productName = Amplify;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ class AWSAuthBaseTest: XCTestCase {
var amplifyConfiguration: AmplifyConfiguration!
var amplifyOutputs: AmplifyOutputsData!

var onlyUseGen2Configuration = false

var useGen2Configuration: Bool {
ProcessInfo.processInfo.arguments.contains("GEN2")
ProcessInfo.processInfo.arguments.contains("GEN2") || onlyUseGen2Configuration
}

override func setUp() async throws {
Expand All @@ -46,6 +48,7 @@ class AWSAuthBaseTest: XCTestCase {

override func tearDown() async throws {
try await super.tearDown()
subscription?.cancel()
await Amplify.reset()
}

Expand Down Expand Up @@ -113,6 +116,84 @@ class AWSAuthBaseTest: XCTestCase {
XCTFail("Amplify configuration failed")
}
}

// Dictionary to store MFA codes with usernames as keys
var mfaCodeDictionary: [String: String] = [:]
var subscription: AmplifyAsyncThrowingSequence<GraphQLSubscriptionEvent<[String: JSONValue]>>? = nil

let document: String = """
subscription OnCreateMfaInfo {
onCreateMfaInfo {
username
code
expirationTime
}
}
"""

/// Function to create a subscription and store MFA codes in a dictionary
func createMFASubscription() {
subscription = Amplify.API.subscribe(request: .init(document: document, responseType: [String: JSONValue].self))

// Create the subscription and listen for MFA code events
Task {
do {
guard let subscription = subscription else { return }
for try await subscriptionEvent in subscription {
switch subscriptionEvent {
case .connection(let subscriptionConnectionState):
print("Subscription connect state is \(subscriptionConnectionState)")
case .data(let result):
switch result {
case .success(let mfaCodeResult):
print("Successfully got MFA code from subscription: \(mfaCodeResult)")
if let eventUsername = mfaCodeResult["onCreateMfaInfo"]?.asObject?["username"]?.stringValue,
let code = mfaCodeResult["onCreateMfaInfo"]?.asObject?["code"]?.stringValue {
// Store the code in the dictionary for the given username
mfaCodeDictionary[eventUsername] = code
}
case .failure(let error):
print("Got failed result with \(error.errorDescription)")
}
}
}
} catch {
print("Subscription terminated with error: \(error)")
}
}
}

/// Test that waits for the MFA code using XCTestExpectation
func waitForMFACode(for username: String) async throws -> String? {
let expectation = XCTestExpectation(description: "Wait for MFA code")
expectation.expectedFulfillmentCount = 1

let task = Task { () -> String? in
var code: String?
for _ in 0..<30 { // Poll for the code, max 30 times (once per second)
if let mfaCode = mfaCodeDictionary[username] {
code = mfaCode
expectation.fulfill() // Fulfill the expectation when the value is found
break
}
try await Task.sleep(nanoseconds: 1_000_000_000) // Sleep for 1 second
}
return code
}

// Wait for expectation or timeout after 30 seconds
let result = await XCTWaiter.fulfillment(of: [expectation], timeout: 30)

if result == .timedOut {
// Task cancels if timed out
task.cancel()
subscription?.cancel()
return nil
}

subscription?.cancel()
return try await task.value
}
}

class TestConfigHelper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,20 @@ enum AuthSignInHelper {
password: String,
email: String,
phoneNumber: String? = nil) async throws -> Bool {
return try await signUpUserReturningResult(username: username, password: password, email: email, phoneNumber: phoneNumber).isSignUpComplete
}

static func signUpUserReturningResult(
username: String,
password: String,
email: String? = nil,
phoneNumber: String? = nil) async throws -> AuthSignUpResult {

var userAttributes: [AuthUserAttribute] = []

var userAttributes = [
AuthUserAttribute(.email, value: email)
]
if let email = email {
userAttributes.append(AuthUserAttribute(.email, value: email))
}

if let phoneNumber = phoneNumber {
userAttributes.append(AuthUserAttribute(.phoneNumber, value: phoneNumber))
Expand All @@ -34,7 +44,7 @@ enum AuthSignInHelper {
let options = AuthSignUpRequest.Options(
userAttributes: userAttributes)
let result = try await Amplify.Auth.signUp(username: username, password: password, options: options)
return result.isSignUpComplete
return result
}

static func signInUser(username: String, password: String) async throws -> AuthSignInResult {
Expand All @@ -46,7 +56,7 @@ enum AuthSignInHelper {
password: String,
email: String,
phoneNumber: String? = nil) async throws -> Bool {
let signedUp = try await AuthSignInHelper.signUpUser(
let signedUp: Bool = try await AuthSignInHelper.signUpUser(
username: username,
password: password,
email: email,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import XCTest
import Amplify
import AWSCognitoAuthPlugin
import AWSAPIPlugin

// MFA Required
// - Email
class EmailMFAOnlyTests: AWSAuthBaseTest {

override func setUp() async throws {
onlyUseGen2Configuration = true
// Use a custom configuration these tests
amplifyOutputsFile = "testconfiguration/amplify_outputs"

let awsApiPlugin = AWSAPIPlugin()
try Amplify.add(plugin: awsApiPlugin)
try await super.setUp()
AuthSessionHelper.clearSession()
}

override func tearDown() async throws {
try await super.tearDown()
AuthSessionHelper.clearSession()
}

/// Test a signIn with valid inputs getting continueSignInWithEmailMFASetup challenge
///
/// - Given: Given an auth plugin with mocked service.
///
/// - When:
/// - I invoke signIn with valid values
/// - Then:
/// - I should get a .continueSignInWithEmailMFASetup response
///
//Requires only Email MFA to be enabled
func disabled_testSuccessfulEmailMFASetupStep() async {

do {
let uniqueId = UUID().uuidString
let username = "integTest\(uniqueId)"
let password = "Pp123@\(uniqueId)"

_ = try await AuthSignInHelper.signUpUserReturningResult(
username: username,
password: password)

let options = AuthSignInRequest.Options()
let result = try await Amplify.Auth.signIn(
username: username,
password: password,
options: options)

guard case .continueSignInWithEmailMFASetup = result.nextStep else {
XCTFail("Result should be .continueSignInWithEmailMFASetup for next step, instead got: \(result.nextStep)")
return
}
XCTAssertFalse(result.isSignedIn, "Signin result should be complete")
} catch {
XCTFail("Received failure with error \(error)")
}
}
}
Loading

0 comments on commit 18a8c70

Please sign in to comment.