# چک‌لیست آزمون دستی (فارسی)

این چک‌لیست ۱۵ معیار پذیرش را پوشش می‌دهد. بخش اول با آزمون‌های خودکار اجرا شده است؛
بخش دوم باید **روی سرور واقعی** با اعتبارنامه‌های واقعی انجام شود.

---

## بخش الف — آزمون‌های خودکار

```bash
cd aquacoin-marketplace
mkdir -p storage/logs storage/database tests/.tmp
php tests/run.php
```

خروجی انتظاری:

```
موارد موفق: ۱۸۲
موارد ناموفق: ۰
همه آزمون‌ها با موفقیت اجرا شدند.
```

پوشش‌شده توسط آزمون‌ها:

| معیار | نتیجه |
|---|---|
| مبلغ ۲۷ AquaCoin = ۲۷٬۰۰۰ تومان | ✅ محاسبهٔ صحیح عددی |
| رد تعدادِ کمتر از ۱۰، اعشاری، منفی، غیرعددی | ✅ |
| رد نام کاربری نامعتبر ماینکرفت | ✅ |
| رد قیمت/تعداد دستکاری‌شده در سمت مرورگر | ✅ بازمحاسبهٔ سروری |
| پرداخت تأییدنشده هرگز تحویل نمی‌دهد | ✅ |
| پرداخت معتبر → دقیقاً یک فرمان `giveaquacoin Steve 27` | ✅ |
| callback تکراری نمی‌تواند دو بار اعطا کند | ✅ کلید یکتا + یونیک دیتابیس |
| تلاش مجدد پس از شکست نمی‌تواند دو بار اعطا کند | ✅ همان کلید یکتا |
| تلاش‌های ناموفقِ پیاپی → بررسی دستی | ✅ |
| وضعیت نامشخص (timeout) → بررسی دستی، بازارسال خودکار ممنوع | ✅ |
| مدیر AquaMC از مسیرهای ادمین مسدود است | ✅ ۴۰۳ |
| مدیر نمی‌تواند تسویهٔ مدیر دیگر را بخواند/تغییر دهد | ✅ |
| تغییر وضعیت تسویه بدون اجازه رد می‌شود | ✅ |
| CSRF فعال است (توکن نامعتبر → ۴۱۹) | ✅ |
| محدودسازی ورود فعال است | ✅ |
| لاگ حسابرسی ثبت می‌شود | ✅ |
| قفل نصاب مانع ساخت مدیر اولیهٔ جدید می‌شود | ✅ |
| خروجی HTML در برابر XSS ایمن است (escape) | ✅ |

---

## بخش ب — آزمون دستی روی مرورگر

### ۱. خرید ۱۰ عدد AquaCoin
1. صفحهٔ اصلی را باز کنید و مقدار را `۱۰` بگذارید.
2. مبلغ نمایش‌داده‌شده باید **۱۰٬۰۰۰ تومان** باشد.
3. نام کاربری معتبر وارد کنید و ادامه دهید.

**انتظار:** انتقال به درگاه زرین‌پال و ثبت سفارش با وضعیت «در انتظار پرداخت».

### ۲. خرید تعداد دلخواه (۲۷ عدد)
1. مقدار را `۲۷` وارد کنید.
2. مبلغ باید **۲۷٬۰۰۰ تومان** باشد.

**انتظار:** همانند بالا؛ در پایگاه داده `quantity = 27` و `amount_toman = 27000`.

### ۳. محاسبهٔ مبلغ
`۲۷ × ۱,۰۰۰ = ۲۷,۰۰۰ تومان` — عدد باید با جداکنندهٔ هزارگانِ فارسی نمایش داده شود (`۲۷٬۰۰۰`).

### ۴. رد ورودی‌های نامعتبر
| ورودی | انتظار |
|---|---|
| تعداد `۹` | پیام خطا: حداقل ۱۰ عدد |
| تعداد `۱۲.۵` | پیام خطا: تعداد باید عدد صحیح باشد |
| تعداد `abc` یا خالی | پیام خطای فارسی در کنار فیلد |
| نام کاربری `ab` یا `bad-name!` یا ۲۰ کاراکتر | پیام خطا: نام کاربری معتبر نیست |
| دستکاری `quantity`/`amount` با ابزار توسعه‌دهنده | سرور مقدار را بازمحاسبه می‌کند؛ مقدار جعلی پذیرفته نمی‌شود |

### ۵. پرداخت ناموفق → بدون تحویل
1. در درگاه «انصراف» را بزنید یا پرداخت را ناموفق کنید.
2. به `/order/{کد}` برگردید.

**انتظار:** وضعیت «پرداخت ناموفق/لغو شده»؛ **هیچ** فرمانی به ماینکرفت ارسال نشده است
(در `/admin/deliveries` هیچ رکوردی برای این سفارش نیست).

### ۶. پرداخت معتبر → تحویل خودکار
1. یک پرداخت واقعی (یا با `merchant_id` معتبر در حالت تولید) انجام دهید.
2. پس از بازگشت، وضعیت سفارش را دنبال کنید.

**انتظار:** «پرداخت شده» → «در انتظار تحویل» → «تحویل شده» و در لاگ تحویل
فرمان `giveaquacoin Steve 27` با پاسخ موفق ثبت شده باشد.

