Skip to content

Commit

Permalink
test(e2e): login success with code
Browse files Browse the repository at this point in the history
  • Loading branch information
Benehiko committed Aug 21, 2023
1 parent c00316c commit e117fef
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 17 deletions.
175 changes: 175 additions & 0 deletions test/e2e/cypress/integration/profiles/code/login/success.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import { appPrefix, APP_URL, gen } from "../../../../helpers"
import { routes as express } from "../../../../helpers/express"

context("Login success with code method", () => {
;[
{
route: express.login,
app: "express" as "express",
profile: "code",
},
// {
// route: react.registration,
// app: "react" as "react",
// profile: "code",
// },
].forEach(({ route, profile, app }) => {
describe(`for app ${app}`, () => {
before(() => {
cy.deleteMail()
cy.useConfigProfile(profile)
cy.proxy(app)
cy.setPostCodeRegistrationHooks([])
cy.setupHooks("login", "after", "code", [])
})

beforeEach(() => {
const email = gen.email()
cy.wrap(email).as("email")
cy.registerWithCode({ email })

cy.deleteMail()
cy.clearAllCookies()
cy.visit(route)
})

it("should be able to sign in with code", () => {
cy.get("@email").then((email) => {
cy.get('form[data-testid="login-flow-code"] input[name="identifier"]')
.clear()
.type(email.toString())
cy.submitCodeForm()

cy.getLoginCodeFromEmail(email.toString()).then((code) => {
cy.get(
'form[data-testid="login-flow-code"] input[name="code"]',
).type(code)

cy.get("button[name=method][value=code]").click()
})

if (app === "express") {
cy.get('a[href*="sessions"').click()
}
cy.getSession().should((session) => {
const { identity } = session
expect(identity.id).to.not.be.empty
expect(identity.verifiable_addresses).to.have.length(1)
expect(identity.verifiable_addresses[0].status).to.equal(
"completed",
)
expect(identity.traits.email).to.equal(email)
})
})
})

it("should be able to resend login code", () => {
cy.get("@email").then((email) => {
cy.get('form[data-testid="login-flow-code"] input[name="identifier"]')
.clear()
.type(email.toString())
cy.submitCodeForm()

cy.getLoginCodeFromEmail(email.toString()).then((code) => {
cy.wrap(code).as("code1")
})

cy.get("button[name=resend]").click()

cy.getLoginCodeFromEmail(email.toString()).then((code) => {
cy.wrap(code).as("code2")
})

cy.get("@code1").then((code1) => {
cy.get("@code2").then((code2) => {
expect(code1).to.not.equal(code2)
})
})

// attempt to submit code 1
cy.get("@code1").then((code1) => {
cy.get('form[data-testid="login-flow-code"] input[name="code"]')
.clear()
.type(code1.toString())
})

cy.get("button[name=method][value=code]").click()

cy.get("[data-testid='ui/message/4010008']").contains(
"The login code is invalid or has already been used",
)

// attempt to submit code 2
cy.get("@code2").then((code2) => {
cy.get('form[data-testid="login-flow-code"] input[name="code"]')
.clear()
.type(code2.toString())
})

cy.get('button[name="method"][value="code"]').click()

if (app === "express") {
cy.get('a[href*="sessions"').click()
}
cy.getSession().should((session) => {
const { identity } = session
expect(identity.id).to.not.be.empty
expect(identity.verifiable_addresses).to.have.length(1)
expect(identity.verifiable_addresses[0].status).to.equal(
"completed",
)
expect(identity.traits.email).to.equal(email)
})
})
})

it("should be able to login to un-verfied email", () => {
const email = gen.email()
const email2 = gen.email()

// Setup complex schema
cy.setIdentitySchema(
"file://test/e2e/profiles/code/identity.complex.traits.schema.json",
)

cy.registerWithCode({
email: email,
traits: {
"traits.username": Math.random().toString(36),
"traits.email2": email2,
},
})
cy.deleteMail({ atLeast: 2 })

cy.visit(route)

cy.get('form[data-testid="login-flow-code"] input[name="identifier"]')
.clear()
.type(email2)
cy.submitCodeForm()

cy.getLoginCodeFromEmail(email2).then((code) => {
cy.get('form[data-testid="login-flow-code"] input[name="code"]').type(
code,
)
cy.get("button[name=method][value=code]").click()
})

cy.getSession({ expectAal: "aal1", expectMethods: ["code"] }).then(
(session) => {
expect(session.identity.verifiable_addresses).to.have.length(2)
expect(session.identity.verifiable_addresses[0].status).to.equal(
"completed",
)
expect(session.identity.verifiable_addresses[1].status).to.equal(
"completed",
)
},
)
})
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ context("Registration success with code method", () => {
}

cy.getSession().should((session) => {
console.dir({ session })
const { identity } = session
expect(identity.id).to.not.be.empty
expect(identity.verifiable_addresses).to.have.length(2)
Expand Down
42 changes: 27 additions & 15 deletions test/e2e/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ Cypress.Commands.add(

Cypress.Commands.add(
"registerWithCode",
({ email = gen.email(), code = undefined, query = {} } = {}) => {
({ email = gen.email(), code = undefined, traits = {}, query = {} } = {}) => {
console.log("Creating user account: ", { email })

cy.clearAllCookies()
Expand All @@ -409,6 +409,7 @@ Cypress.Commands.add(
body: mergeFields(form, {
method: "code",
"traits.email": email,
...traits,
...(code && { code }),
}),
url: form.action,
Expand All @@ -423,21 +424,32 @@ Cypress.Commands.add(
f.group === "code" && f.attributes.name === "traits.email",
).attributes.value,
).to.eq(email)
return cy.getRegistrationCodeFromEmail(email).then((code) => {
return cy.request({
headers: {
Accept: "application/json",
},
method: form.method,
body: mergeFields(form, {
method: "code",
"traits.email": email,
code,
}),
url: form.action,
followRedirect: false,

const expectedCount =
Object.keys(traits)
.map((k) => (k.includes("email") ? k : null))
.filter(Boolean).length + 1

return cy
.getRegistrationCodeFromEmail(email, {
expectedCount: expectedCount,
})
.then((code) => {
return cy.request({
headers: {
Accept: "application/json",
},
method: form.method,
body: mergeFields(form, {
method: "code",
"traits.email": email,
code,
...traits,
}),
url: form.action,
followRedirect: false,
})
})
})
} else {
expect(body.session).to.contain(email)
}
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/cypress/support/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ declare global {
getSession(opts?: {
expectAal?: "aal2" | "aal1"
expectMethods?: Array<
"password" | "webauthn" | "lookup_secret" | "totp"
"password" | "webauthn" | "lookup_secret" | "totp" | "code"
>
}): Chainable<KratosSession>

Expand Down Expand Up @@ -78,6 +78,7 @@ declare global {
registerWithCode(opts: {
email: string
code?: string
traits?: { [key: string]: any }
query?: { [key: string]: string }
}): Chainable<Response<void>>

Expand Down

0 comments on commit e117fef

Please sign in to comment.