describe('Authentication Flow', () => { beforeEach(() => { // Clear localStorage before each test cy.clearLocalStorage() }) it('displays login page', () => { cy.visit('/login') cy.contains('h2', 'Sign In').should('be.visible') cy.get('input[type="email"]').should('be.visible') cy.get('input[type="password"]').should('be.visible') }) it('displays registration page', () => { cy.visit('/register') cy.contains('h2', 'Create Account').should('be.visible') cy.get('input[type="text"]').should('be.visible') cy.get('input[type="email"]').should('be.visible') cy.get('input[type="password"]').should('be.visible') }) it('redirects to login when accessing protected route while unauthenticated', () => { cy.visit('/dashboard') cy.url().should('include', '/login') }) it('can register with email and password', () => { cy.intercept('POST', '**/register-email-password', { statusCode: 201, body: { userId: 1, message: 'User registered successfully' } }).as('register') cy.intercept('POST', '**/login-email-password', { statusCode: 200, body: { token: 'mock-jwt-token' } }).as('login') cy.intercept('GET', '**/profile', { statusCode: 200, body: { id: 1, name: 'Test User', email: 'test@example.com', roles: ['CLIENT'], createdAt: new Date().toISOString() } }).as('profile') cy.visit('/register') cy.get('input[type="text"]').type('Test User') cy.get('input[type="email"]').type('test@example.com') cy.get('input[type="password"]').first().type('SecurePass123!') cy.get('input[type="password"]').last().type('SecurePass123!') cy.get('button[type="submit"]').click() cy.wait('@register') cy.url().should('include', '/dashboard') }) it('can login with email and password', () => { cy.intercept('POST', '**/login-email-password', { statusCode: 200, body: { token: 'mock-jwt-token' } }).as('login') cy.intercept('GET', '**/profile', { statusCode: 200, body: { id: 1, name: 'Test User', email: 'test@example.com', roles: ['CLIENT'], createdAt: new Date().toISOString() } }).as('profile') cy.visit('/login') cy.get('input[type="email"]').type('test@example.com') cy.get('input[type="password"]').type('password123') cy.get('button[type="submit"]').click() cy.wait('@login') cy.wait('@profile') cy.url().should('include', '/dashboard') }) it('shows error on invalid login credentials', () => { cy.intercept('POST', '**/login-email-password', { statusCode: 401, body: { error: 'Invalid credentials' } }).as('loginFailed') cy.visit('/login') cy.get('input[type="email"]').type('wrong@example.com') cy.get('input[type="password"]').type('wrongpassword') cy.get('button[type="submit"]').click() cy.wait('@loginFailed') cy.contains('Login failed').should('be.visible') }) it('can logout successfully', () => { // Set token in localStorage cy.window().then((win) => { win.localStorage.setItem('auth_token', 'mock-jwt-token') }) cy.intercept('GET', '**/profile', { statusCode: 200, body: { id: 1, name: 'Test User', email: 'test@example.com', roles: ['CLIENT'], createdAt: new Date().toISOString() } }).as('profile') cy.visit('/dashboard') cy.wait('@profile') cy.contains('button', 'Logout').click() cy.url().should('eq', Cypress.config().baseUrl + '/') cy.window().then((win) => { expect(win.localStorage.getItem('auth_token')).to.be.null }) }) })