- Replace per-model admin forms with the shared generic AdminTable/AdminModal CRUD - Add ProclamationGroup model and admin + API v2 routes (replaces subscription levels) - Drop subscription levels and flatten proclamation categories - Update v2 serializers and seed data accordingly
175 lines
4.8 KiB
TypeScript
175 lines
4.8 KiB
TypeScript
import { page } from 'vitest/browser';
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
import { render } from 'vitest-browser-svelte';
|
|
import type { PageProps } from './$types';
|
|
|
|
vi.mock('$app/forms', () => ({
|
|
enhance: () => () => {}
|
|
}));
|
|
|
|
import Page from './+page.svelte';
|
|
|
|
const relationOptionsData = {
|
|
solfeggioFrequencyId: [
|
|
{ label: 'UT - 396', value: 1 },
|
|
{ label: 'RE - 417', value: 2 }
|
|
]
|
|
};
|
|
|
|
const categories = [
|
|
{ id: 1, name: 'Healing' },
|
|
{ id: 2, name: 'Manifestation' }
|
|
];
|
|
|
|
const groups = [
|
|
{ id: 1, name: 'General' },
|
|
{ id: 2, name: 'Specific' }
|
|
];
|
|
|
|
const superAdmin = {
|
|
id: 'admin-1',
|
|
name: 'Super Admin',
|
|
roleId: 1,
|
|
roleName: 'SUPER'
|
|
};
|
|
|
|
function makeData(overrides: Partial<PageProps['data']> = {}): PageProps['data'] {
|
|
return {
|
|
records: [],
|
|
relationOptionsData,
|
|
categories,
|
|
groups,
|
|
adminUser: superAdmin,
|
|
userRoleId: superAdmin.roleId,
|
|
...overrides
|
|
};
|
|
}
|
|
|
|
function mountPage(dataOverrides: Partial<PageProps['data']> = {}) {
|
|
return render(Page, { params: {}, data: makeData(dataOverrides), form: null });
|
|
}
|
|
|
|
const editRecord = {
|
|
id: 'proc-1',
|
|
name: 'Test Proclamation',
|
|
content: '<p>Secret</p>',
|
|
solfeggioFrequencyId: 2,
|
|
categoryId: 1,
|
|
groupId: 2,
|
|
category: { name: 'Healing' },
|
|
group: { name: 'Specific' },
|
|
solfeggioFrequency: { name: 'RE - 417' }
|
|
};
|
|
|
|
async function openCreateModal() {
|
|
await page.getByRole('button', { name: 'New Proclamation +' }).click();
|
|
}
|
|
|
|
async function openEditModal() {
|
|
await page.getByRole('cell', { name: 'Test Proclamation' }).click();
|
|
}
|
|
|
|
describe('proclamations admin page (super user)', () => {
|
|
it('renders all basic fields in create mode', async () => {
|
|
mountPage();
|
|
|
|
await openCreateModal();
|
|
|
|
await expect.element(page.getByRole('textbox', { name: 'Name' })).toBeInTheDocument();
|
|
await expect.element(page.getByRole('combobox', { name: /^Frequency$/ })).toBeInTheDocument();
|
|
await expect.element(page.getByRole('combobox', { name: /^Category$/ })).toBeInTheDocument();
|
|
await expect.element(page.getByRole('combobox', { name: /^Group$/ })).toBeInTheDocument();
|
|
await expect.element(page.getByRole('button', { name: 'Create' })).toBeInTheDocument();
|
|
});
|
|
|
|
it('pre-fills name input when editing an existing record', async () => {
|
|
mountPage({ records: [editRecord] });
|
|
|
|
await openEditModal();
|
|
|
|
await expect
|
|
.element(page.getByRole('textbox', { name: 'Name' }))
|
|
.toHaveValue('Test Proclamation');
|
|
});
|
|
|
|
it('pre-fills select values when editing an existing record', async () => {
|
|
mountPage({ records: [editRecord] });
|
|
|
|
await openEditModal();
|
|
|
|
const freqEl = (await page
|
|
.getByRole('combobox', { name: /^Frequency$/ })
|
|
.element()) as HTMLSelectElement;
|
|
const categoryEl = (await page
|
|
.getByRole('combobox', { name: /^Category$/ })
|
|
.element()) as HTMLSelectElement;
|
|
const groupEl = (await page
|
|
.getByRole('combobox', { name: /^Group$/ })
|
|
.element()) as HTMLSelectElement;
|
|
|
|
expect(freqEl.value).toBe('2');
|
|
expect(categoryEl.value).toBe('1');
|
|
expect(groupEl.value).toBe('2');
|
|
});
|
|
|
|
it('keeps group selection independent of category selection (movable filter)', async () => {
|
|
mountPage({ records: [editRecord] });
|
|
|
|
await openEditModal();
|
|
|
|
const categoryEl = (await page
|
|
.getByRole('combobox', { name: /^Category$/ })
|
|
.element()) as HTMLSelectElement;
|
|
const groupEl = (await page
|
|
.getByRole('combobox', { name: /^Group$/ })
|
|
.element()) as HTMLSelectElement;
|
|
|
|
categoryEl.value = '2';
|
|
categoryEl.dispatchEvent(new Event('change', { bubbles: true }));
|
|
|
|
expect(categoryEl.value).toBe('2');
|
|
expect(groupEl.value).toBe('2');
|
|
});
|
|
|
|
it('shows content editor when isSuper is true', async () => {
|
|
mountPage({ records: [editRecord] });
|
|
|
|
await openEditModal();
|
|
|
|
await expect.element(page.getByText('Content')).toBeInTheDocument();
|
|
await expect.element(page.getByTestId('tiptap-editor')).toBeInTheDocument();
|
|
});
|
|
|
|
it('disables submit button when editing and not dirty', async () => {
|
|
mountPage({ records: [editRecord] });
|
|
|
|
await openEditModal();
|
|
|
|
await expect.element(page.getByRole('button', { name: 'Update' })).toBeDisabled();
|
|
});
|
|
|
|
it('enables submit button when editing and user modifies a field', async () => {
|
|
mountPage({ records: [editRecord] });
|
|
|
|
await openEditModal();
|
|
|
|
await page.getByRole('textbox', { name: 'Name' }).fill('New Name');
|
|
|
|
await expect.element(page.getByRole('button', { name: 'Update' })).toBeEnabled();
|
|
});
|
|
});
|
|
|
|
describe('proclamations admin page (non-super user)', () => {
|
|
it('hides create/edit entry points and content field from non-super users', async () => {
|
|
mountPage({
|
|
records: [editRecord],
|
|
adminUser: { ...superAdmin, id: 'admin-2', roleId: 2, roleName: 'ADMIN' }
|
|
});
|
|
|
|
await expect
|
|
.element(page.getByRole('button', { name: 'New Proclamation +' }))
|
|
.not.toBeInTheDocument();
|
|
await expect.element(page.getByText('Content')).not.toBeInTheDocument();
|
|
});
|
|
});
|