Clarify transfer rejections and improve storage readability

This commit is contained in:
2026-10-15 17:18:07 +09:00
parent 60a14e9c6c
commit 8fb8c203f0
17 changed files with 300 additions and 55 deletions

View File

@@ -194,9 +194,52 @@ try {
await expect(blocked.getByText('차단한 기기가 없어요.')).toBeVisible();
await expect(receiver.locator('.peer-card')).toHaveCount(1);
assert.equal((await api(receiver, '/device/blocks')).blocks.length, 0);
await blocked.getByRole('button', { name: '대화상자 닫기', exact: true }).click();
const recipientName = (await api(receiver, '/device/me')).device.name;
// Reject the first request before its POST response reaches the sender. This
// must still close the composer even if it never observed a pending snapshot.
await sender.route('**/api/transfer-requests', async (route) => {
const response = await route.fetch();
assert.equal(response.status(), 200);
const { requestId } = await response.json();
await api(receiver, `/transfer-requests/${requestId}/reject`, 'POST', {});
await route.fulfill({ response });
});
for (const kind of ['text', 'file', 'url']) {
await sender.locator('.peer-card').first().click();
if (kind === 'file')
await sender.getByLabel('보낼 파일 선택', { exact: true }).setInputFiles({
name: 'declined.txt',
mimeType: 'text/plain',
buffer: Buffer.from('test'),
});
else
await sender
.getByLabel('보낼 텍스트', { exact: true })
.fill(kind === 'url' ? 'https://example.com/declined' : '빠른 거절도 놓치지 않습니다.');
await sender.getByRole('button', { name: '전송하기', exact: true }).click();
if (kind !== 'text') {
const incoming = receiver.getByRole('dialog', { name: '전송 수락 요청' });
await incoming.getByRole('button', { name: '거절', exact: true }).click();
}
await expect(sender.locator('.send-dialog')).toHaveCount(0);
await expect(sender.locator('.toast')).toHaveText(`${recipientName}에서 전송을 거절했어요.`);
if (kind === 'text') await sender.unroute('**/api/transfer-requests');
}
// History must not replay rejection notifications after a reload; the fourth
// request now gets the real pair cooldown and visible remaining seconds.
await sender.reload();
await sender.locator('.peer-card').first().waitFor();
await expect(sender.locator('.toast')).toHaveCount(0);
await sender.locator('.peer-card').first().click();
await sender.getByLabel('보낼 텍스트', { exact: true }).fill('세 번 거절 이후의 대기');
await sender.getByRole('button', { name: '전송하기', exact: true }).click();
await expect(sender.locator('.content-submit')).toBeDisabled();
await expect(sender.locator('.content-submit')).toHaveText(/\d+초 후 전송 가능/);
await expect(sender.locator('.error-toast')).toContainText('연속 3회 거절');
assert.deepEqual(errors, []);
console.log(
'PASS: content icons/titles, desktop/mobile 2:1 buttons, consistent single file sizes 97.7KB/1.3MB/1.6GB, no list indent or overflow, retry countdown and draft preservation, block confirmation and private unblock UI.',
'PASS: receive icons/sizes, desktop/mobile 2:1 controls, retry countdown/draft preservation, block/unblock, first two rejections allow retries, text/file/link rejection closes sender and notifies, decision before HTTP response and reload deduplication, third rejection triggers pair cooldown.',
);
} finally {
await browser?.close();