feat(taiga): Ticket-Stand im Knoten-Fenster — gelesen, nie geschrieben (D91-Nachtrag 6, SPEC §9)
Wo eine Ref steht und ein `&taiga.<slug>` gilt, zeigt das Knoten-Fenster
Betreff, Status und Zuständigen des Tickets; Taigas Statusname steht neben
der Statusbox der Notation (`In progress → [~]`).
- Proxy: zwei benannte Lese-Endpunkte (`GET /taiga/userstories/{ref}` und
`…/tasks/{ref}`, je `?slug=`) — das Präfix der Ref trägt den Typ, Taiga
hat getrennte `by_ref`-Endpunkte. Erst `/projects/by_slug`, dann `by_ref`
(eine Ref ist nur je Projekt eindeutig); der Slug wird kodiert angehängt.
- Die Abbildung Status → Statusbox liegt im Editor (`mapTaigaStatus`,
headless): Statuscodes sind Notation, das Backend parst sie nicht (D14).
Unbekannte Namen bleiben unabgebildet — Raten hieße, dem Knoten eine
Aussage zu geben, die niemand gemacht hat.
- Geholt wird erst nach 400 ms Verweilen und je Ticket einmal je Sitzung
(↻ holt neu); ohne Anmeldung gar nicht — der Knopf meldet erst an.
- Nichts wird geschrieben: kein Text, keine Statusbox (das bleibt
`#trk.write`).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e58f71bf90
commit
842e89795a
@@ -1,7 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { parse } from '../src/parser.js';
|
||||
import { taigaSlugs } from '../src/model.js';
|
||||
import { ticketRefOf, taskCandidates, appendToken, refToken, slugToken, ticketUrl, ticketRefAt } from '../src/taiga.js';
|
||||
import { ticketRefOf, taskCandidates, appendToken, refToken, slugToken, ticketUrl, ticketRefAt, refParts, ticketApiPath, mapTaigaStatus } from '../src/taiga.js';
|
||||
|
||||
/* Schlagworte `&tag` (SPEC §1, D91): Extraktion im Parser und die
|
||||
`taiga.*`-Vererbung in model.js — der erste Konsument der reservierten
|
||||
@@ -242,3 +242,62 @@ describe('ticketRefAt — die Ref unter der Schreibmarke', () => {
|
||||
expect(ticketRefAt(text, at(text, 'US'))).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
/* Ticket-Stand lesen (D91-Nachtrag 6): Ref zerlegen, Proxy-Pfad bauen,
|
||||
Taiga-Workflow auf die Statusbox der Notation abbilden. */
|
||||
|
||||
describe('refParts / ticketApiPath — das Präfix trägt den Typ', () => {
|
||||
it('zerlegt Story- und Task-Refs', () => {
|
||||
expect(refParts('US-123')).toEqual({kind: 'US', nr: '123'});
|
||||
expect(refParts('T-9')).toEqual({kind: 'T', nr: '9'});
|
||||
});
|
||||
|
||||
it('alles andere ergibt null — geraten wird nicht', () => {
|
||||
expect(refParts('ABC-1')).toBe(null);
|
||||
expect(refParts('US-1x')).toBe(null);
|
||||
expect(refParts('123')).toBe(null);
|
||||
expect(refParts(null)).toBe(null);
|
||||
});
|
||||
|
||||
it('baut die getrennten by_ref-Pfade des Proxys samt Slug', () => {
|
||||
expect(ticketApiPath('US-123', 'mi-kunde')).toBe('/userstories/123?slug=mi-kunde');
|
||||
expect(ticketApiPath('T-1234', 'mi-kunde')).toBe('/tasks/1234?slug=mi-kunde');
|
||||
});
|
||||
|
||||
it('kodiert den Slug — er hängt keinen zweiten Parameter an', () => {
|
||||
expect(ticketApiPath('US-1', 'a&b=2')).toBe('/userstories/1?slug=a%26b%3D2');
|
||||
});
|
||||
|
||||
it('ohne Slug oder mit unbrauchbarer Ref gibt es keinen Pfad', () => {
|
||||
expect(ticketApiPath('US-1', null)).toBe(null);
|
||||
expect(ticketApiPath('ABC-1', 'mi-kunde')).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapTaigaStatus — Workflow auf die Statusbox (SPEC §4/§9)', () => {
|
||||
const code = name => (mapTaigaStatus(name) || {}).code;
|
||||
|
||||
it('bildet die fünf vorgegebenen Zustände ab', () => {
|
||||
expect(code('New')).toBe(' ');
|
||||
expect(code('In progress')).toBe('~');
|
||||
expect(code('Ready for test')).toBe('/');
|
||||
expect(code('Done')).toBe('x');
|
||||
expect(code('Archived')).toBe('^');
|
||||
});
|
||||
|
||||
it('liefert den vollen Status samt Schlüssel für die Anzeige', () => {
|
||||
expect(mapTaigaStatus('in progress').key).toBe('arbeit');
|
||||
expect(mapTaigaStatus('DONE').key).toBe('fertig');
|
||||
});
|
||||
|
||||
it('Groß-/Kleinschreibung und Leerraum sind egal', () => {
|
||||
expect(code(' ready FOR test ')).toBe('/');
|
||||
});
|
||||
|
||||
it('ein unbekannter Name bleibt unabgebildet', () => {
|
||||
expect(mapTaigaStatus('Blocked')).toBe(null);
|
||||
expect(mapTaigaStatus('')).toBe(null);
|
||||
expect(mapTaigaStatus(null)).toBe(null);
|
||||
expect(mapTaigaStatus(undefined)).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user