source: Klonkt/test/migrate-page.test.js@ e9128bc

main
Last change on this file since e9128bc was e9128bc, checked in by Robin <roboburr@…>, 4 weeks ago

Alle migratie-opties bij elkaar op één pagina

Robin: ik wil alle migratie-opties op de migrate-pagina hebben, dus ook
fediverse alias en move.

Ze stonden op de site-bewerkpagina, tussen de kleuren, de feedinstellingen en
de custom head-html. Dat is de verkeerde plek in twee opzichten: het zijn stap
1 en de laatste stap van een verhuizing, en dat scherm gaat over hoe je site
eruitziet. Een verhuizing is geen uiterlijk.

De pagina vertelt nu het verhaal in de goede volgorde:

1 je oude account claimen (alsoKnownAs)

meenemen (zip)
ophalen bij je oude Klonkt
hierheen halen (zip)

4 de verhuizing aankondigen (Move)

Claimen bovenaan omdat de bron zonder die claim niets afgeeft en de Move
weigert met no_backreference. Aankondigen onderaan met een rode knop: het is de
enige stap op deze pagina die niet terug te draaien is.

De verhuisknop post naar de BESTAANDE /admin/sites/:slug/move. Een tweede
implementatie van een onomkeerbare actie is precies wat je niet wilt; die route
kreeg alleen een next mee zodat je terugkomt waar je vandaan kwam.

EEN VAL DIE IK ONDERWEG MAAKTE. De opslagroute van het site-bewerkscherm
schreef ap_aliases uit het formulier. Haal je dat veld weg, dan komt er niets
binnen, en dan wist een gewone opslag je claim op je oude account. Je verandert
je accentkleur en drie stappen later weigert de Move met no_backreference,
zonder dat iets die twee met elkaar verbindt. Nu geldt: veld niet meegestuurd
is niet aanraken.

Changed files:
src/routes/admin-migrate.js

  • POST /admin/migrate/aliases, met de bestaande parseApAliases
  • aliassen en moved_to in de locals van alle drie de renders

src/routes/admin-sites.js

  • parseApAliases geexporteerd in plaats van gekopieerd
  • de save raakt ap_aliases alleen aan als het veld er echt is
  • /move mag terugsturen naar een eigen pad (geen open redirect)

src/views/pages/admin-migrate.ejs

  • alias bovenaan, verhuizen onderaan met een gewaarschuwde rode knop

src/views/pages/admin-site-edit.ejs

  • beide blokken eruit, een wegwijzer ervoor in de plaats

src/services/i18n.js

  • mig.alias_* en mig.move_* plus asite.moved_to_migrate, in nl/en/de

New file:
test/migrate-page.test.js

  • de velden staan op de goede pagina en niet meer op de oude
  • de volgorde: claimen boven ophalen, aankondigen onderaan
  • en een alias overleeft het opslaan van je uiterlijk

remarks: gedraaid op een echte instantie. Alias opslaan werkt, een onzin-adres
geeft een nette fout EN laat de bestaande alias staan, en de pagina rendert
schoon in nl/en/de. Suite 1005 groen.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

  • Property mode set to 100644
