@@ -31,7 +31,7 @@ final class MSALNativeAuthResetPasswordEndToEndTests: MSALNativeAuthEndToEndBase
31
31
private let codeRetryCount = 3
32
32
33
33
func test_resetPassword_withoutAutomaticSignIn_succeeds( ) async throws {
34
- throw XCTSkip ( " 1secmail service is down. Ignoring test for now. " )
34
+ throw XCTSkip ( " Retrieving OTP failure " )
35
35
36
36
guard let sut = initialisePublicClientApplication ( ) ,
37
37
let username = retrieveUsernameForResetPassword ( )
@@ -71,10 +71,173 @@ final class MSALNativeAuthResetPasswordEndToEndTests: MSALNativeAuthEndToEndBase
71
71
await fulfillment ( of: [ resetPasswordCompletedExp] )
72
72
XCTAssertTrue ( resetPasswordRequiredDelegate. onResetPasswordCompletedCalled)
73
73
}
74
+
75
+ // User Case 3.1.3. SSPR – New password being set doesn’t meet password complexity requirements set on portal
76
+ func test_resetPassword_passwordComplexity_error( ) async throws {
77
+ throw XCTSkip ( " Retrieving OTP failure " )
78
+
79
+ guard let sut = initialisePublicClientApplication ( ) ,
80
+ let username = retrieveUsernameForResetPassword ( )
81
+ else {
82
+ XCTFail ( " Missing information " )
83
+ return
84
+ }
85
+ let codeRequiredExp = expectation ( description: " code required " )
86
+ let resetPasswordStartDelegate = ResetPasswordStartDelegateSpy ( expectation: codeRequiredExp)
87
+
88
+ sut. resetPassword ( username: username, delegate: resetPasswordStartDelegate)
89
+
90
+ await fulfillment ( of: [ codeRequiredExp] )
91
+ XCTAssertTrue ( resetPasswordStartDelegate. onResetPasswordCodeRequiredCalled)
92
+
93
+ guard resetPasswordStartDelegate. onResetPasswordCodeRequiredCalled else {
94
+ XCTFail ( " onResetPasswordCodeRequired not called " )
95
+ return
96
+ }
97
+
98
+ XCTAssertEqual ( resetPasswordStartDelegate. channelTargetType? . isEmailType, true )
99
+ XCTAssertFalse ( resetPasswordStartDelegate. sentTo? . isEmpty ?? true )
100
+ XCTAssertNotNil ( resetPasswordStartDelegate. codeLength)
101
+
102
+ // Now submit the code...
103
+ let newPasswordRequiredState = await retrieveAndSubmitCode ( resetPasswordStartDelegate: resetPasswordStartDelegate,
104
+ username: username,
105
+ retries: codeRetryCount)
106
+
107
+ // Now submit the password...
108
+ let resetPasswordCompletedExp = expectation ( description: " reset password completed " )
109
+ let resetPasswordRequiredDelegate = ResetPasswordRequiredDelegateSpy ( expectation: resetPasswordCompletedExp)
110
+
111
+ let uniquePassword = " INVALID_Passwprd "
112
+ newPasswordRequiredState? . submitPassword ( password: uniquePassword, delegate: resetPasswordRequiredDelegate)
113
+
114
+ await fulfillment ( of: [ resetPasswordCompletedExp] )
115
+ XCTAssertTrue ( resetPasswordRequiredDelegate. onResetPasswordCompletedCalled)
116
+ }
117
+
118
+ // User Case 3.1.4 SSPR - Resend email OTP
119
+ func test_resetPassword_resendCode_succeeds( ) async throws {
120
+ throw XCTSkip ( " Retrieving OTP failure " )
121
+
122
+ guard let sut = initialisePublicClientApplication ( ) ,
123
+ let username = retrieveUsernameForResetPassword ( )
124
+ else {
125
+ XCTFail ( " Missing information " )
126
+ return
127
+ }
128
+ let codeRequiredExp = expectation ( description: " code required " )
129
+ let resetPasswordStartDelegate = ResetPasswordStartDelegateSpy ( expectation: codeRequiredExp)
130
+
131
+ sut. resetPassword ( username: username, delegate: resetPasswordStartDelegate)
132
+
133
+ await fulfillment ( of: [ codeRequiredExp] )
134
+ XCTAssertTrue ( resetPasswordStartDelegate. onResetPasswordCodeRequiredCalled)
135
+
136
+ guard resetPasswordStartDelegate. onResetPasswordCodeRequiredCalled else {
137
+ XCTFail ( " onResetPasswordCodeRequired not called " )
138
+ return
139
+ }
140
+
141
+ // Now get code1...
142
+ guard let code1 = await retrieveCodeFor ( email: username) else {
143
+ XCTFail ( " OTP code could not be retrieved " )
144
+ return
145
+ }
146
+
147
+ // Resend code
148
+ let resendCodeRequiredExp = expectation ( description: " code required again " )
149
+ let resetPasswordResendCodeDelegate = ResetPasswordResendCodeDelegateSpy ( expectation: resendCodeRequiredExp)
150
+
151
+ // Call resend code method
152
+ resetPasswordStartDelegate. newState? . resendCode ( delegate: resetPasswordResendCodeDelegate)
153
+
154
+ await fulfillment ( of: [ resendCodeRequiredExp] )
155
+
156
+ // Verify that resend code method was called
157
+ XCTAssertTrue ( resetPasswordResendCodeDelegate. onResetPasswordResendCodeCodeRequiredCalled,
158
+ " Resend code method should have been called " )
159
+
160
+ // Now get code2...
161
+ guard let code2 = await retrieveCodeFor ( email: username) else {
162
+ XCTFail ( " OTP code could not be retrieved " )
163
+ return
164
+ }
165
+
166
+ // Verify that the codes are different
167
+ XCTAssertNotEqual ( code1, code2, " Resent code should be different from the original code " )
168
+ }
169
+
170
+ // User Case 3.1.5 SSPR - Email is not found in records
171
+ func test_resetPassword_emailNotFound_error( ) async throws {
172
+ guard let sut = initialisePublicClientApplication ( ) ,
173
+ let username = retrieveUsernameForResetPassword ( )
174
+ else {
175
+ XCTFail ( " Missing information " )
176
+ return
177
+ }
178
+
179
+ let resetPasswordFailureExp = expectation ( description: " reset password user not found " )
180
+ let resetPasswordStartDelegate = ResetPasswordStartDelegateSpy ( expectation: resetPasswordFailureExp)
181
+
182
+ sut. resetPassword ( username: username, delegate: resetPasswordStartDelegate)
183
+
184
+ await fulfillment ( of: [ resetPasswordFailureExp] )
185
+
186
+ // Verify error condition
187
+ XCTAssertTrue ( resetPasswordStartDelegate. onResetPasswordErrorCalled)
188
+ XCTAssertEqual ( resetPasswordStartDelegate. error? . isUserNotFound, true )
189
+ }
190
+
191
+ // User Case 3.1.6 SSPR - When SSPR requires a challenge type not supported by the client, redirect to web-fallback
192
+ func test_resetPassword_webfallback_error( ) async throws {
193
+ guard let sut = initialisePublicClientApplication ( challengeTypes: [ . password] ) ,
194
+ let username = retrieveUsernameForResetPassword ( )
195
+ else {
196
+ XCTFail ( " Missing information " )
197
+ return
198
+ }
199
+
200
+ let resetPasswordFailureExp = expectation ( description: " reset password web-fallback " )
201
+ let resetPasswordStartDelegate = ResetPasswordStartDelegateSpy ( expectation: resetPasswordFailureExp)
202
+
203
+ sut. resetPassword ( username: username, delegate: resetPasswordStartDelegate)
204
+
205
+ await fulfillment ( of: [ resetPasswordFailureExp] )
206
+
207
+ // Verify error condition
208
+ XCTAssertTrue ( resetPasswordStartDelegate. onResetPasswordErrorCalled)
209
+ XCTAssertEqual ( resetPasswordStartDelegate. error? . isBrowserRequired, true )
210
+ }
211
+
212
+ // User Case 3.1.8 SSPR – Email exists but not linked to any password
213
+ // Not applicable
214
+
215
+ // User Case 3.1.9 - Email exists but signup method was OTP, social, etc.
216
+ func test_resetPassword_socialAccount_error( ) async throws {
217
+ throw XCTSkip ( " Skipping test as it requires a Social account, not present in MSIDLAB " )
218
+
219
+ guard let sut = initialisePublicClientApplication ( ) else {
220
+ XCTFail ( " Missing information " )
221
+ return
222
+ }
223
+
224
+ let username = " invalid "
225
+
226
+ let resetPasswordFailureExp = expectation ( description: " reset password user not found " )
227
+ let resetPasswordStartDelegate = ResetPasswordStartDelegateSpy ( expectation: resetPasswordFailureExp)
228
+
229
+ sut. resetPassword ( username: username, delegate: resetPasswordStartDelegate)
230
+
231
+ await fulfillment ( of: [ resetPasswordFailureExp] )
232
+
233
+ // Verify error condition
234
+ XCTAssertTrue ( resetPasswordStartDelegate. onResetPasswordErrorCalled)
235
+ XCTAssertEqual ( resetPasswordStartDelegate. error? . isInvalidUsername, true )
236
+ }
74
237
75
238
// SSPR - with automatic sign in
76
239
func test_resetPassword_withAutomaticSignIn_succeeds( ) async throws {
77
- throw XCTSkip ( " 1secmail service is down. Ignoring test for now. " )
240
+ throw XCTSkip ( " Retrieving OTP failure " )
78
241
79
242
guard let sut = initialisePublicClientApplication ( ) ,
80
243
let username = retrieveUsernameForResetPassword ( )
0 commit comments