# Manual QA Test Scripts - Payment Gateway Landing

## Test Environment Setup

**Prerequisites:**

- Application running on https://landing.academy.introduct.dev/ (dev) or configured port
- PostgreSQL database initialized and migrated
- Payment Gateway API running on https://payment-gw.academy.introduct.dev/
- Azure Email Service configured (or Swoosh local in dev)
- Valid test credentials
- Network access for API calls

**Environment Variables Required:**

- `GATEWAY_API_BASE_URL` - Gateway API endpoint
- `REGISTRATION_USER_UUID` - System user UUID for registration
- `REGISTRATION_USER_PRIV_KEY` - System private key

---

## Test Suite 1: User Creation

### TC-UC-001: Create New User with Valid Data

**Objective:** Verify that a new user can be created successfully with all required fields.

**Preconditions:**

- Navigate to `/users/register`
- Email service is operational
- Payment Gateway API is accessible

**Test Data:**

- Name: `John Doe` (2-80 characters)
- Email: `testuser_${timestamp}@example.com`
- Password: `ValidPassword123!` (minimum 12 characters)

**Steps:**

1. Navigate to `/users/register`
2. Fill in Name: `John Doe`
3. Fill in Email: unique email address
4. Fill in Password: at least 12 characters
5. Complete Cloudflare Turnstile CAPTCHA challenge
6. Click "Create an account →" button
7. Observe automatic login and redirection

**Expected Results:**

- User account created successfully in database
- Flash message: "Account created successfully!"
- User automatically logged in with session created
- Redirected to homepage `/`
- User starts with `status: :pending` (requires admin approval for full access)
- Registration notification email sent via Azure Email Service
- Email contains welcome message and account details
- User can now access authenticated routes like `/users/settings`

**Postconditions:**

- New user record in `users` table
- User session created

---

### TC-UC-002: Create User with Duplicate Email

**Objective:** Verify system prevents duplicate user registration.

**Preconditions:**

- Existing user with email `existing@example.com` in database

**Test Data:**

- Email: `existing@example.com` (already registered)
- Name: `Test User`
- Password: `NewPassword123!`

**Steps:**

1. Navigate to `/users/register`
2. Enter email that already exists in system
3. Fill remaining required fields
4. Click "Create an account" button

**Expected Results:**

- Registration fails with validation error
- Error message displayed under email field: "has already been taken"
- No new user record created
- User remains on registration page
- No email sent

---

### TC-UC-003: Create User with Invalid Email Format

**Objective:** Verify email validation works correctly.

**Test Data:**

- Invalid emails:
  - `invalid.email` (no @ sign)
  - `@example.com` (missing local part)
  - `user@` (missing domain)
  - `user @example.com` (contains space)

**Steps:**

1. Navigate to `/users/register`
2. Enter invalid email format
3. Fill other fields correctly
4. Attempt to submit form

**Expected Results:**

- Validation error displayed under email field
- Error message: "must be a valid email address"
- Form not submitted
- No user created
- No database changes

---

### TC-UC-004: Create User with Weak Password

**Objective:** Verify password strength requirements are enforced.

**Test Data:**

- Weak passwords:
  - `short` (less than 12 characters)
  - `123` (too short)
  - `password` (too short)

**Steps:**

1. Navigate to `/users/register`
2. Enter weak password (less than 12 characters)
3. Fill other fields correctly
4. Submit form

**Expected Results:**

- Validation error: "should be at least 12 character(s)"
- Form not submitted
- Password field cleared or highlighted
- No user created

**Note:** Password must be 12-72 characters. No complexity requirements (uppercase/lowercase/numbers) are enforced by default but can be added.

---

### TC-UC-005: Create User with Missing Required Fields

**Objective:** Verify all required fields are validated.

**Test Cases:**

- Missing name
- Missing email
- Missing password

**Steps:**

1. Navigate to `/users/register`
2. Leave one required field empty
3. Fill other fields
4. Attempt to submit

**Expected Results:**

- Validation error for missing field: "can't be blank"
- Form not submitted
- No user created

---

