/** * test/e2e/fake-mail.mjs — Resend 호환 발신 API 흉내(포털 mailer 'resend' 모드 포획). * 포털이 보내는 이메일(가입 확인·초대·필수 알림)을 메모리에 모아 하네스가 링크·토큰을 꺼내 쓴다. 실제 발송은 없다. * POST /emails { from, to[], subject, text, html } → { id } */ import http from 'node:http'; export async function startFakeMail(port) { const mails = []; const srv = http.createServer((req, res) => { let body = ''; req.on('data', (c) => (body += c)); req.on('end', () => { const j = (code, o) => { res.writeHead(code, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(o)); }; if (req.method === 'POST' && req.url === '/emails') { if (!/^Bearer /.test(req.headers.authorization || '')) return j(401, { name: 'unauthenticated' }); let m = {}; try { m = JSON.parse(body); } catch (_) {} const id = 'mail_' + (mails.length + 1); mails.push({ id, at: new Date().toISOString(), to: [].concat(m.to || []), subject: m.subject || '', text: m.text || '', html: m.html || '' }); return j(200, { id }); } j(404, { name: 'not_found' }); }); }); await new Promise((r) => srv.listen(port, '127.0.0.1', r)); return { url: `http://127.0.0.1:${port}`, mails, /** 받는 사람·제목 조건으로 마지막 메일 찾기 */ last: (to, re = null) => [...mails].reverse().find((m) => (!to || m.to.includes(to)) && (!re || re.test(m.subject + '\n' + m.text))) || null, close: () => new Promise((r) => srv.close(r)) }; }