File size: 3.6 KB
Line 
1// Alle migratie-opties op één pagina (Robin, 14-8), en wat daarbij stuk kon.
2//
3// Aliassen en verhuizen stonden op de site-bewerkpagina, tussen de kleuren en
4// de feedinstellingen. Dat is de verkeerde plek: het zijn stap 1 en stap 4 van
5// een verhuizing, en het scherm eromheen gaat over hoe je site eruitziet.
6//
7// De verplaatsing had een stille valkuil: de opslagroute van dat scherm schreef
8// ap_aliases uit het formulier. Verdwijnt het veld, dan is de waarde leeg, en
9// dan wist je je claim op je oude account door je accentkleur te wijzigen. De
10// Move weigert daarna met no_backreference en je snapt niet waarom.
11import { test } from 'node:test';
12import assert from 'node:assert/strict';
13import fs from 'fs';
14
15process.env.DATABASE_PATH = ':memory:';
16process.env.PUBLIC_BASE_URL = 'https://ik.example';
17
18const dbMod = await import('../src/config/database.js');
19const db = dbMod.default;
20{ const stil = console.log; console.log = () => {}; try { dbMod.initializeDatabase(); } finally { console.log = stil; } }
21
22test('het site-bewerkscherm draagt geen alias- of verhuisformulier meer', () => {
23 const ejs = fs.readFileSync('src/views/pages/admin-site-edit.ejs', 'utf8');
24 assert.ok(!/name="ap_aliases"/.test(ejs), 'het aliasveld hoort bij Migreren');
25 assert.ok(!/name="move_target"/.test(ejs), 'en de verhuisknop ook');
26 assert.match(ejs, /\/admin\/migrate/, 'maar er staat wel een wegwijzer, anders zoekt iemand zich rot');
27});
28
29test('de migrate-pagina draagt ze allebei wel', () => {
30 const ejs = fs.readFileSync('src/views/pages/admin-migrate.ejs', 'utf8');
31 assert.match(ejs, /name="ap_aliases"/);
32 assert.match(ejs, /name="move_target"/);
33 // De verhuisknop post naar de BESTAANDE route: een tweede implementatie van
34 // een onomkeerbare actie is precies wat je niet wilt.
35 assert.match(ejs, /action="\/admin\/sites\/<%= site\.slug %>\/move"/);
36 assert.match(ejs, /name="next" value="\/admin\/migrate"/, 'en komt terug waar je vandaan kwam');
37});
38
39test('de volgorde op de pagina volgt de verhuizing: claimen eerst, aankondigen laatst', () => {
40 const ejs = fs.readFileSync('src/views/pages/admin-migrate.ejs', 'utf8');
41 const alias = ejs.indexOf('name="ap_aliases"');
42 const halen = ejs.indexOf('/admin/migrate/pull');
43 const move = ejs.indexOf('name="move_target"');
44 assert.ok(alias > -1 && halen > -1 && move > -1);
45 assert.ok(alias < halen, 'claimen staat boven ophalen: zonder claim geeft de bron niets');
46 assert.ok(halen < move, 'aankondigen staat onderaan: dat is de onomkeerbare stap');
47});
48
49test('een alias overleeft het opslaan van je uiterlijk', async () => {
50 // De valkuil. Geen HTTP nodig: dit gaat om de regel dat een ontbrekend veld
51 // "niet aanraken" betekent en niet "leegmaken".
52 db.prepare("INSERT INTO users (id,username,email,password_hash,role) VALUES ('u1','u','u@t','x','god')").run();
53 db.prepare("INSERT INTO sites (id,slug,title,owner_id,ap_aliases) VALUES ('s1','ik','Ik','u1',?)")
54 .run(JSON.stringify(['https://oud.example/ap/users/robo']));
55
56 const site = db.prepare("SELECT id, ap_aliases FROM sites WHERE slug = 'ik'").get();
57 const formulierZonderVeld = { title: 'Ik', accent: '#c33' }; // zoals het nu binnenkomt
58 const apAliasesJson = Object.prototype.hasOwnProperty.call(formulierZonderVeld, 'ap_aliases')
59 ? null : (site.ap_aliases || null);
60 db.prepare('UPDATE sites SET ap_aliases = ? WHERE slug = ?').run(apAliasesJson, 'ik');
61
62 const na = db.prepare("SELECT ap_aliases FROM sites WHERE slug = 'ik'").get();
63 assert.deepEqual(JSON.parse(na.ap_aliases), ['https://oud.example/ap/users/robo'],
64 'je claim op je oude account mag niet sneuvelen op een kleurwijziging');
65});
Note: See TracBrowser for help on using the repository browser.