Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android E2E Sign Up, Fixes AB#3073857 #2213

Open
wants to merge 27 commits into
base: dev
Choose a base branch
from
Open

Android E2E Sign Up, Fixes AB#3073857 #2213

wants to merge 27 commits into from

Conversation

Yuki-YuXin
Copy link
Contributor

@Yuki-YuXin Yuki-YuXin commented Oct 31, 2024

Create a draft version instead of an official one: #2212 because the PR is still in the draft version.

AB#3073857

Android Test plan: https://identitydivision.visualstudio.com/Engineering/_testPlans/define?planId=3054662&suiteId=3054727
2.1.5
2.1.6
2.1.7 (out of scopes for the Lab environment, include them once the environment is ready)
2.1.8
2.1.9
2.1.10
2.1.11

1.1.2
1.1.5
1.1.10
1.1.11
1.1.12
1.1.13
1.1.14

… allow flexibility. Complete sign up email otp case
# Conflicts:
#	msal/src/test/java/com/microsoft/identity/client/e2e/tests/network/nativeauth/SignUpEmailPasswordTest.kt
@github-actions github-actions bot added the msal label Oct 31, 2024
@Yuki-YuXin Yuki-YuXin marked this pull request as ready for review November 20, 2024 11:10
@Yuki-YuXin Yuki-YuXin requested a review from a team as a code owner November 20, 2024 11:10
@Yuki-YuXin
Copy link
Contributor Author

image

import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode

// TODO: move to "PAUSED". A work in RoboTestUtils will be needed though.
Copy link

Choose a reason for hiding this comment

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

Is this TODO needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removing this TODO is not inside the work of this scope thus I would be prudential here of removing it.

@@ -85,8 +85,8 @@ class SignInEmailPasswordTest : NativeAuthPublicClientApplicationAbstractTest()
Assert.assertTrue((result as SignInError).isInvalidCredentials())
}

@Test
@Ignore("Ignore until MFA is available on test slice")
Copy link

Choose a reason for hiding this comment

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

Can we remove this "Ignore" line? It should be available now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removing this tag causes failure in the pipeline. I may need to re-add that.

Copy link

Choose a reason for hiding this comment

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

MFA is available for the lab tenant. What the pipeline error is about?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

"Error: invalid_grant - AADSTS9002313: Invalid request. Request is malformed or invalid. Trace ID: 567dd14e-a142-4138-83d4-056260310100 Correlation ID: 48bd9ed2-491d-46cd-ba3a-83f32d6e23f2 Timestamp: 2024-11-20 16:50:25Z"

Choose a reason for hiding this comment

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

Can you try to run the test locally and fix it? From the code it seems the response is being mocked, so this test will probably need to be updated to work with the real API in the same line as the tests you've added in the PR.

For reference, this is the test file on iOS: https://github.com/AzureAD/microsoft-authentication-library-for-objc/blob/dev/MSAL/test/integration/native_auth/end_to_end/mfa/MSALNativeAuthSignInWithMFAEndToEndTests.swift

Copy link
Contributor Author

@Yuki-YuXin Yuki-YuXin Nov 26, 2024

Choose a reason for hiding this comment

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

Hi @nilo-ms @diegojerezba . Under SignInMFATest, there is a test case called fun test get other auth methods, request challenge on specific auth method and complete MFA flow(). It overlaps with this one under SignInEmailPasswordTest, so I'll remove this test case

Choose a reason for hiding this comment

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

OK, but the tests in SignInMFATest are all disabled. Can you enable them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

val signUpResult = application.signUp(user)
assertResult<SignUpResult.CodeRequired>(signUpResult)
val codeRequiredState = (signUpResult as SignUpResult.CodeRequired).nextState
val resendCodeResult = codeRequiredState.resendCode()
Copy link

@nilo-ms nilo-ms Nov 20, 2024

Choose a reason for hiding this comment

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

To test that the resend code works properly we should:

  • signUp
  • retrieve code from mailbox (otp1)
  • resend code
  • retrieve code from mailbox (otp2)
  • check that otp1 and otp2 are different

Same comment applies also for use case 1.1.2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://identitydivision.visualstudio.com/Engineering/_workitems/edit/2702377 According to the steps defined in the test case, SignInResendCodeResult.Success would be better than otp1 and otp2 difference.

Copy link

Choose a reason for hiding this comment

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

based on the test case you linked:
Screenshot 2024-11-20 at 16 57 55
You need to check that a new code is received in the mailbox. Reviewing your code, it seems that this step is missing. Do you agree?
You decide the best way to check if a new code has been received.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SDK.resendCode() action then SDK return SignInResendCodeResult.Success Result. Receive a new code in the email box is the UI appearance. E2E test is focused on the SDK test without any UI requirement.

