refactor(stammbaum): extract chipLabel/otherName to shared relationshipLabels helper
Addresses @felix blocker: both functions were duplicated verbatim in StammbaumCard.svelte and StammbaumSidePanel.svelte. Now exported from $lib/relationshipLabels.ts with perspectivePersonId as an explicit param. 8 unit tests added (red→green). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
66
frontend/src/lib/relationshipLabels.test.ts
Normal file
66
frontend/src/lib/relationshipLabels.test.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
|
import { chipLabel, otherName } from './relationshipLabels';
|
||||||
|
import type { components } from '$lib/generated/api';
|
||||||
|
|
||||||
|
type RelationshipDTO = components['schemas']['RelationshipDTO'];
|
||||||
|
|
||||||
|
const ALICE_ID = 'alice-uuid';
|
||||||
|
const BOB_ID = 'bob-uuid';
|
||||||
|
|
||||||
|
function makeRel(
|
||||||
|
relationType: RelationshipDTO['relationType'],
|
||||||
|
override: Partial<RelationshipDTO> = {}
|
||||||
|
): RelationshipDTO {
|
||||||
|
return {
|
||||||
|
id: 'rel-1',
|
||||||
|
personId: ALICE_ID,
|
||||||
|
relatedPersonId: BOB_ID,
|
||||||
|
personDisplayName: 'Alice',
|
||||||
|
relatedPersonDisplayName: 'Bob',
|
||||||
|
relationType,
|
||||||
|
...override
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('chipLabel', () => {
|
||||||
|
it('returns parent_of when perspective is the subject of PARENT_OF', () => {
|
||||||
|
const rel = makeRel('PARENT_OF');
|
||||||
|
expect(chipLabel(rel, ALICE_ID)).toBe(m.relation_parent_of());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns child_of when perspective is the object of PARENT_OF', () => {
|
||||||
|
const rel = makeRel('PARENT_OF');
|
||||||
|
expect(chipLabel(rel, BOB_ID)).toBe(m.relation_child_of());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns spouse_of for SPOUSE_OF regardless of perspective', () => {
|
||||||
|
const rel = makeRel('SPOUSE_OF');
|
||||||
|
expect(chipLabel(rel, ALICE_ID)).toBe(m.relation_spouse_of());
|
||||||
|
expect(chipLabel(rel, BOB_ID)).toBe(m.relation_spouse_of());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns sibling_of for SIBLING_OF', () => {
|
||||||
|
expect(chipLabel(makeRel('SIBLING_OF'), ALICE_ID)).toBe(m.relation_sibling_of());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns friend for FRIEND', () => {
|
||||||
|
expect(chipLabel(makeRel('FRIEND'), ALICE_ID)).toBe(m.relation_friend());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns other for OTHER', () => {
|
||||||
|
expect(chipLabel(makeRel('OTHER'), ALICE_ID)).toBe(m.relation_other());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('otherName', () => {
|
||||||
|
it('returns relatedPersonDisplayName when perspective is the subject', () => {
|
||||||
|
const rel = makeRel('PARENT_OF');
|
||||||
|
expect(otherName(rel, ALICE_ID)).toBe('Bob');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns personDisplayName when perspective is the object', () => {
|
||||||
|
const rel = makeRel('PARENT_OF');
|
||||||
|
expect(otherName(rel, BOB_ID)).toBe('Alice');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,4 +1,37 @@
|
|||||||
import * as m from '$lib/paraglide/messages.js';
|
import * as m from '$lib/paraglide/messages.js';
|
||||||
|
import type { components } from '$lib/generated/api';
|
||||||
|
|
||||||
|
type RelationshipDTO = components['schemas']['RelationshipDTO'];
|
||||||
|
|
||||||
|
export function chipLabel(rel: RelationshipDTO, perspectivePersonId: string): string {
|
||||||
|
const viewpointIsSubject = rel.personId === perspectivePersonId;
|
||||||
|
switch (rel.relationType) {
|
||||||
|
case 'PARENT_OF':
|
||||||
|
return viewpointIsSubject ? m.relation_parent_of() : m.relation_child_of();
|
||||||
|
case 'SPOUSE_OF':
|
||||||
|
return m.relation_spouse_of();
|
||||||
|
case 'SIBLING_OF':
|
||||||
|
return m.relation_sibling_of();
|
||||||
|
case 'FRIEND':
|
||||||
|
return m.relation_friend();
|
||||||
|
case 'COLLEAGUE':
|
||||||
|
return m.relation_colleague();
|
||||||
|
case 'EMPLOYER':
|
||||||
|
return m.relation_employer();
|
||||||
|
case 'DOCTOR':
|
||||||
|
return m.relation_doctor();
|
||||||
|
case 'NEIGHBOR':
|
||||||
|
return m.relation_neighbor();
|
||||||
|
default:
|
||||||
|
return m.relation_other();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function otherName(rel: RelationshipDTO, perspectivePersonId: string): string {
|
||||||
|
return rel.personId === perspectivePersonId
|
||||||
|
? rel.relatedPersonDisplayName
|
||||||
|
: rel.personDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a backend inferred-label key (parent, uncle_aunt, ...) to its
|
* Maps a backend inferred-label key (parent, uncle_aunt, ...) to its
|
||||||
|
|||||||
Reference in New Issue
Block a user