vikunja/frontend/cypress/e2e/user/email-confirmation.spec.ts

150 lines
5.0 KiB
TypeScript

import {UserFactory} from '../../factories/user'
import {TokenFactory} from '../../factories/token'
context('Email Confirmation', () => {
let user
let confirmationToken
beforeEach(() => {
UserFactory.truncate()
TokenFactory.truncate()
// Create a user with status = 1 (StatusEmailConfirmationRequired)
user = UserFactory.create(1, {
username: 'unconfirmeduser',
email: 'unconfirmed@example.com',
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.', // 1234
status: 1, // StatusEmailConfirmationRequired
})[0]
// Create an email confirmation token for this user
// kind: 2 = TokenEmailConfirm
confirmationToken = 'test-email-confirm-token-12345678901234567890123456789012'
TokenFactory.create(1, {
user_id: user.id,
kind: 2,
token: confirmationToken,
})
})
it('Should fail login before email is confirmed', () => {
cy.visit('/login')
cy.get('input[id=username]').type(user.username)
cy.get('input[id=password]').type('1234')
cy.get('.button').contains('Login').click()
cy.get('div.message.danger').contains('Email address of the user not confirmed')
})
it('Should confirm email and allow login', () => {
// Intercept the confirmation API call
cy.intercept('POST', '**/user/confirm').as('confirmEmail')
// Manually set the token in localStorage before visiting the page
// This simulates what happens when the user clicks the email link
cy.visit('/login', {
onBeforeLoad(win) {
win.localStorage.setItem('emailConfirmToken', confirmationToken)
},
})
// Wait for the confirmation API call to complete
cy.wait('@confirmEmail', {timeout: 10000}).its('response.statusCode').should('eq', 200)
// Should show success message
cy.get('.message.success', {timeout: 10000}).should('be.visible')
cy.get('.message.success').contains('You successfully confirmed your email')
// Now login should work
cy.get('input[id=username]').type(user.username)
cy.get('input[id=password]').type('1234')
cy.get('.button').contains('Login').click()
// Should successfully log in
cy.url().should('include', '/')
cy.url().should('not.include', '/login')
// Check that the username appears in the greeting
cy.contains(user.username)
})
it('Should fail with invalid confirmation token', () => {
// Intercept the confirmation API call
cy.intercept('POST', '**/user/confirm').as('confirmEmail')
// Try to confirm with an invalid token
const invalidToken = 'invalid-token-that-does-not-exist-in-database'
cy.visit('/login', {
onBeforeLoad(win) {
win.localStorage.setItem('emailConfirmToken', invalidToken)
},
})
// Wait for the confirmation API call to fail
cy.wait('@confirmEmail', {timeout: 10000})
// Should show error message
cy.get('.message.danger', {timeout: 10000}).should('be.visible')
// Login should still fail
cy.get('input[id=username]').type(user.username)
cy.get('input[id=password]').type('1234')
cy.get('.button').contains('Login').click()
cy.get('div.message.danger').contains('Email address of the user not confirmed')
})
it('Should not allow using the same token twice', () => {
// Intercept the confirmation API call
cy.intercept('POST', '**/user/confirm').as('confirmEmail')
// First confirmation - should work
cy.visit('/login', {
onBeforeLoad(win) {
win.localStorage.setItem('emailConfirmToken', confirmationToken)
},
})
cy.wait('@confirmEmail', {timeout: 10000}).its('response.statusCode').should('eq', 200)
cy.get('.message.success', {timeout: 10000}).should('be.visible')
cy.get('.message.success').contains('You successfully confirmed your email')
// Try to use the same token again - should fail
cy.visit('/login', {
onBeforeLoad(win) {
win.localStorage.setItem('emailConfirmToken', confirmationToken)
},
})
cy.wait('@confirmEmail', {timeout: 10000})
cy.get('.message.danger', {timeout: 10000}).should('be.visible')
})
it('Should confirm email when clicking link from email (via query parameter)', () => {
// Intercept the confirmation API call
cy.intercept('POST', '**/user/confirm').as('confirmEmail')
// Simulate clicking the email confirmation link with query parameter
// This is what happens when a user clicks the link in their email
cy.visit(`/?userEmailConfirm=${confirmationToken}`)
// Should redirect to login page
cy.url().should('include', '/login')
// Wait for the confirmation API call to complete
cy.wait('@confirmEmail', {timeout: 10000}).its('response.statusCode').should('eq', 200)
// Should show success message
cy.get('.message.success', {timeout: 10000}).should('be.visible')
cy.get('.message.success').contains('You successfully confirmed your email')
// Now login should work
cy.get('input[id=username]').type(user.username)
cy.get('input[id=password]').type('1234')
cy.get('.button').contains('Login').click()
// Should successfully log in
cy.url().should('include', '/')
cy.url().should('not.include', '/login')
// Check that the username appears in the greeting
cy.contains(user.username)
})
})