## Test Suite 2: User Verification/Confirmation

### TC-UV-001: Verify User Email with Valid Token

**Objective:** Verify user can complete email confirmation successfully.

**Preconditions:**

- Registered user account
- Valid confirmation token available from email

**Steps:**

1. Register new user
2. Retrieve confirmation email from inbox/logs
3. Click confirmation link in email (format: `/users/confirm/:token`)
4. Observe confirmation page

**Expected Results:**

- Confirmation page displays success message: "User confirmed successfully."
- User `confirmed_at` field updated with timestamp in database
- Success message displayed
- User can continue using the application

---

### TC-UV-002: Verify User with Expired Token

**Objective:** Verify expired tokens are rejected.

**Preconditions:**

- Expired confirmation token (check UserToken validity period)

**Steps:**

1. Use expired confirmation token
2. Navigate to `/users/confirm/:expired_token`

**Expected Results:**

- Confirmation fails
- Error message: "User confirmation link is invalid or it has expired."
- User `confirmed_at` remains NULL
- User remains unconfirmed

---

### TC-UV-003: Verify User with Invalid Token

**Objective:** Verify invalid tokens are rejected.

**Test Data:**

- Invalid token: `invalid_token_123`

**Steps:**

1. Navigate to `/users/confirm/invalid_token_123`

**Expected Results:**

- Confirmation fails
- Error message: "User confirmation link is invalid or it has expired."
- No database changes

---

## Test Suite 3: User Login & Authentication

### TC-UL-001: Login with Valid Credentials

**Objective:** Verify user can log in with correct credentials.

**Preconditions:**

- Existing user in database

**Test Data:**

- Email: `testuser@example.com`
- Password: `ValidPassword123!`

**Steps:**

1. Navigate to `/users/log_in`
2. Enter valid email
3. Enter correct password
4. Click "Sign in" button

**Expected Results:**

- Login successful
- Success message: "Welcome back!"
- User session created
- Redirected to homepage `/`
- User menu shows logged-in state
- Access to protected routes granted

---

### TC-UL-002: Login with Invalid Password

**Objective:** Verify invalid credentials are rejected.

**Test Data:**

- Email: `testuser@example.com`
- Password: `WrongPassword123!`

**Steps:**

1. Navigate to `/users/log_in`
2. Enter valid email
3. Enter wrong password
4. Attempt login

**Expected Results:**

- Login fails
- Error message: "Invalid email or password!"
- User remains on login page
- No session created
- Failed attempt logged (check application logs)
- No enumeration of whether email exists

---

### TC-UL-003: Logout

**Objective:** Verify logout functionality.

**Preconditions:**

- User logged in

**Steps:**

1. Click logout button/link
2. Confirm logout

**Expected Results:**

- User session destroyed
- Redirected to homepage `/`
- No flash message displayed (silent logout)
- Access to protected routes denied
- User menu shows logged-out state

---

## Test Suite 4: User Settings & Profile Update

### TC-UU-001: Update User Email

**Objective:** Verify user can update email address (requires reverification).

**Preconditions:**

- Authenticated user session

**Test Data:**

- Current email: `oldmail@example.com`
- New email: `newemail@example.com`
- Current password: User's password for verification

**Steps:**

1. Log in as user
2. Navigate to `/users/settings`
3. In "Change Email" section, enter new email
4. Enter current password for verification
5. Click "Change Email"

**Expected Results:**

- Email update initiated
- Success message: "A link to confirm your email change has been sent to the new address."
- Verification email sent to NEW email address
- Email contains confirmation link
- Old email remains active until new email confirmed
- User `email` field unchanged until confirmation

---

### TC-UU-002: Confirm Email Update with Valid Token

**Objective:** Verify email update completion with valid token.

**Preconditions:**

- Email update initiated
- Valid confirmation token received

**Steps:**

1. Click confirmation link from new email address
2. Navigate to `/users/settings/confirm_email/:token`

**Expected Results:**

- Email updated successfully
- Success message: "Email changed successfully."
- User `email` field updated in database
- `confirmed_at` timestamp updated
- Redirected to `/users/settings`
- Old email no longer valid for login

