mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-27 22:30:56 +00:00
103 lines
3.5 KiB
TypeScript
103 lines
3.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import {
|
|
Applicant,
|
|
newApplicant,
|
|
signUp,
|
|
verifyOtpIfPrompted,
|
|
} from './support/applicant';
|
|
import { deleteApplicant, sql } from './support/db';
|
|
|
|
/**
|
|
* Signing up, and being asked what you operate as before anything else.
|
|
*
|
|
* The gate is the whole point: the catalogue is filtered by the answer and the
|
|
* API refuses an application for a mode the profile does not hold, so an
|
|
* applicant who skipped this would reach a dashboard that offers them nothing
|
|
* and explains nothing.
|
|
*/
|
|
test.describe('signup and onboarding', () => {
|
|
let applicant: Applicant;
|
|
|
|
test.beforeEach(() => {
|
|
applicant = newApplicant('onboard');
|
|
});
|
|
|
|
test.afterEach(() => {
|
|
deleteApplicant(applicant.email);
|
|
});
|
|
|
|
test('a new applicant is asked for their operations before reaching the dashboard', async ({
|
|
page,
|
|
}) => {
|
|
const offset = await signUp(page, applicant);
|
|
await verifyOtpIfPrompted(page, offset);
|
|
|
|
// The account exists in IAM ...
|
|
const rows = sql(
|
|
`SELECT email FROM iam.users WHERE email = '${applicant.email}'`,
|
|
);
|
|
expect(rows).toHaveLength(1);
|
|
|
|
// ... and the first thing behind the session is the question, not the app.
|
|
await expect(page).toHaveURL(/\/onboarding\/operations/, { timeout: 30_000 });
|
|
await expect(
|
|
page.getByRole('heading', { name: /what do you operate as/i }),
|
|
).toBeVisible();
|
|
|
|
// The dashboard stays out of reach until it is answered.
|
|
await page.goto('/dashboard');
|
|
await expect(page).toHaveURL(/\/onboarding\/operations/);
|
|
|
|
// Answer it.
|
|
await page
|
|
.getByRole('checkbox', { name: /freight forwarder license/i })
|
|
.first()
|
|
.check();
|
|
await page.getByRole('button', { name: /save operations/i }).click();
|
|
|
|
await expect(page).toHaveURL(/\/dashboard/, { timeout: 30_000 });
|
|
|
|
// And it stuck: stored against the profile, keyed by the IAM user id.
|
|
const declared = sql(`
|
|
SELECT lt.key
|
|
FROM profile_operator_types pot
|
|
JOIN profiles p ON p.id = pot.profile_id
|
|
JOIN iam.users u ON u.id = p.user_id
|
|
JOIN license_types lt ON lt.id = pot.license_type_id
|
|
WHERE u.email = '${applicant.email}' AND pot.deleted_at IS NULL
|
|
`);
|
|
expect(declared.map((r) => r[0])).toEqual(['FREIGHT_FORWARDER']);
|
|
});
|
|
|
|
test('the dashboard leads with a get-started panel when there is nothing to show', async ({
|
|
page,
|
|
}) => {
|
|
const offset = await signUp(page, applicant);
|
|
await verifyOtpIfPrompted(page, offset);
|
|
await expect(page).toHaveURL(/\/onboarding\/operations/, { timeout: 30_000 });
|
|
|
|
await page
|
|
.getByRole('checkbox', { name: /freight forwarder license/i })
|
|
.first()
|
|
.check();
|
|
await page.getByRole('button', { name: /save operations/i }).click();
|
|
await expect(page).toHaveURL(/\/dashboard/, { timeout: 30_000 });
|
|
|
|
// Nothing filed and nothing held: one panel, not two empty sections.
|
|
await expect(page.getByRole('heading', { name: 'Get started' })).toBeVisible();
|
|
await expect(
|
|
page.getByRole('heading', { name: 'My applications' }),
|
|
).toHaveCount(0);
|
|
await expect(page.getByRole('heading', { name: 'My licences' })).toHaveCount(
|
|
0,
|
|
);
|
|
|
|
// The catalogue is directly beneath it, filtered to what they declared.
|
|
await expect(
|
|
page.getByRole('heading', { name: /apply for a licence/i }),
|
|
).toBeVisible();
|
|
await expect(page.getByText('Freight Forwarder License').first()).toBeVisible();
|
|
await expect(page.getByText('Shipping Agent License')).toHaveCount(0);
|
|
});
|
|
});
|