(base: string)
| 175 | // ─── HTTP repros (optional) ─────────────────────────────────────────── |
| 176 | |
| 177 | async function httpRepros(base: string): Promise<void> { |
| 178 | const uid = () => `repro-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; |
| 179 | |
| 180 | // #119 illegal POST content-type |
| 181 | { |
| 182 | const room = uid(); |
| 183 | await fetch(`${base}/_/${room}`, { |
| 184 | method: 'PUT', |
| 185 | headers: { 'Content-Type': 'text/plain' }, |
| 186 | body: 'cell:A1:t:hello\n', |
| 187 | }); |
| 188 | await fetch(`${base}/_/${room}`, { |
| 189 | method: 'POST', |
| 190 | body: '1,2,3', // missing Content-Type |
| 191 | }); |
| 192 | const csv = await fetch(`${base}/_/${room}/csv`); |
| 193 | const html = await fetch(`${base}/_/${room}/html`); |
| 194 | record( |
| 195 | 119, |
| 196 | 'GET export after bad POST', |
| 197 | csv.ok && html.ok ? 'fixed' : 'broken', |
| 198 | `csv=${csv.status}, html=${html.status}`, |
| 199 | ); |
| 200 | } |
| 201 | |
| 202 | // #385 / recalc via POST |
| 203 | { |
| 204 | const room = uid(); |
| 205 | await fetch(`${base}/_/${room}`, { |
| 206 | method: 'POST', |
| 207 | headers: { 'Content-Type': 'application/json' }, |
| 208 | body: JSON.stringify({ command: ['set A1 value n 1', 'set A2 value n 2', 'set A3 formula SUM(A1:A2)'] }), |
| 209 | }); |
| 210 | const cells = await fetch(`${base}/_/${room}/cells/A3`); |
| 211 | const j = (await cells.json()) as { datavalue?: number }; |
| 212 | record(385, 'Recalc after API POST', j.datavalue === 3 ? 'fixed' : 'broken', `A3=${j.datavalue}`); |
| 213 | } |
| 214 | |
| 215 | // #304 via PUT csv |
| 216 | { |
| 217 | const room = uid(); |
| 218 | const csv = '1,=A1*2\n2,=A2*2\n'; |
| 219 | await fetch(`${base}/_/${room}`, { |
| 220 | method: 'PUT', |
| 221 | headers: { 'Content-Type': 'text/csv' }, |
| 222 | body: csv, |
| 223 | }); |
| 224 | const snap = await fetch(`${base}/_/${room}`); |
| 225 | const body = await snap.text(); |
| 226 | const hasFormula = body.includes('formula'); |
| 227 | record(304, 'PUT csv preserves formulas', hasFormula ? 'fixed' : 'unchanged', hasFormula ? 'snapshot has formula' : 'no formula in snapshot'); |
| 228 | } |
| 229 | |
| 230 | // #442 DELETE + formdata sibling |
| 231 | { |
| 232 | const room = uid(); |
| 233 | await fetch(`${base}/_/${room}`, { |
| 234 | method: 'POST', |
no test coverage detected