---

### TC-UU-003: Update Password

**Objective:** Verify user can change password.

**Preconditions:**

- Authenticated user session

**Test Data:**

- Current password: `OldPassword123!`
- New password: `NewSecurePass456!`
- Password confirmation: `NewSecurePass456!`

**Steps:**

1. Log in as user
2. Navigate to `/users/settings`
3. In "Change Password" section:
   - Enter current password
   - Enter new password (12+ characters)
   - Confirm new password
4. Click "Change Password"

**Expected Results:**

- Password updated successfully
- Success message: "Password updated successfully!"
- User automatically re-authenticated with new password
- Password hashed with Bcrypt in database
- Old password no longer works
- User can log out and log in with new password

---

### TC-UU-004: Update Password with Wrong Current Password

**Objective:** Verify current password verification.

**Steps:**

1. Navigate to `/users/settings`
2. Enter wrong current password
3. Enter valid new password
4. Submit

**Expected Results:**

- Update fails
- Error message: "is not valid" under current password field
- No database changes
- User remains authenticated with old password

---

### TC-UU-005: Update Password with Mismatched Confirmation

**Objective:** Verify password confirmation matching.

**Steps:**

1. Navigate to `/users/settings`
2. Enter correct current password
3. Enter new password
4. Enter different password confirmation
5. Submit

**Expected Results:**

- Validation error: "does not match password"
- Form not submitted
- No database changes

---

## Test Suite 5: Password Reset Flow

### TC-PR-001: Request Password Reset

**Objective:** Verify password reset can be initiated.

**Test Data:**

- Email: `testuser@example.com`

**Steps:**

1. Navigate to `/users/reset_password`
2. Enter registered email address
3. Click "Send instructions to reset password"

**Expected Results:**

- Success message: "If your email is in our system, you will receive instructions to reset your password shortly."
- Password reset email sent to user
- Email contains reset link (format: `/users/reset_password/:token`)
- Token valid for limited time
- No indication whether email exists (security)

---

### TC-PR-002: Reset Password with Valid Token

**Objective:** Verify password can be reset using valid token.

**Preconditions:**

- Valid password reset token received

**Test Data:**

- New password: `ResetPassword123!`
- Password confirmation: `ResetPassword123!`

**Steps:**

1. Click reset link from email
2. Navigate to `/users/reset_password/:token`
3. Enter new password (12+ characters)
4. Confirm new password
5. Click "Reset Password"

**Expected Results:**

- Password reset successful
- Success message displayed
- User can log in with new password
- Old password no longer works
- Reset token invalidated
- Redirected to login page

---

### TC-PR-003: Reset Password with Expired Token

**Objective:** Verify expired reset tokens are rejected.

**Preconditions:**

- Expired reset token

**Steps:**

1. Attempt to use expired token URL

**Expected Results:**

- Error message: "Reset password link is invalid or it has expired."
- Password not changed
- User must request new reset link

---

## Test Suite 6: Payment Gateway API Integration

**Note:** This application is a landing/demo site that calls a separate Payment Gateway API.

### TC-API-001: Test Pay-In Request (Demo)

**Objective:** Verify pay-in transaction request works.

**Preconditions:**

- Logged in user with **active** account status (pending/blocked users cannot access the form)
- User has UUID and private key generated
- Payment Gateway API running on http://localhost:4100

**Test Data:**

- Provider: `bitpay`, `crypto_processing`, `mollie`, etc.
- Amount: `1.0`
- Currency: `BTC`, `EUR`, etc.
- Success URL: auto-filled with callback URL (read-only)
- Fail URL: auto-filled with callback URL (read-only)

**Steps:**

1. Log in
2. Navigate to `/test-gateway`
3. In the "Try it yourself" section, select endpoint "POST /transaction/pay-in"
4. In the pay-in form:
   - Select provider
   - Enter amount
   - Select currency (fiat or crypto, loaded dynamically per provider)
5. Click "Create Payment"

**Expected Results:**

