Skip to content

Add SSPR v2 e2e basic tests - #3052

Open
antrix1989 wants to merge 1 commit into
sedemche/native-auth-v2_releasefrom
sedemche/native-auth-v2-sspr-e2e-v2release
Open

Add SSPR v2 e2e basic tests#3052
antrix1989 wants to merge 1 commit into
sedemche/native-auth-v2_releasefrom
sedemche/native-auth-v2-sspr-e2e-v2release

Conversation

@antrix1989

Copy link
Copy Markdown
Contributor

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

  • Happy pathresetPasswordV2onCodeRequiredsubmitCodeonNewPasswordRequiredsubmitNewPasswordonFlowCompleted (asserts scenario == .passwordReset).
  • Invalid passwordsubmitNewPassword with a non-compliant password → onFlowError with error.isInvalidPassword.
  • Resend codeonCodeRequiredresendCode → second onCodeRequired; retrieves two codes.
  • Email not found — unknown username → onFlowError with error.isUserNotFound.

OTP retrieval reuses the existing mail.tm code retriever already in the base branch.

Notes

  • All tests are XCTSkip-gated until a V2 test tenant is enabled (keeps CI green; runnable on demand), consistent with the V1 SSPR suite.
  • Wired into both MSAL iOS Native Auth E2E Tests and MSAL Mac Native Auth E2E Tests targets.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

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
@antrix1989
antrix1989 requested review from a team as code owners July 21, 2026 22:28
@antrix1989
antrix1989 requested review from hieunguyenmsft and mipetriu and removed request for a team July 21, 2026 22:28
Comment thread MSAL/MSAL.xcodeproj/project.pbxproj
/// (`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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants