Skip to content

Commit

Permalink
feat(RV-386): Add login screen
Browse files Browse the repository at this point in the history
  • Loading branch information
knguyenrise8 committed Jan 10, 2025
1 parent 5c80f8c commit 069020d
Show file tree
Hide file tree
Showing 16 changed files with 754 additions and 27 deletions.
4 changes: 2 additions & 2 deletions OCR/ocr/services/phdc_converter/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ def _build_patient(self, patient: Patient) -> ET.Element:
)
patient_data.append(v)
else:
logging.warning(f"Race code {patient.race_code} not found in " "the OMB classification.")
logging.warning(f"Race code {patient.race_code} not found in the OMB classification.")

if patient.ethnic_group_code is not None:
if patient.ethnic_group_code in ethnicity_code_and_mapping:
Expand All @@ -658,7 +658,7 @@ def _build_patient(self, patient: Patient) -> ET.Element:
)
patient_data.append(v)
else:
logging.warning(f"Ethnic group code {patient.ethnic_group_code} not " "found in OMB classification.")
logging.warning(f"Ethnic group code {patient.ethnic_group_code} not found in OMB classification.")

return patient_data

Expand Down
13 changes: 13 additions & 0 deletions frontend/e2e/App.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ import { test, expect } from "@playwright/test";
test("has STLT Name", async ({ page }) => {
await page.goto("/");

await page.evaluate(() => {
localStorage.setItem('auth_token', 'token');
});
await page.goto("/");

await expect(page.getByText("Demo STLT")).toBeVisible();
});

test("has new template button", async ({ page, baseURL }) => {
await page.goto("/");
await page.evaluate(() => {
localStorage.setItem('auth_token', 'token');
});
await page.goto("/");

await expect(
page.getByRole("button", { name: "+ New Template" }),
).toBeVisible();
Expand All @@ -18,6 +28,9 @@ test("has new template button", async ({ page, baseURL }) => {
test.describe("when templates exist", async () => {
test.beforeEach(async ({ page }) => {
await page.goto("/");
await page.evaluate(() => {
localStorage.setItem('auth_token', 'token');
});
await page.evaluate(() => {
const templates = [
{
Expand Down
5 changes: 5 additions & 0 deletions frontend/e2e/ReviewTemplate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import { test, expect } from "@playwright/test";

test.describe("ReviewTemplate Page", () => {
test.beforeEach(async ({ page }) => {

// Navigate to the ReviewTemplate page
await page.goto("/extract/review");
await page.evaluate(() => {
localStorage.setItem('auth_token', 'token');
});
await page.goto("/extract/review");
});

// Test the Back button functionality
Expand Down
70 changes: 70 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"prettier": "npx prettier . --write"
},
"dependencies": {
"@hookform/resolvers": "^3.10.0",
"@tanstack/react-query": "^5.59.20",
"@trussworks/react-uswds": "^9.0.0",
"@types/hex-rgb": "^3.0.0",
Expand All @@ -29,8 +30,10 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^5.0.0",
"react-hook-form": "^7.54.2",
"react-image-label": "^1.3.4",
"react-router-dom": "^6.26.0",
"yup": "^1.6.1",
"zustand": "^5.0.1"
},
"devDependencies": {
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/FileInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ export const FileInputForwardRef: React.ForwardRefRenderFunction<
}
}
setFiles(fileArr);
console.log('change')
if (onChange) onChange(e);
};

Expand Down
108 changes: 108 additions & 0 deletions frontend/src/components/LoginForm.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { describe, it, expect, vi } from 'vitest'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'

import LoginForm from './LoginForm'
import RootLayout from './RootLayout'
import { MemoryRouter } from 'react-router-dom'

describe('LoginForm', () => {
it('renders the form fields and a submit button', () => {
render(
<MemoryRouter>
<RootLayout>
<LoginForm />
</RootLayout>
</MemoryRouter>
)

expect(screen.getByRole('heading', { name: /log into my account/i })).toBeInTheDocument()

expect(screen.getByLabelText(/email address/i)).toBeInTheDocument()

expect(screen.getByLabelText(/password/i)).toBeInTheDocument()

expect(screen.getByRole('button', { name: /login to your account/i })).toBeInTheDocument()
})

it('shows validation errors when fields are empty and user submits', async () => {
render(
<MemoryRouter>
<RootLayout>
<LoginForm />
</RootLayout>
</MemoryRouter>
)

// Get the button
const loginButton = screen.getByRole('button', { name: /login to your account/i })

// Click it without typing anything
await fireEvent.click(loginButton)

// Wait for validation errors to appear
expect(await screen.findByText(/email is required/i)).toBeInTheDocument()
expect(await screen.findByText(/Password must be at least 8 characters/i)).toBeInTheDocument()
})

it('shows email format error if email is invalid', async () => {
render(
<MemoryRouter>
<RootLayout>
<LoginForm />
</RootLayout>
</MemoryRouter>
)
// Type an invalid email
await fireEvent.change(screen.getByLabelText(/email address/i), 'not-an-email')
// Type a password so that password doesn’t fail the “required” check
await fireEvent.change(screen.getByLabelText(/password/i), 'ValidPass123')

// Submit
const loginButton = screen.getByRole('button', { name: /login to your account/i })
await fireEvent.click(loginButton)

// Should show the "Please enter a valid email address" error
expect(await screen.findByText(/Email is required/i)).toBeInTheDocument()
})

it('shows password format errors if password does not meet requirements', async () => {
render(
<MemoryRouter>
<RootLayout>
<LoginForm />
</RootLayout>
</MemoryRouter>
)
// For instance, a password that's too short and missing uppercase
fireEvent.change(screen.getByTestId('email'), '[email protected]')
fireEvent.change(screen.getByTestId('password'), 'abcabcabc1')


const loginButton = screen.getByRole('button', { name: /login to your account/i })

await waitFor(() => {
fireEvent.change(screen.getByTestId('email'), '[email protected]')
fireEvent.change(screen.getByTestId('password'), 'abcabcabc1')
fireEvent.click(loginButton)
})

expect(screen.getByText(/password must be at least 8 characters/i)).toBeInTheDocument()
})

it('submits successfully when valid data is entered', async () => {
render(
<MemoryRouter>
<RootLayout>
<LoginForm />
</RootLayout>
</MemoryRouter>
)
// Provide valid inputs
await fireEvent.change(screen.getByLabelText(/email address/i), '[email protected]')
await fireEvent.change(screen.getByLabelText(/password/i), 'ValidPass123')

// Click the login button
const loginButton = screen.getByRole('button', { name: /login to your account/i })
await fireEvent.click(loginButton)
})
})
Loading

0 comments on commit 069020d

Please sign in to comment.