- Request sent to Gateway API: `POST /api/transaction/pay-in`
- Request signed with user's private key
- Headers include: `KEY-ID` (user UUID), `SIGN` (signature)
- Response displayed with:
  - Status code (200)
  - Transaction status: `pending`
  - Payment URL: `pay_url`
  - Internal transaction ID
- Callback received via PubSub when transaction completes

---

### TC-API-002: Test Pay-Out Request (Demo)

**Objective:** Verify pay-out transaction request works.

**Preconditions:**

- Logged in user
- Gateway API accessible

**Test Data:**

- Provider: `crypto_processing`
- Currency: `BTC`
- Amount: `0.00001`
- Address: Valid crypto address
- Sender type: `legal` or `natural`
- Receiver type: `legal` or `natural`

**Steps:**

1. Navigate to `/test-gateway`
2. In the "Try it yourself" section, select endpoint "POST /transaction/pay-out"
3. Fill in payout details:
   - Provider, currency, amount, address
   - Sender information
   - Receiver information
4. Click "Create Payout"

**Expected Results:**

- Request sent: `POST /api/transaction/pay-out`
- Request properly signed
- Response contains:
  - Transaction status
  - Internal ID
  - Processing details
- Transaction logged

---

### TC-API-003: Get Transaction Status (Demo)

**Objective:** Verify transaction listing works.

**Preconditions:**

- Logged in user
- At least one transaction exists

**Test Data:**

- Query parameters: provider, status, type, date range

**Steps:**

1. Navigate to `/test-gateway`
2. In the "Try it yourself" section, select endpoint "GET /transactions"
3. Set filters (optional): status, currency, provider, type, date range, limit, offset
4. Click "Fetch Transactions"

**Expected Results:**

- Request sent: `GET /api/transactions`
- Response contains array of transactions
- Each transaction shows:
  - ID, status, amount, currency
  - User info, payment system
  - Timestamps
- Pagination info included

---

## Test Suite 7: Security Testing

### TC-SEC-001: CSRF Protection

**Objective:** Verify CSRF tokens protect forms.

**Steps:**

1. Inspect registration/login form HTML
2. Verify `csrf_token` hidden input exists
3. Attempt form submission without CSRF token (using curl/Postman)

**Expected Results:**

- All forms include CSRF token
- Requests without valid token rejected
- Error: 403 or validation error

---

### TC-SEC-002: SQL Injection Prevention

**Objective:** Verify Ecto protects against SQL injection.

**Test Data:**

- Email: `admin'--`
- Email: `'; DROP TABLE users;--`
- Search: `' OR '1'='1`

**Steps:**

1. Enter SQL injection patterns in email field
2. Attempt registration/login

**Expected Results:**

- Input safely escaped by Ecto
- No SQL errors
- No unauthorized data access
- Database intact
- Query logged safely

---

### TC-SEC-003: Password Storage Security

**Objective:** Verify passwords are securely hashed.

**Steps:**

1. Create new user
2. Query database directly: `SELECT hashed_password FROM users WHERE email = '...'`
3. Examine password hash

**Expected Results:**

- Password stored as Bcrypt hash
- Hash starts with `$2b$` (Bcrypt identifier)
- Original password not visible
- Each password has unique salt
- Password field not stored in plaintext anywhere

---

### TC-SEC-004: Session Security

**Objective:** Verify session tokens are secure.

**Steps:**

1. Log in and examine session cookie
2. Check cookie attributes
3. Attempt to use session after logout

**Expected Results:**

- Session cookie has `HttpOnly` flag
- `Secure` flag set in production
- `SameSite` attribute configured
- Session invalidated on logout
- Old session tokens don't work after logout

---

### TC-SEC-005: Authentication Required for Protected Routes

**Objective:** Verify route protection works.

**Test Protected Routes:**

- `/users/settings` - requires authentication (active status)
- `/users/info` - requires authentication (active status)

**Note:** `/users/settings/confirm_email/:token` is a **public** route and does NOT require authentication.

**Steps:**

1. Without logging in, navigate to protected route
2. Observe redirect

**Expected Results:**

