chore: save current Ruby implementation state before Next.js rewrite
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'playwright'
|
||||
|
||||
RSpec.describe 'Authentication', type: :playwright do
|
||||
# Use RSpec's around hook to manage Playwright lifecycle
|
||||
around do |example|
|
||||
Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
|
||||
playwright.chromium.launch(headless: true) do |browser|
|
||||
@browser = browser
|
||||
example.run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
@context = @browser.new_context(viewport: { width: 1280, height: 800 })
|
||||
@page = @context.new_page
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
@context.close
|
||||
end
|
||||
|
||||
describe 'Login Form Display' do
|
||||
it 'displays login page at /login' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
expect(@page.locator('h1').text_content).to include('Login')
|
||||
end
|
||||
|
||||
it 'has email and password input fields' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
email_input = @page.locator('input[type="email"]')
|
||||
password_input = @page.locator('input[type="password"]')
|
||||
|
||||
expect(email_input.count).to be > 0
|
||||
expect(password_input.count).to be > 0
|
||||
end
|
||||
|
||||
it 'has a login form with POST method' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
form = @page.locator('form[method="POST"]')
|
||||
expect(form.count).to be > 0
|
||||
end
|
||||
|
||||
it 'includes CSRF token in login form' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
csrf_input = @page.locator('input[name="_csrf_token"]')
|
||||
expect(csrf_input.count).to be > 0
|
||||
expect(csrf_input.input_value).not_to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Login Flow' do
|
||||
before(:all) do
|
||||
# Admin user credentials for testing
|
||||
@admin_email = 'david@dhg.lol'
|
||||
@admin_password = 'admin'
|
||||
end
|
||||
|
||||
it 'successfully logs in with valid credentials' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Fill in login form
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
|
||||
# Submit form
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Should redirect to rankings page
|
||||
expect(@page.url).to include('/')
|
||||
end
|
||||
|
||||
it 'shows success message after login' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Fill in login form
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
|
||||
# Submit form
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Should redirect to rankings page
|
||||
expect(@page.url).to include('/')
|
||||
end
|
||||
|
||||
it 'redirects to admin dashboard when logged in' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# After login, user is redirected to rankings
|
||||
# Then navigate to admin
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
|
||||
# Should see admin dashboard
|
||||
expect(@page.locator('h1').text_content).to include('Admin Dashboard')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Failed Login Scenarios' do
|
||||
it 'rejects invalid email' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
@page.locator('input[type="email"]').fill('invalid@example.com')
|
||||
@page.locator('input[type="password"]').fill('wrongpassword')
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Should show error message
|
||||
page_content = @page.content
|
||||
expect(page_content).to include('Invalid email or password')
|
||||
end
|
||||
|
||||
it 'rejects invalid password' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
@page.locator('input[type="email"]').fill('david@dhg.lol')
|
||||
@page.locator('input[type="password"]').fill('wrongpassword')
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Should show error message
|
||||
page_content = @page.content
|
||||
expect(page_content).to include('Invalid email or password')
|
||||
end
|
||||
|
||||
it 'requires email field' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
@page.locator('input[type="password"]').fill('somepassword')
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Browser validation should prevent submission
|
||||
# Or server should handle empty email
|
||||
page_content = @page.content
|
||||
# Either an error or the form should remain
|
||||
expect(page_content).to include('Login')
|
||||
end
|
||||
|
||||
it 'requires password field' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
@page.locator('input[type="email"]').fill('david@dhg.lol')
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Browser validation should prevent submission
|
||||
page_content = @page.content
|
||||
expect(page_content).to include('Login')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Session Management' do
|
||||
before(:all) do
|
||||
@admin_email = 'david@dhg.lol'
|
||||
@admin_password = 'admin'
|
||||
end
|
||||
|
||||
it 'creates session after successful login' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Check that session cookie is set
|
||||
cookies = @context.cookies
|
||||
session_cookie = cookies.find { |c| c['name'] == 'rack.session' }
|
||||
|
||||
expect(session_cookie).not_to be_nil
|
||||
expect(session_cookie['value']).not_to be_empty
|
||||
end
|
||||
|
||||
it 'persists session across page reloads' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Verify we're logged in
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
expect(@page.locator('h1').text_content).to include('Admin Dashboard')
|
||||
|
||||
# Reload page
|
||||
@page.reload
|
||||
|
||||
# Should still be logged in
|
||||
expect(@page.locator('h1').text_content).to include('Admin Dashboard')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Logout Functionality' do
|
||||
before(:all) do
|
||||
@admin_email = 'david@dhg.lol'
|
||||
@admin_password = 'admin'
|
||||
end
|
||||
|
||||
it 'logs out user when clicking logout link' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Verify logged in - check for Logout link in navigation
|
||||
# Navigate to admin to confirm login
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
expect(@page.locator('h1').text_content).to include('Admin Dashboard')
|
||||
|
||||
# Click logout - use first match since logout may appear in multiple places
|
||||
@page.locator('a[href="/logout"]').first.click
|
||||
|
||||
# After logout, check we're back at rankings
|
||||
expect(@page.url).to include('/')
|
||||
end
|
||||
|
||||
it 'clears session after logout' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Navigate to admin to verify logged in
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
expect(@page.locator('h1').text_content).to include('Admin Dashboard')
|
||||
|
||||
# Logout
|
||||
@page.locator('a[href="/logout"]').first.click
|
||||
|
||||
# Try to access admin page again - should redirect (not show admin dashboard)
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
|
||||
# Should not see admin dashboard
|
||||
expect(@page.locator('h1').text_content).not_to include('Admin Dashboard')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Authorization Redirects' do
|
||||
before(:all) do
|
||||
@admin_email = 'david@dhg.lol'
|
||||
@admin_password = 'admin'
|
||||
end
|
||||
|
||||
it 'redirects to rankings when accessing admin page without auth' do
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
|
||||
# Unauthenticated users are redirected to rankings page
|
||||
expect(@page.url).to include('/')
|
||||
expect(@page.locator('h1').text_content).to include('Rankings')
|
||||
end
|
||||
|
||||
it 'allows access to admin page after login' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Navigate to admin page
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
|
||||
# Should see admin dashboard
|
||||
expect(@page.locator('h1').text_content).to include('Admin Dashboard')
|
||||
end
|
||||
|
||||
it 'redirects to rankings after logout when accessing admin page' do
|
||||
@page.goto('http://localhost:2300/login')
|
||||
|
||||
# Login
|
||||
@page.locator('input[type="email"]').fill(@admin_email)
|
||||
@page.locator('input[type="password"]').fill(@admin_password)
|
||||
@page.locator('button[type="submit"]').click
|
||||
|
||||
# Go to admin page
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
expect(@page.url).to include('/admin')
|
||||
|
||||
# Click logout link in admin page
|
||||
# Note: logout link is in bottom nav on mobile, main nav on desktop
|
||||
@page.locator('a[href="/logout"]').first.click
|
||||
|
||||
# After logout, try to access admin page again
|
||||
@page.goto('http://localhost:2300/admin')
|
||||
|
||||
# Should redirect to rankings (unauthenticated users see rankings, not login)
|
||||
expect(@page.url).to include('/')
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user