Sign in verified accounts automatically and require eight-character passwords
This commit is contained in:
@@ -68,18 +68,35 @@ try {
|
||||
const auth = page.locator('.account-auth');
|
||||
await auth.getByLabel('이메일', { exact: true }).fill(email);
|
||||
await auth.getByLabel('표시 이름', { exact: true }).fill(name);
|
||||
await auth.getByLabel('비밀번호', { exact: true }).fill('1234');
|
||||
await auth.getByLabel('비밀번호 확인', { exact: true }).fill('1234');
|
||||
assert.equal(await auth.getByLabel('비밀번호', { exact: true }).getAttribute('minlength'), '8');
|
||||
assert.equal(
|
||||
await auth.getByLabel('비밀번호', { exact: true }).getAttribute('placeholder'),
|
||||
'8자 이상',
|
||||
);
|
||||
await auth.getByLabel('비밀번호', { exact: true }).fill('1234567');
|
||||
await auth.getByLabel('비밀번호 확인', { exact: true }).fill('1234567');
|
||||
const beforeShortPassword = mails.length;
|
||||
await auth.getByRole('button', { name: '가입하고 인증 메일 받기' }).click();
|
||||
assert.equal(
|
||||
await auth.getByLabel('비밀번호', { exact: true }).evaluate((el) => el.validity.tooShort),
|
||||
true,
|
||||
);
|
||||
assert.equal(mails.length, beforeShortPassword);
|
||||
await auth.getByLabel('비밀번호', { exact: true }).fill('12345678');
|
||||
await auth.getByLabel('비밀번호 확인', { exact: true }).fill('12345678');
|
||||
await auth.getByRole('button', { name: '가입하고 인증 메일 받기' }).click();
|
||||
await auth.locator('.auth-message').waitFor();
|
||||
const token = mails.find((m) => m.to === email).text.match(/#verify=([A-Za-z0-9_-]+)/)[1];
|
||||
await page.goto(`${url}/#verify=${token}`);
|
||||
await page.getByRole('button', { name: '이메일 인증 완료하기' }).click();
|
||||
await auth.getByRole('button', { name: '로그인', exact: true }).waitFor();
|
||||
await auth.getByLabel('이메일', { exact: true }).fill(email);
|
||||
await auth.getByLabel('비밀번호', { exact: true }).fill('1234');
|
||||
await auth.getByRole('button', { name: '로그인', exact: true }).click();
|
||||
await page.locator('.account-workspace').waitFor();
|
||||
assert.equal(
|
||||
await page.evaluate(async () => (await (await fetch('/api/auth/me')).json()).account.email),
|
||||
email,
|
||||
'인증한 계정으로 자동 로그인',
|
||||
);
|
||||
assert.equal(await auth.count(), 0);
|
||||
assert(!(await page.locator('body').innerText()).includes('로그인해 주세요'));
|
||||
assert.deepEqual(
|
||||
(await page.getByRole('tab').allTextContents()).map((text) => text.trim()),
|
||||
['받은 항목', '임시 저장'],
|
||||
@@ -377,9 +394,82 @@ try {
|
||||
await receiver.getByRole('button', { name: '로그아웃', exact: true }).click();
|
||||
await receiver.locator('.account-auth').waitFor();
|
||||
assert(!(await receiver.locator('body').innerText()).includes('https://example.com/saved'));
|
||||
const signup = receiver.locator('.account-auth');
|
||||
await signup.getByRole('button', { name: '이메일로 가입', exact: true }).click();
|
||||
await signup.getByLabel('이메일', { exact: true }).fill('carol@example.com');
|
||||
await signup.getByLabel('표시 이름', { exact: true }).fill('Carol');
|
||||
await signup.getByLabel('비밀번호', { exact: true }).fill('12345678');
|
||||
await signup.getByLabel('비밀번호 확인', { exact: true }).fill('12345678');
|
||||
await signup.getByRole('button', { name: '가입하고 인증 메일 받기' }).click();
|
||||
await signup.locator('.auth-message').waitFor();
|
||||
const carolToken = mails
|
||||
.find((mail) => mail.to === 'carol@example.com')
|
||||
.text.match(/#verify=([A-Za-z0-9_-]+)/)[1];
|
||||
const oldAccountCookie = (await a.cookies(url)).find(
|
||||
(cookie) => cookie.name === 'hop_account',
|
||||
).value;
|
||||
const verificationPage = await a.newPage();
|
||||
verificationPage.on('pageerror', (error) => errors.push(error.message));
|
||||
await verificationPage.goto(`${url}/#verify=${carolToken}`);
|
||||
await verificationPage.getByRole('button', { name: '이메일 인증 완료하기' }).waitFor();
|
||||
await verificationPage.locator('.app-shell[data-online="true"]').waitFor();
|
||||
await verificationPage.waitForFunction(
|
||||
() => document.querySelector('.account-auth button[type="submit"]')?.disabled === false,
|
||||
);
|
||||
assert.equal(
|
||||
await verificationPage.evaluate(
|
||||
async () => (await (await fetch('/api/auth/me')).json()).account.email,
|
||||
),
|
||||
'alice@example.com',
|
||||
);
|
||||
let delayedAuthLookup = false;
|
||||
await verificationPage.route('**/api/auth/me', async (route) => {
|
||||
const response = await route.fetch();
|
||||
if (!delayedAuthLookup) {
|
||||
delayedAuthLookup = true;
|
||||
const stale = { ...(await response.json()), account: null };
|
||||
await new Promise((resolve) => setTimeout(resolve, 260));
|
||||
await route.fulfill({ response, json: stale });
|
||||
} else await route.fulfill({ response });
|
||||
});
|
||||
await verificationPage.getByRole('button', { name: '이메일 인증 완료하기' }).click();
|
||||
await verificationPage.locator('.account-workspace').waitFor();
|
||||
await verificationPage.unroute('**/api/auth/me');
|
||||
assert.equal(
|
||||
await verificationPage.evaluate(
|
||||
async () => (await (await fetch('/api/auth/me')).json()).account.email,
|
||||
),
|
||||
'carol@example.com',
|
||||
);
|
||||
assert.equal(
|
||||
await verificationPage
|
||||
.getByRole('tab', { name: '받은 항목', exact: true })
|
||||
.getAttribute('aria-selected'),
|
||||
'true',
|
||||
);
|
||||
assert.equal(await verificationPage.locator('.item-card,.account-auth').count(), 0);
|
||||
assert(
|
||||
!(await verificationPage.locator('body').innerText()).includes('https://example.com/saved'),
|
||||
);
|
||||
const revokedAccount = await a.request.get(`${url}/api/auth/me`, {
|
||||
headers: { Cookie: `hop_account=${oldAccountCookie}` },
|
||||
});
|
||||
assert.equal((await revokedAccount.json()).account, null);
|
||||
const inaccessibleVault = await a.request.get(`${url}/api/vault`, {
|
||||
headers: { Cookie: `hop_account=${oldAccountCookie}` },
|
||||
});
|
||||
assert.equal(inaccessibleVault.status(), 401);
|
||||
assert.equal(verificationPage.url(), `${url}/`, '인증 토큰을 주소창에 남기지 않음');
|
||||
await verificationPage.getByRole('button', { name: '계정 설정', exact: true }).click();
|
||||
await verificationPage
|
||||
.getByRole('dialog', { name: '계정 설정', exact: true })
|
||||
.getByText('carol@example.com', { exact: true })
|
||||
.waitFor();
|
||||
await verificationPage.screenshot({ path: 'tests/e2e/verification-switch.png' });
|
||||
await verificationPage.close();
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(
|
||||
'PASS: 받은 항목 기본 화면·보관 안내, PC/모바일 계정 설정·입력·키보드 탐색, 가입·인증·로그인, 날짜별 기록, 직접 링크/파일 저장·메모·수락 후 자동 열기/다운로드, 파일 재업로드 없음, 7일 만료·삭제/복원·로그아웃 권한 격리, 원본 수동 삭제 시 다운로드 전 안내·양쪽 목록/용량 정리·열린 전송 선택 해제. 실제 Resend 발송은 포함하지 않음.',
|
||||
'PASS: PC/모바일 가입 8자 규칙과 인증 자동 로그인, 다른 계정의 인증 링크에서 세션 교체·이전 쿠키 무효화·보관함 격리·지연된 인증 조회 경합, 받은 항목 기본 화면·계정 설정·날짜별 기록·저장/메모/수락 후 열기/다운로드·7일 보관·삭제/복원·원본 수동 삭제 대응·토스트. 실제 Resend 발송은 포함하지 않음.',
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
Reference in New Issue
Block a user