- Unauthenticated users redirected to `/users/log_in`
- Flash message may appear
- After login, user redirected back to intended page
- Cannot access protected pages without auth

---

### TC-SEC-006: Private Key Security

**Objective:** Verify private keys are securely stored.

**Steps:**

1. Create new user
2. Check database: `SELECT priv_key_pem FROM users`
3. Verify key format and storage

**Expected Results:**

- Private key stored in PEM format
- Key marked as `redact: true` in schema (not logged)
- Key not exposed in API responses
- Key only accessible to user via settings
- Used for signing Gateway API requests

---

## Test Suite 8: Email Functionality

### TC-EMAIL-001: Registration Notification Email

**Objective:** Verify registration email is sent.

**Preconditions:**Manual

- Email service configured (Azure or local)

**Steps:**

1. Register new user
2. Check email inbox or logs

**Expected Results:**

- Email sent via Azure Email Service (or Swoosh local)
- Subject: "Payment Gateway - Registration Notification"
- Contains HTML content
- Body includes:
  - User's name
  - Welcome message
  - Account registered notification
- Email delivered within reasonable time (< 2 minutes)

---

### TC-EMAIL-002: Email Confirmation Instructions

**Objective:** Verify confirmation email is sent.

**Steps:**

1. After registration, check for confirmation email
2. Examine email content

**Expected Results:**

- Email sent with subject: "Confirmation instructions"
- Contains confirmation link
- Link format: `#{url}/users/confirm/#{token}`
- Instructions to confirm account
- Token embedded in URL

---

### TC-EMAIL-003: Password Reset Email

**Objective:** Verify password reset email.

**Steps:**

1. Request password reset
2. Check email

**Expected Results:**

- Email sent with subject: "Reset password instructions"
- Contains reset link
- Link format: `#{url}/users/reset_password/#{token}`
- Instructions on how to reset
- Security notice

---

### TC-EMAIL-004: Email Change Confirmation

**Objective:** Verify email change notification.

**Steps:**

1. Update email in settings
2. Check both old and new email addresses

**Expected Results:**

- Confirmation email sent to NEW email address
- Contains link to confirm change
- Instructions clear
- Old email may receive notification (optional)

---

### TC-EMAIL-005: Email Service Failure Handling

**Objective:** Verify graceful handling of email failures.

**Preconditions:**

- Simulate email service unavailability

**Steps:**

1. Disable email service temporarily
2. Attempt registration or password reset
3. Check application logs

**Expected Results:**