Copy link

Choose a reason for hiding this comment

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

I think Yuki we're not understanding each other. Let's have a call and I can explain you what I mean

Copy link

Choose a reason for hiding this comment

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

Me and Yuki had a chat, but we couldn't reach an agreement. Explaining here my reasoning why this test is missing a crucial piece:

  • E2E tests are meant to validate the real product in a production environment. No component should be mocked. These tests should check that the entire product works as intended. In this case we want to test that the SDK resendCode feature works properly. This means, that when the sdk.resendCode() method is called, we need to check that the SDK returns a successful result and that a new email containing the OTP code is received in the email box.
  • Additionally, we're automating the manual test (https://identitydivision.visualstudio.com/Engineering/_workitems/edit/2702377). scenario 1.1.2 from acceptance criteria. One step of the test requires verifying that a new code is sent to the email box. When automating this test, we should include all steps.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point. Done.

Choose a reason for hiding this comment

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

I agree with @nilo-ms. Checking if the code has arrived in the mailbox should be included in our logic.

The E2E test simulates what a real user would do. A user would first check if the code has arrived before doing the next step.

Also, as we’ve seen before, the main reason our tests are unreliable is that emails don’t always arrive on time. If we check for the email before moving to the next step, it will make it easier to understand why the test is failing (we can log this information to the console).

Choose a reason for hiding this comment

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

@Yuki-YuXin I see that you've implemented this in the test case 2.1.5, but not in the 1.1.2. Can you please implement it there as well? I will resolve this conversation afterwards.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My mistake. Update the 1.1.2 as well.

// Turn an existing username to a non-existing username
val alteredUsername = username.replace("@", "1234@")
val result = application.signIn(alteredUsername, password.toCharArray())
Assert.assertTrue(result is SignInError)

Choose a reason for hiding this comment

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

Nit: these Assert. are redundant and can be removed, in the same style as the test testErrorIsInvalidCredentials() (there are several in the PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

* (Test case 13)
*/
@Test
fun testErrorUserExistAsPassword() {

Choose a reason for hiding this comment

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

This test doesn't belong here, and it already exists in SignUpEmailPasswordTests (test 1.1.10) so I think you can remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

test 1.1.10 is email+password authentication and this one is using email+otp authentication.

There is a test case in the Android board there we need to run it manually.
image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://microsofteur-my.sharepoint.com/:w:/g/personal/sodenhoven_microsoft_com/ERrvxU_ZybBIvnq1UfVKWagBG-u_xFS7pcvRbVXCzFHnsQ?e=5EAUlc It was not included in the numbering of the Native Auth Acceptance criteria, so it was added to the Test plan later

@Ignore("TODO: Add social account in the tenant.")
@Test
fun testErrorUserExistAsSocial() {
config = getConfig(ConfigType.SIGN_IN_PASSWORD)

Choose a reason for hiding this comment

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

Nit: it doesn't really matter, but this test is defined as an OTP test in the test plan.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Use ConfigType.SIGN_IN_OTP instead.

val username = config.email
val password = getSafePassword()
// Turn an existing username to a non-existing username
val alteredUsername = username.replace("@", "1234@")

Choose a reason for hiding this comment

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

Nit: Is it possible to use the INVALID_EMAIL from NativeAuthPublicClientApplicationAbstractTest to keep consistency with other tests? (For example, it is used in SignUpEmailOTPTest.testErrorInvalidEmailFormat())

Same in line 184 with the alteredPassword.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Choose a reason for hiding this comment

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

Nit: Can you put the tests of this file in order? This helps a lot while reading them for first time.

This is what I mean:

Test 1.1.1
Test 1.1.2
Test 1.1.4
...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done on both.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, according to Silviu's suggestions, I may remove all the Test case number for clarity.

Choose a reason for hiding this comment

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

Just in case I am talking about the order here, not Number SO 1.1.3 is ok, 13 is not

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Test plan 13 is a special one that does not exist in our original user case sequence, but was added as a patch to the test plan at a later stage. At the moment I have removed all Test plan numbers and sorted them by user case.


runBlocking { // Running with runBlocking to avoid default 10 second execution timeout.
val user = config.email
val signUpResult = application.signUp(user)

Choose a reason for hiding this comment

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

Password is missing.

Same in tests 1.1.2, 1.1.11 and 1.1.12

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch. Done.

assertResult<SignUpResult.CodeRequired>(signUpResult)
val codeRequiredState = (signUpResult as SignUpResult.CodeRequired).nextState
val resendCodeResult = codeRequiredState.resendCode()
assertResult<SignUpResendCodeResult.Success>(resendCodeResult)

Choose a reason for hiding this comment

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

I know this test is disabled for now, but it should result in userAlreadyExists error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants