Add SSPR v2 e2e basic tests - #3052
Conversation
Add MSALNativeAuthResetPasswordV2EndToEndTests covering the server-driven V2 self-service password reset flow (resetPasswordV2) via the unified delegate: code-required -> submitCode -> new-password-required -> submitNewPassword -> flow-completed, plus invalid-password, resend-code, and email-not-found cases. Wired into both Native Auth E2E targets. Tests are XCTSkip-gated until a V2 test tenant is enabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b8c2b650-9e9e-46ad-b344-f31b6d39cb7c
| /// (`onCodeRequired`, `onNewPasswordRequired`) and the two terminal callbacks | ||
| /// (`onFlowCompleted`, `onFlowError`), and the app continues by calling methods on the | ||
| /// `MSALNativeAuthState` it is handed. | ||
| final class MSALNativeAuthResetPasswordV2EndToEndTests: MSALNativeAuthEndToEndBaseTestCase { |
There was a problem hiding this comment.
We should have a test where the code sent is invalid and we get back the correct error and state and only after we submit again correctly. It can be standalone test or a branch on an existing one
| let flowErrorExp = expectation(description: "reset password flow error") | ||
| delegate.reset(expectation: flowErrorExp) | ||
|
|
||
| newPasswordRequiredState.submitNewPassword("INVALID_PASSWORD", delegate: delegate) |
There was a problem hiding this comment.
INVALID_PASSWORD only fails the Entra default policy because it hits 2 of the 4 character classes - it is 16 chars, so it passes on length. If the tenant policy is ever relaxed this test silently exercises the success path and then fails on onFlowErrorCalled with a misleading message. The V1 suite uses \"1\" for the same case; please use a value that can't be complex enough.
| onNewPasswordRequiredCalled = false | ||
| onFlowCompletedCalled = false | ||
| onFlowErrorCalled = false | ||
| error = nil |
There was a problem hiding this comment.
reset clears the called flags and error but leaves codeRequiredState, newPasswordRequiredState and result from the previous step. Unlike V1, this spy is reused across every step of the flow, so a future test that reads one of those after a step that didn't set it will get stale data instead of nil. Please clear them here too.
| await fulfillment(of: [flowCompletedExp]) | ||
| XCTAssertTrue(delegate.onFlowCompletedCalled) | ||
| XCTAssertEqual(delegate.scenario, .passwordReset) | ||
| XCTAssertNotNil(delegate.result) |
There was a problem hiding this comment.
XCTAssertNotNil on the result is weak for the one V2 behaviour that differs from V1 - SSPR now ends with tokens. Please also assert delegate.result?.account.username matches username so the test would catch tokens issued for the wrong account.
Summary
Adds
MSALNativeAuthResetPasswordV2EndToEndTests— a new end-to-end suite covering the server-driven V2 self-service password reset flow (resetPasswordV2) via the unified delegate.Branch is a direct descendant of
sedemche/native-auth-v2_release, so the diff is exactly one new test file + its project wiring (no conflicts). It compiles against the V2 API already present in the base.Test coverage
resetPasswordV2→onCodeRequired→submitCode→onNewPasswordRequired→submitNewPassword→onFlowCompleted(assertsscenario == .passwordReset).submitNewPasswordwith a non-compliant password →onFlowErrorwitherror.isInvalidPassword.onCodeRequired→resendCode→ secondonCodeRequired; retrieves two codes.onFlowErrorwitherror.isUserNotFound.OTP retrieval reuses the existing mail.tm code retriever already in the base branch.
Notes
XCTSkip-gated until a V2 test tenant is enabled (keeps CI green; runnable on demand), consistent with the V1 SSPR suite.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com