feat: PersonNameParser enhancements and Person model refactor (#209-#213) #215
@@ -5,10 +5,10 @@ import DocumentMetadataDrawer from './DocumentMetadataDrawer.svelte';
|
|||||||
|
|
||||||
afterEach(cleanup);
|
afterEach(cleanup);
|
||||||
|
|
||||||
const sender = { id: 's1', firstName: 'Karl', lastName: 'Müller' };
|
const sender = { id: 's1', firstName: 'Karl', lastName: 'Müller', displayName: 'Karl Müller' };
|
||||||
const receivers = [
|
const receivers = [
|
||||||
{ id: 'r1', firstName: 'Anna', lastName: 'Schmidt' },
|
{ id: 'r1', firstName: 'Anna', lastName: 'Schmidt', displayName: 'Anna Schmidt' },
|
||||||
{ id: 'r2', firstName: 'Hans', lastName: 'Weber' }
|
{ id: 'r2', firstName: 'Hans', lastName: 'Weber', displayName: 'Hans Weber' }
|
||||||
];
|
];
|
||||||
const tags = [
|
const tags = [
|
||||||
{ id: 't1', name: 'Familienbrief' },
|
{ id: 't1', name: 'Familienbrief' },
|
||||||
|
|||||||
@@ -7,9 +7,21 @@ const waitForDebounce = () => new Promise((r) => setTimeout(r, 350));
|
|||||||
const tick = () => new Promise((r) => setTimeout(r, 0));
|
const tick = () => new Promise((r) => setTimeout(r, 0));
|
||||||
|
|
||||||
const PERSONS = [
|
const PERSONS = [
|
||||||
{ id: '1', firstName: 'Max', lastName: 'Mustermann' },
|
{
|
||||||
{ id: '2', firstName: 'Anna', lastName: 'Musterfrau' },
|
id: '1',
|
||||||
{ id: '3', firstName: 'Karl', lastName: 'König' }
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{ id: '3', firstName: 'Karl', lastName: 'König', displayName: 'Karl König', personType: 'PERSON' }
|
||||||
];
|
];
|
||||||
|
|
||||||
function mockFetch(persons = PERSONS) {
|
function mockFetch(persons = PERSONS) {
|
||||||
@@ -45,8 +57,20 @@ describe('PersonMultiSelect – rendering', () => {
|
|||||||
it('renders pre-selected persons as chips', async () => {
|
it('renders pre-selected persons as chips', async () => {
|
||||||
render(PersonMultiSelect, {
|
render(PersonMultiSelect, {
|
||||||
selectedPersons: [
|
selectedPersons: [
|
||||||
{ id: '1', firstName: 'Max', lastName: 'Mustermann' },
|
{
|
||||||
{ id: '2', firstName: 'Anna', lastName: 'Musterfrau' }
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
@@ -57,8 +81,20 @@ describe('PersonMultiSelect – rendering', () => {
|
|||||||
it('renders hidden inputs for each selected person', async () => {
|
it('renders hidden inputs for each selected person', async () => {
|
||||||
render(PersonMultiSelect, {
|
render(PersonMultiSelect, {
|
||||||
selectedPersons: [
|
selectedPersons: [
|
||||||
{ id: '1', firstName: 'Max', lastName: 'Mustermann' },
|
{
|
||||||
{ id: '2', firstName: 'Anna', lastName: 'Musterfrau' }
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
await tick();
|
await tick();
|
||||||
@@ -70,7 +106,15 @@ describe('PersonMultiSelect – rendering', () => {
|
|||||||
|
|
||||||
it('hides the placeholder when persons are selected', async () => {
|
it('hides the placeholder when persons are selected', async () => {
|
||||||
render(PersonMultiSelect, {
|
render(PersonMultiSelect, {
|
||||||
selectedPersons: [{ id: '1', firstName: 'Max', lastName: 'Mustermann' }]
|
selectedPersons: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
await expect.element(page.getByPlaceholder('Namen tippen...')).not.toBeInTheDocument();
|
await expect.element(page.getByPlaceholder('Namen tippen...')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -85,7 +129,7 @@ describe('PersonMultiSelect – selecting persons', () => {
|
|||||||
const input = page.getByRole('textbox');
|
const input = page.getByRole('textbox');
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await page.getByText('Mustermann, Max').click();
|
await page.getByText('Max Mustermann').click();
|
||||||
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
await expect.element(input).toHaveValue('');
|
await expect.element(input).toHaveValue('');
|
||||||
await page.screenshot({
|
await page.screenshot({
|
||||||
@@ -100,11 +144,11 @@ describe('PersonMultiSelect – selecting persons', () => {
|
|||||||
|
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await page.getByText('Mustermann, Max').click();
|
await page.getByText('Max Mustermann').click();
|
||||||
|
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await page.getByText('Musterfrau, Anna').click();
|
await page.getByText('Anna Musterfrau').click();
|
||||||
|
|
||||||
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
await expect.element(page.getByText('Anna Musterfrau')).toBeInTheDocument();
|
await expect.element(page.getByText('Anna Musterfrau')).toBeInTheDocument();
|
||||||
@@ -116,22 +160,41 @@ describe('PersonMultiSelect – selecting persons', () => {
|
|||||||
it('filters already-selected persons from search results', async () => {
|
it('filters already-selected persons from search results', async () => {
|
||||||
mockFetch();
|
mockFetch();
|
||||||
render(PersonMultiSelect, {
|
render(PersonMultiSelect, {
|
||||||
selectedPersons: [{ id: '1', firstName: 'Max', lastName: 'Mustermann' }]
|
selectedPersons: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
const input = page.getByRole('textbox');
|
const input = page.getByRole('textbox');
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).not.toBeInTheDocument();
|
// Chip still shows "Max Mustermann" but the dropdown item (role=button) must be filtered out
|
||||||
await expect.element(page.getByText('Musterfrau, Anna')).toBeInTheDocument();
|
await expect
|
||||||
|
.element(page.getByRole('button', { name: 'Max Mustermann' }))
|
||||||
|
.not.toBeInTheDocument();
|
||||||
|
await expect.element(page.getByRole('button', { name: 'Anna Musterfrau' })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('selects a result with Enter key', async () => {
|
it('selects a result with Enter key', async () => {
|
||||||
mockFetch([{ id: '1', firstName: 'Max', lastName: 'Mustermann' }]);
|
mockFetch([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
]);
|
||||||
render(PersonMultiSelect, { selectedPersons: [] });
|
render(PersonMultiSelect, { selectedPersons: [] });
|
||||||
const input = page.getByRole('textbox');
|
const input = page.getByRole('textbox');
|
||||||
await input.fill('Ma');
|
await input.fill('Ma');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await page.getByText('Mustermann, Max').click();
|
await page.getByText('Max Mustermann').click();
|
||||||
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -142,8 +205,20 @@ describe('PersonMultiSelect – removing persons', () => {
|
|||||||
it('removes a chip when its × button is clicked', async () => {
|
it('removes a chip when its × button is clicked', async () => {
|
||||||
render(PersonMultiSelect, {
|
render(PersonMultiSelect, {
|
||||||
selectedPersons: [
|
selectedPersons: [
|
||||||
{ id: '1', firstName: 'Max', lastName: 'Mustermann' },
|
{
|
||||||
{ id: '2', firstName: 'Anna', lastName: 'Musterfrau' }
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
// Buttons have aria-label="Entfernen"
|
// Buttons have aria-label="Entfernen"
|
||||||
@@ -156,8 +231,20 @@ describe('PersonMultiSelect – removing persons', () => {
|
|||||||
it('removes the corresponding hidden input when a chip is removed', async () => {
|
it('removes the corresponding hidden input when a chip is removed', async () => {
|
||||||
render(PersonMultiSelect, {
|
render(PersonMultiSelect, {
|
||||||
selectedPersons: [
|
selectedPersons: [
|
||||||
{ id: '1', firstName: 'Max', lastName: 'Mustermann' },
|
{
|
||||||
{ id: '2', firstName: 'Anna', lastName: 'Musterfrau' }
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
await page.getByRole('button', { name: 'Entfernen' }).first().click();
|
await page.getByRole('button', { name: 'Entfernen' }).first().click();
|
||||||
@@ -177,9 +264,9 @@ describe('PersonMultiSelect – click outside', () => {
|
|||||||
const input = page.getByRole('textbox');
|
const input = page.getByRole('textbox');
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
document.body.click();
|
document.body.click();
|
||||||
await tick();
|
await tick();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).not.toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,8 +7,20 @@ const waitForDebounce = () => new Promise((r) => setTimeout(r, 350));
|
|||||||
const tick = () => new Promise((r) => setTimeout(r, 0));
|
const tick = () => new Promise((r) => setTimeout(r, 0));
|
||||||
|
|
||||||
const PERSONS = [
|
const PERSONS = [
|
||||||
{ id: '1', firstName: 'Max', lastName: 'Mustermann' },
|
{
|
||||||
{ id: '2', firstName: 'Anna', lastName: 'Musterfrau' }
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
function mockFetchWithPersons(persons = PERSONS) {
|
function mockFetchWithPersons(persons = PERSONS) {
|
||||||
@@ -76,8 +88,8 @@ describe('PersonTypeahead – search', () => {
|
|||||||
const input = page.getByPlaceholder('Namen tippen...');
|
const input = page.getByPlaceholder('Namen tippen...');
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
await expect.element(page.getByText('Musterfrau, Anna')).toBeInTheDocument();
|
await expect.element(page.getByText('Anna Musterfrau')).toBeInTheDocument();
|
||||||
await page.screenshot({ path: 'test-results/screenshots/person-typeahead-open.png' });
|
await page.screenshot({ path: 'test-results/screenshots/person-typeahead-open.png' });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -105,7 +117,7 @@ describe('PersonTypeahead – search', () => {
|
|||||||
const input = page.getByPlaceholder('Namen tippen...');
|
const input = page.getByPlaceholder('Namen tippen...');
|
||||||
await input.fill('Ma');
|
await input.fill('Ma');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).not.toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -122,7 +134,7 @@ describe('PersonTypeahead – selection', () => {
|
|||||||
await tick();
|
await tick();
|
||||||
await expect.element(input).toHaveValue('Max Mustermann');
|
await expect.element(input).toHaveValue('Max Mustermann');
|
||||||
await expect
|
await expect
|
||||||
.element(page.getByRole('button', { name: 'Mustermann, Max' }))
|
.element(page.getByRole('button', { name: 'Max Mustermann' }))
|
||||||
.not.toBeInTheDocument();
|
.not.toBeInTheDocument();
|
||||||
await page.screenshot({ path: 'test-results/screenshots/person-typeahead-selected.png' });
|
await page.screenshot({ path: 'test-results/screenshots/person-typeahead-selected.png' });
|
||||||
});
|
});
|
||||||
@@ -152,7 +164,15 @@ describe('PersonTypeahead – selection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('selects a result with Enter key', async () => {
|
it('selects a result with Enter key', async () => {
|
||||||
mockFetchWithPersons([{ id: '1', firstName: 'Max', lastName: 'Mustermann' }]);
|
mockFetchWithPersons([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
]);
|
||||||
render(PersonTypeahead, { name: 'senderId', label: 'Absender' });
|
render(PersonTypeahead, { name: 'senderId', label: 'Absender' });
|
||||||
const input = page.getByPlaceholder('Namen tippen...');
|
const input = page.getByPlaceholder('Namen tippen...');
|
||||||
await input.fill('Ma');
|
await input.fill('Ma');
|
||||||
@@ -218,7 +238,7 @@ describe('PersonTypeahead – correspondent mode', () => {
|
|||||||
(document.querySelector('input[placeholder="Namen tippen..."]') as HTMLInputElement).focus();
|
(document.querySelector('input[placeholder="Namen tippen..."]') as HTMLInputElement).focus();
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
|
|
||||||
await expect.element(page.getByText('Mustermann, Max')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses correspondents endpoint with q param when typing', async () => {
|
it('uses correspondents endpoint with q param when typing', async () => {
|
||||||
@@ -259,9 +279,9 @@ describe('PersonTypeahead – click outside', () => {
|
|||||||
const input = page.getByPlaceholder('Namen tippen...');
|
const input = page.getByPlaceholder('Namen tippen...');
|
||||||
await input.fill('Mu');
|
await input.fill('Mu');
|
||||||
await waitForDebounce();
|
await waitForDebounce();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).toBeInTheDocument();
|
||||||
document.body.click();
|
document.body.click();
|
||||||
await tick();
|
await tick();
|
||||||
await expect.element(page.getByText('Mustermann, Max')).not.toBeInTheDocument();
|
await expect.element(page.getByText('Max Mustermann')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,7 +54,15 @@ describe('korrespondenz load — senderId set, no receiverId', () => {
|
|||||||
const docs = [{ id: 'd1', title: 'Testbrief' }];
|
const docs = [{ id: 'd1', title: 'Testbrief' }];
|
||||||
const GET = mockApi([
|
const GET = mockApi([
|
||||||
{ ok: true, data: docs },
|
{ ok: true, data: docs },
|
||||||
{ ok: true, data: { firstName: 'Hans', lastName: 'Müller' } }
|
{
|
||||||
|
ok: true,
|
||||||
|
data: {
|
||||||
|
firstName: 'Hans',
|
||||||
|
lastName: 'Müller',
|
||||||
|
displayName: 'Hans Müller',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = await load({
|
const result = await load({
|
||||||
@@ -76,8 +84,24 @@ describe('korrespondenz load — senderId and receiverId set', () => {
|
|||||||
it('calls conversation, sender person, and receiver person endpoints', async () => {
|
it('calls conversation, sender person, and receiver person endpoints', async () => {
|
||||||
const GET = mockApi([
|
const GET = mockApi([
|
||||||
{ ok: true, data: [] },
|
{ ok: true, data: [] },
|
||||||
{ ok: true, data: { firstName: 'Hans', lastName: 'Müller' } },
|
{
|
||||||
{ ok: true, data: { firstName: 'Anna', lastName: 'Schmidt' } }
|
ok: true,
|
||||||
|
data: {
|
||||||
|
firstName: 'Hans',
|
||||||
|
lastName: 'Müller',
|
||||||
|
displayName: 'Hans Müller',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ok: true,
|
||||||
|
data: {
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Schmidt',
|
||||||
|
displayName: 'Anna Schmidt',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = await load({
|
const result = await load({
|
||||||
@@ -98,7 +122,15 @@ describe('korrespondenz load — canWrite', () => {
|
|||||||
it('derives canWrite true from WRITE_ALL permission', async () => {
|
it('derives canWrite true from WRITE_ALL permission', async () => {
|
||||||
mockApi([
|
mockApi([
|
||||||
{ ok: true, data: [] },
|
{ ok: true, data: [] },
|
||||||
{ ok: true, data: { firstName: 'Hans', lastName: 'Müller' } }
|
{
|
||||||
|
ok: true,
|
||||||
|
data: {
|
||||||
|
firstName: 'Hans',
|
||||||
|
lastName: 'Müller',
|
||||||
|
displayName: 'Hans Müller',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = await load({
|
const result = await load({
|
||||||
@@ -113,7 +145,15 @@ describe('korrespondenz load — canWrite', () => {
|
|||||||
it('derives canWrite false when user lacks WRITE_ALL', async () => {
|
it('derives canWrite false when user lacks WRITE_ALL', async () => {
|
||||||
mockApi([
|
mockApi([
|
||||||
{ ok: true, data: [] },
|
{ ok: true, data: [] },
|
||||||
{ ok: true, data: { firstName: 'Hans', lastName: 'Müller' } }
|
{
|
||||||
|
ok: true,
|
||||||
|
data: {
|
||||||
|
firstName: 'Hans',
|
||||||
|
lastName: 'Müller',
|
||||||
|
displayName: 'Hans Müller',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = await load({
|
const result = await load({
|
||||||
@@ -132,7 +172,15 @@ describe('korrespondenz load — backend error', () => {
|
|||||||
it('throws when the conversation endpoint returns non-ok', async () => {
|
it('throws when the conversation endpoint returns non-ok', async () => {
|
||||||
mockApi([
|
mockApi([
|
||||||
{ ok: false, status: 500 },
|
{ ok: false, status: 500 },
|
||||||
{ ok: true, data: { firstName: 'Hans', lastName: 'Müller' } }
|
{
|
||||||
|
ok: true,
|
||||||
|
data: {
|
||||||
|
firstName: 'Hans',
|
||||||
|
lastName: 'Müller',
|
||||||
|
displayName: 'Hans Müller',
|
||||||
|
personType: 'PERSON'
|
||||||
|
}
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ describe('New document page – receiver prefill', () => {
|
|||||||
it('shows a receiver chip when initialReceivers has a person', async () => {
|
it('shows a receiver chip when initialReceivers has a person', async () => {
|
||||||
const data = {
|
const data = {
|
||||||
...baseData,
|
...baseData,
|
||||||
initialReceivers: [{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt' }]
|
initialReceivers: [
|
||||||
|
{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt', displayName: 'Anna Schmidt' }
|
||||||
|
]
|
||||||
};
|
};
|
||||||
render(Page, { data, form: null });
|
render(Page, { data, form: null });
|
||||||
await expect.element(page.getByText('Anna Schmidt')).toBeInTheDocument();
|
await expect.element(page.getByText('Anna Schmidt')).toBeInTheDocument();
|
||||||
@@ -67,7 +69,9 @@ describe('New document page – receiver prefill', () => {
|
|||||||
it('renders a hidden receiverIds input for the prefilled receiver', async () => {
|
it('renders a hidden receiverIds input for the prefilled receiver', async () => {
|
||||||
const data = {
|
const data = {
|
||||||
...baseData,
|
...baseData,
|
||||||
initialReceivers: [{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt' }]
|
initialReceivers: [
|
||||||
|
{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt', displayName: 'Anna Schmidt' }
|
||||||
|
]
|
||||||
};
|
};
|
||||||
render(Page, { data, form: null });
|
render(Page, { data, form: null });
|
||||||
const hidden = document.querySelector<HTMLInputElement>('input[name="receiverIds"]');
|
const hidden = document.querySelector<HTMLInputElement>('input[name="receiverIds"]');
|
||||||
|
|||||||
@@ -39,8 +39,22 @@ const makeDoc = (overrides = {}) => ({
|
|||||||
status: 'UPLOADED' as const,
|
status: 'UPLOADED' as const,
|
||||||
documentDate: '2024-03-15',
|
documentDate: '2024-03-15',
|
||||||
location: 'Berlin',
|
location: 'Berlin',
|
||||||
sender: { id: 'p1', firstName: 'Max', lastName: 'Mustermann' },
|
sender: {
|
||||||
receivers: [{ id: 'p2', firstName: 'Anna', lastName: 'Musterfrau' }],
|
id: 'p1',
|
||||||
|
firstName: 'Max',
|
||||||
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
|
personType: 'PERSON' as const
|
||||||
|
},
|
||||||
|
receivers: [
|
||||||
|
{
|
||||||
|
id: 'p2',
|
||||||
|
firstName: 'Anna',
|
||||||
|
lastName: 'Musterfrau',
|
||||||
|
displayName: 'Anna Musterfrau',
|
||||||
|
personType: 'PERSON' as const
|
||||||
|
}
|
||||||
|
],
|
||||||
tags: [{ id: 't1', name: 'Familie' }],
|
tags: [{ id: 't1', name: 'Familie' }],
|
||||||
filePath: '/files/testbrief.pdf',
|
filePath: '/files/testbrief.pdf',
|
||||||
createdAt: '2024-03-15T10:00:00Z',
|
createdAt: '2024-03-15T10:00:00Z',
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const makePerson = (overrides = {}) => ({
|
|||||||
id: '1',
|
id: '1',
|
||||||
firstName: 'Max',
|
firstName: 'Max',
|
||||||
lastName: 'Mustermann',
|
lastName: 'Mustermann',
|
||||||
|
displayName: 'Max Mustermann',
|
||||||
documentCount: 0,
|
documentCount: 0,
|
||||||
...overrides
|
...overrides
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user