Changeset f926d13 in Klonkt for test


Ignore:
Timestamp:
08/13/2026 07:37:56 PM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
47db4b5
Parents:
822d16d
Message:

De volglijst als bestand uploaden, niet alleen plakken

Robins vraag bij de echte verhuizing: hij downloadt een CSV en moet hem dan met de
hand openen en de inhoud overplakken. Dat is een omweg die niemand hoort te lopen.

Nu een bestandskiezer naast het plakveld. Multer met memoryStorage, want dit is een
lijstje adressen van een paar kilobyte dat na het lezen niets te zoeken heeft op de
server; op schijf schrijven zou alleen rommel achterlaten. Een gekozen bestand wint
van het plakveld: wie een bestand aanwijst bedoelt dat.

De BOM gaat eraf. Excel zet die voor een CSV, en zonder dat eraf te halen plakt hij
aan het eerste adres vast en is de eerste regel stil onbruikbaar.

En twee redirects in deze route wezen nog naar /following. Dat is de oude pagina
waar niets meer naartoe linkt (zie 822d16d), dus je kwam na een import op een
scherm waar je zelf niet meer weg kon. Beide naar /connect.

Changed files:
src/routes/posts.js

  • multer memoryStorage, single('csvfile'), 512kb, 1 bestand
  • bestand wint van plakveld, BOM eraf
  • drie redirects van /following naar /connect

src/views/pages/connect.ejs

  • bestandskiezer met accept=".csv,text/csv,text/plain", formulier op multipart

src/services/i18n.js

  • tl.move_import_file in nl, en en de; het plakveld-label ingekort tot "Of plak de lijst hier"

test/following-csv.test.js

  • test 14: een echt multipart-verzoek met een BOM ervoor, plus de controle dat het plakveld ernaast blijft werken

remarks: 927 groen in UTC en Europe/Amsterdam. De uploadweg is met een echte
multipart-POST tegen een draaiende express+multer getest, niet alleen beredeneerd.
De pagina apart gerenderd: bestandskiezer en multipart-enctype aanwezig, geen
onvertaalde sleutels.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/following-csv.test.js

    r822d16d rf926d13  
    141141  assert.match(String(r.files.get('following.csv')), /jason@a\.example,,,,true/);
    142142});
     143
     144// De uploadweg. De parser kan prima werken terwijl het formulier niets doorgeeft,
     145// en dat merk je pas als je met een echt bestand voor de knop staat.
     146test('een geupload bestand wordt gelezen, ook met de BOM die Excel ervoor zet', async () => {
     147  const multer = (await import('multer')).default;
     148  const express = (await import('express')).default;
     149
     150  const up = multer({ storage: multer.memoryStorage(), limits: { fileSize: 512 * 1024, files: 1 } }).single('csvfile');
     151  const app = express();
     152  app.post('/t', up, (req, res) => {
     153    const csv = (req.file && req.file.buffer)
     154      ? req.file.buffer.toString('utf8').replace(/^/, '')
     155      : ((req.body && req.body.csv) || '');
     156    res.json({ bron: req.file ? 'bestand' : 'plakveld', rijen: parseFollowingCsv(csv) });
     157  });
     158
     159  const srv = app.listen(0);
     160  await new Promise((r) => srv.once('listening', r));
     161  const url = `http://127.0.0.1:${srv.address().port}/t`;
     162  const csv = 'Account address,Show boosts,Notify on new posts,Languages,Featured\n'
     163            + 'jason@a.example,,,,true\n';
     164  try {
     165    const fd = new FormData();
     166    fd.append('csvfile', new Blob([`${csv}`], { type: 'text/csv' }), 'following.csv');
     167    const a = await (await fetch(url, { method: 'POST', body: fd })).json();
     168    assert.equal(a.bron, 'bestand');
     169    assert.deepEqual(a.rijen, [{ address: 'jason@a.example', featured: true }],
     170      'de BOM mag niet in het eerste adres blijven plakken');
     171
     172    // Het plakveld moet blijven werken naast de upload.
     173    const fd2 = new FormData();
     174    fd2.append('csv', csv);
     175    const b = await (await fetch(url, { method: 'POST', body: fd2 })).json();
     176    assert.equal(b.bron, 'plakveld');
     177    assert.deepEqual(b.rijen, [{ address: 'jason@a.example', featured: true }]);
     178  } finally {
     179    srv.close();
     180  }
     181});
Note: See TracChangeset for help on using the changeset viewer.