chore: save current Ruby implementation state before Next.js rewrite

This commit is contained in:
2026-03-27 14:36:22 -07:00
parent e9365faa10
commit 96f7cb86d3
20 changed files with 894 additions and 106 deletions
+303
View File
@@ -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