import { test, expect, type Page } from '@playwright/test' import { fetchMe, registerViaUi, uniqueUsername } from './helpers/auth' async function finishThroughShop(page: Page, headers: { authorization: string }) { const lessons: Record = { 1: [{ questionId: 'money-q1', answerId: 'option-a' }, { questionId: 'money-q2', answerId: 'true' }, { questionId: 'money-q3', answerId: 'option-a' }, { questionId: 'money-q4', answerId: 'true' }, { questionId: 'money-q5', answerId: 'option-b' }], 2: [{ questionId: 'saving-q1', answerId: 'option-b' }, { questionId: 'saving-q2', answerId: 'true' }, { questionId: 'saving-q3', answerId: 'option-a' }, { questionId: 'saving-q4', answerId: 'true' }, { questionId: 'saving-q5', answerId: 'option-a' }], 3: [{ questionId: 'needs-q1', answerId: 'option-a' }, { questionId: 'needs-q2', answerId: 'true' }, { questionId: 'needs-q3', orderedItemIds: ['water', 'food', 'medicine', 'shoes', 'toy', 'crown'] }, { questionId: 'needs-q4', answerId: 'option-a' }, { questionId: 'needs-q5', answerId: 'true' }], 4: [{ questionId: 'gold-q1', answerId: 'option-a' }, { questionId: 'gold-q2', answerId: 'true' }, { questionId: 'gold-q3', answerId: 'option-a' }, { questionId: 'gold-q4', answerId: 'false' }, { questionId: 'gold-q5', answerId: 'option-b' }], 5: [{ questionId: 'market-q1', answerId: 'option-a' }, { questionId: 'market-q2', answerId: 'false' }, { questionId: 'market-q3', answerId: 'option-a' }, { questionId: 'market-q4', answerId: 'true' }, { questionId: 'market-q5', answerId: 'option-b' }], 6: [{ questionId: 'inflation-q1', answerId: 'option-b' }, { questionId: 'inflation-q2', answerId: 'true' }, { questionId: 'inflation-q3', answerId: 'option-a' }, { questionId: 'inflation-q4', answerId: 'false' }, { questionId: 'inflation-q5', answerId: 'option-b' }], } for (let levelId = 1; levelId <= 6; levelId += 1) { expect((await page.request.post(`/api/gold-land/levels/${levelId}/start`, { headers })).ok()).toBeTruthy() expect((await page.request.post(`/api/gold-land/levels/${levelId}/complete`, { headers, data: { answers: lessons[levelId] } })).ok()).toBeTruthy() } const later = [ { answers: [{ questionId: 'initial', allocations: { transport: 20, food: 25, savings: 20, fun: 0 } }, { questionId: 'final', allocations: { transport: 30, food: 25, savings: 20, fun: 0 } }] }, { answers: [{ questionId: 'q-loss', answerId: 'b' }, { questionId: 'q-certain', answerId: 'no' }, { questionId: 'q-need', answerId: 'keep' }, { questionId: 'q-compare', answerId: 'range' }, { questionId: 'q-promise', answerId: 'check' }] }, { answers: [{ questionId: 'portfolio', holdings: { sun: 40, rain: 30, wind: 30 } }, { questionId: 'q-one', answerId: 'depend' }, { questionId: 'q-loss', answerId: 'no' }, { questionId: 'q-name', answerId: 'no' }, { questionId: 'q-best', answerId: 'no' }, { questionId: 'q-approach', answerId: 'balanced' }] }, { answers: [{ questionId: 'compound-q1', answerId: 'on-balance' }, { questionId: 'compound-q2', answerId: '121' }, { questionId: 'compound-q3', answerId: 'from-110' }, { questionId: 'compound-q4', answerId: 'compound' }, { questionId: 'compound-q5', answerId: 'false' }] }, { answers: [{ questionId: 'notebook-choice', answerId: 'b' }, { questionId: 'notebook-why', answerId: 'fits-and-cheaper' }, { questionId: 'discount-choice', answerId: 'b' }, { questionId: 'discount-why', answerId: 'pay-amount' }, { questionId: 'info-choice', answerId: 'ask' }, { questionId: 'info-why', answerId: 'incomplete' }] }, ] for (let index = 0; index < later.length; index += 1) { const levelId = index + 7 expect((await page.request.post(`/api/gold-land/levels/${levelId}/start`, { headers })).ok()).toBeTruthy() expect((await page.request.post(`/api/gold-land/levels/${levelId}/complete`, { headers, data: later[index] })).ok()).toBeTruthy() } } async function answerGoal(page: Page) { const labels = [ 'خرید بسته مشخص با قیمت ۱۲۰ و برنامه پس‌انداز', '۹۰ سکه', '۶ هفته', 'نیاز را تأمین کن و مبلغ پس‌انداز یا زمان هدف را اصلاح کن', 'برنامه و زمان را دوباره بررسی و به‌روز کن', ] for (let index = 0; index < labels.length; index += 1) { await page.getByText(labels[index]!, { exact: true }).click() if (index < labels.length - 1) await page.getByRole('button', { name: 'بعدی' }).click() else await page.getByRole('button', { name: 'مرور پاسخ‌ها' }).click() } } async function buildPlan(page: Page) { await page.getByRole('button', { name: 'ساخت برنامه' }).click() await page.getByRole('button', { name: '15 سکه در هفته' }).click() await expect(page.getByText('برآورد زمان: 6 هفته')).toBeVisible() await page.getByRole('button', { name: 'تأیید برنامه اولیه' }).click() await page.getByRole('button', { name: 'هفته دوم: 5 سکه' }).click() await page.getByRole('button', { name: 'ادامه: 15 سکه' }).click() await expect(page.getByText('کل زمان: 7 هفته')).toBeVisible() await expect(page.getByText('موجودی نهایی برآوردی: 125 سکه')).toBeVisible() await page.getByRole('button', { name: 'رفتن به سؤال‌ها' }).click() await answerGoal(page) } test('financial goal from the map', async ({ page }) => { const user = uniqueUsername('goal') await registerViaUi(page, user, 'pass1234', 'هدف') const token = await page.evaluate(() => localStorage.getItem('gold-land-auth-token')) await finishThroughShop(page, { authorization: `Bearer ${token}` }) await page.goto('/map') await page.getByRole('button', { name: 'مرحله 12: هدف مالی' }).click() await page.getByRole('button', { name: 'شروع چالش' }).click() await buildPlan(page) const before = await fetchMe(page) await page.getByRole('button', { name: 'ثبت نتیجه' }).click() await expect(page.getByText('پاداش:')).toBeVisible() await page.getByRole('button', { name: 'بازگشت به نقشه' }).click() await page.reload() const after = await fetchMe(page) expect(after.progress.mapLevels.find((level) => level.id === 12)?.stars).toBe(3) expect(after.user.coins).toBe(before.user.coins + 20 + 9) await page.getByRole('button', { name: 'مرحله 12: هدف مالی' }).click() await page.getByRole('button', { name: 'مرور مجدد' }).click() await buildPlan(page) const replayBefore = await fetchMe(page) await page.getByRole('button', { name: 'ثبت نتیجه' }).click() await expect(page.getByText('پاداش تازه‌ای اضافه نشد')).toBeVisible() const replayAfter = await fetchMe(page) expect(replayAfter.user.coins).toBe(replayBefore.user.coins) await page.goto('/map') await page.getByRole('button', { name: 'مرحله 13: آزمون قلعه' }).click() await expect(page.getByRole('button', { name: 'شروع آزمون' })).toBeEnabled() })