### ۷. callback تکراری
1. آدرس بازگشتِ همان سفارش را دو بار در مرورگر باز کنید (یا با curl فراخوانی کنید).

**انتظار:** پیام «این سفارش قبلاً پردازش شده است»؛ تعداد کارهای تحویل برای آن سفارش **یک** عدد باقی می‌ماند
و فقط یک بار سکه اعطا می‌شود.

### ۸. خطای RCON/Bridge به‌صورت ایمن ثبت می‌شود
1. اتصال ماینکرفت را موقتاً قطع کنید (یا پورت را اشتباه بگذارید) و یک پرداخت موفق انجام دهید.

**انتظار:** وضعیت سفارش «تحویل ناموفق» یا «نیازمند بررسی دستی»؛ پاسخ/خطا در
`/admin/deliveries` ثبت شده و **هیچ** سکه‌ای به‌صورت کورکورانه اعطا نشده است.

### ۹. تلاش مجدد نمی‌تواند دو بار اعطا کند
1. در `/admin/deliveries` روی «تکرار» بزنید.

**انتظار:** همان کلید یکتا دوباره ارسال می‌شود؛ در حالت Bridge افزونه پاسخ
`duplicate: true` می‌دهد و سکه‌ای اضافه نمی‌شود. در حالت RCON (بدون کلید یکتا)
تلاش مجدد خودکار برای وضعیت‌های نامشخص **مجاز نیست**.

### ۱۰. دسترسی مدیر AquaMC به مسیرهای ادمین
1. با حساب مدیر وارد شوید و مستقیماً `/admin` را باز کنید.

**انتظار:** صفحهٔ **۴۰۳**؛ در لاگ حسابرسی ثبت می‌شود.

### ۱۱. عدم دسترسی مدیر به داده‌های مدیر دیگر
1. دو حساب مدیر بسازید (A و B).
2. با A یک درخواست تسویه ثبت کنید.
3. با B سعی کنید درخواست A را ببیند/ویرایش کند.

**انتظار:** درخواست A در فهرست B نیست؛ تلاش مستقیم برای ویرایش → خطای دسترسی.

### ۱۲. تغییر غیرمجاز وضعیت تسویه
1. با حساب مدیر، درخواستی ثبت کنید و تلاش کنید آن را تأیید/پرداخت کنید.

**انتظار:** رد می‌شود. فقط ادمین WinixStore می‌تواند وضعیت را تغییر دهد
و هر تغییر با نام ادمین، زمان و یادداشت ثبت می‌شود.

### ۱۳. CSRF و محدودسازی نرخ
1. فرم ورود را در یک تب باز کنید، در تب دیگر خارج شوید و دوباره وارد شوید، سپس فرم اول را ارسال کنید.
2. فرم ثبت سفارش را بدون توکن (با حذف فیلد `_token`) ارسال کنید.
3. پنج بار رمز عبور اشتباه وارد کنید.

**انتظار:** به‌ترتیب: صفحهٔ ۴۱۹، صفحهٔ ۴۱۹، و پیام «تلاش‌های زیاد؛ کمی بعد دوباره تلاش کنید»
(قفل موقت).

### ۱۴. نصاب نمی‌تواند مدیر اولیه را دوباره بسازد
1. پس از نصب، فایل `public/install.php` را دوباره اجرا کنید.

**انتظار:** پاسخ ۴۰۳ و پیام «نصب قبلاً انجام شده است».

### ۱۵. فایل‌های حساس از وب قابل دریافت نیستند
این آدرس‌ها را امتحان کنید (همگی باید ۴۰۳/۴۰۴ باشند):

```
https://example.com/config/config.php
https://example.com/storage/database/app.sqlite
https://example.com/storage/logs/app-YYYY-MM-DD.log
https://example.com/app/Core/Config.php
https://example.com/schema/sqlite.sql
https://example.com/.env
```

---

## بخش ج — بررسی ظاهری و واکنش‌گرایی (انجام شده)

ابزار `tests/visual_audit.py` در چهار اندازه (موبایل ۳۹۰، تبلت ۸۳۴، دسکتاپ ۱۴۴۰)
این موارد را بررسی کرده است:

* هیچ سرریز افقی (horizontal scroll) در هیچ صفحه‌ای
* `lang="fa"` و `dir="rtl"` در همهٔ صفحات
* بارگذاری فونت Vazirmatn
* بدون خطای کنسول (CSP شامل inline handlerها می‌شود)
* اهداف لمسی (tap target) با ارتفاع کافی

تصاویر نمونه در `docs/screenshots/` است.

---

## بخش د — مواردی که فقط با اعتبارنامه/سرور واقعی قابل بررسی است

1. پرداخت واقعی زرین‌پال (تولید) و تطبیق مبلغ در واحد تومان
2. رفتار زرین‌پال در حالت انصراف/نا‌موفق واقعی
3. نصب افزونهٔ `AquaCoinBridge` روی Paper/Purpur و اجرای واقعی `giveaquacoin`
4. هماهنگی `grant-command` با افزونهٔ اقتصادی سرور
5. اتصال RCON واقعی با فایروال
6. همزمانی callback روی MySQL
7. ارسال ایمیل/پیامک (پیاده‌سازی نشده)