- User experience not severely degraded
- Error logged appropriately
- User sees success message (don't reveal email service status)
- Email queued for retry (if retry mechanism exists)
- No application crash

---

## Test Suite 9: Logging & Monitoring

### TC-LOG-001: User Registration Logging

**Objective:** Verify registration events are logged.

**Steps:**

1. Register new user
2. Check application logs

**Expected Results:**

- Log entry for registration
- Contains: timestamp, email hash (not plaintext), success/failure
- Metadata: `registration_attrs` (sanitized)
- Log level: INFO for success
- No sensitive data in logs

---

### TC-LOG-002: Authentication Logging

**Objective:** Verify login attempts are logged.

**Steps:**

1. Perform successful login
2. Perform failed login
3. Review logs

**Expected Results:**

- Successful login logged with:
  - Timestamp
  - User ID
  - Log message: "User login successful"
  - Level: INFO
- Failed login logged with:
  - Timestamp
  - Hashed email (SHA256)
  - Log message: "User login failed"
  - Level: WARNING
- No passwords in logs

---

### TC-LOG-003: Gateway API Request Logging

**Objective:** Verify API requests are logged.

**Steps:**

1. Make pay-in or pay-out request
2. Check logs

**Expected Results:**

- API requests logged:
  - Request type (pay-in/pay-out)
  - Status code
  - Success/failure
  - Error details (if failed)
- Sensitive data redacted
- Correlation IDs for tracing

---

## Test Execution Checklist

### Before Testing

- [ ] Database migrated and seeded
- [ ] Application running on correct port
- [ ] Gateway API running and accessible
- [ ] Email service configured
- [ ] Environment variables set
- [ ] Test data prepared

### During Testing

- [ ] Follow test steps exactly
- [ ] Document deviations
- [ ] Take screenshots of failures
- [ ] Record actual vs expected results
- [ ] Note response times
- [ ] Check database state after each test

### After Testing

- [ ] Log all defects found
- [ ] Attach evidence (screenshots, logs)
- [ ] Clean up test data
- [ ] Update test case status
- [ ] Generate test report

---

## Known Limitations & Future Features

**Not Yet Implemented:**

1. **Phone Number Field** - User schema has no phone field
2. **Email Verification Enforcement** - Users can log in before confirming email
3. **Rate Limiting** - No rate limiting on login/registration visible in code
4. **Payment Transaction History UI** - Demo only, no real transaction history page
5. ~~**Admin Dashboard**~~ - **Implemented**: Admin routes exist at `/admin/users` with user approval/blocking functionality and a content editor at `/admin/content_editor`
6. **2FA/MFA** - No two-factor authentication
7. **Account Deletion** - No self-service account deletion
8. **Profile Avatar/Image** - No user profile image support
9. **Transaction Webhooks** - Callbacks exist but webhook subscription UI not visible
10. **Multi-language Support** - Gettext configured but only English visible

**What IS Implemented:**
✅ User registration with name, email, password  
✅ Email/password authentication  
✅ Password reset flow  
✅ Email change with reverification  
✅ Password change (requires current password)  
✅ Email confirmation system  
✅ Private key generation for API auth  
✅ Gateway API integration (pay-in, pay-out, list)  
✅ Request signing with RSA private keys  
✅ CSRF protection  
✅ Bcrypt password hashing  
✅ Azure Email Service integration  
✅ Session management  
✅ Protected routes  
✅ Real-time updates via Phoenix PubSub  
✅ Responsive UI with TailwindCSS

**What providers are available**

The Payment Gateway supports the following payment providers:

**Pay-In Providers (Accept Payments):**

- **BitPay** - `bitpay` - Cryptocurrency payment processor
- **CryptoProcessing** - `crypto_processing` - Cryptocurrency payment gateway
- **Payment4** - `payment_four` - Payment processing service
- **Mollie** - `mollie` - European payment service provider
- **Adyen** - `adyen` - Global payment platform
- **BTCPay** - `btcpay` - Self-hosted Bitcoin payment processor
- **Fondy** - `fondy` - Payment gateway service
- **Dummy** - `dummy` - Test/dummy provider (for development/testing)

**Pay-Out Providers (Send Payments):**

- **CryptoProcessing** - `crypto_processing` - Cryptocurrency payment gateway (supports withdrawals)

**Note:** Each provider supports different currencies. Use the `GET /api/fetch_supported_currencies/:provider` endpoint to retrieve the list of supported currencies for a specific provider.

---

## Test Data

### User Test Accounts

```
# For manual creation during tests
Name: Test User
Email: testuser@example.com
Password: TestPassword123!

# Another test user
Name: Jane Doe
Email: janedoe@example.com
Password: JanePassword456!
```

### Gateway API Test Data

**Pay-In Test:**

```json
{
  "amount": 1.0,
  "currency": "BTC",
  "provider": "bitpay",
  "success_url": "https://example.com/success",
  "fail_url": "https://example.com/fail"
}
```

**Pay-Out Test:**

```json
{
  "provider": "crypto_processing",
  "currency": "BTC",
  "amount": 0.00001,
  "address": "bc1qexampleaddresstest",
  "sender_type": "natural",
  "sender_data": {
    "first_name": "John",
    "last_name": "Doe",
    "date_of_birth": "1990-01-01",
    "email": "john@example.com"
  }
}
```

---

## Contact and Support

**Development Team:** dev-team@company.com  
**Issue Tracker:** Create issues in project repository  
**Documentation:** README.md in project root

---

**Document Version:** 2.1 (Updated based on actual implementation)  
**Last Updated:** March 3, 2026  
**Based on Code Review:** lib/, config/, test/ directories
