40fc435bda
- Add DeleteSessionAsync to ISessionStore/SessionService (unpublish portfolio card, remove bot-created empty forum topic, update batch message). - Add DeleteSessionForCurrentUserAsync to AuthorizedSessionService with audit log. - Add delete button + confirmation dialog to GroupDetails.razor. - Extend dashboard Playwright tests with edit persistence and delete verification. - Update AuthorizedSessionServiceTests with delete authorization coverage. - Mark issue #150 as done in tests/e2e/README.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
141 lines
6.9 KiB
Markdown
141 lines
6.9 KiB
Markdown
# GmRelay E2E Tests
|
|
|
|
This module contains locally-run end-to-end tests for the GmRelay Telegram bot and Blazor/Web dashboard.
|
|
It is deliberately **not** wired into CI because it requires real Telegram infrastructure (MTProto user client) and a running Web instance.
|
|
|
|
## Status
|
|
|
|
Tracked as a Gitea milestone: [E2E Automation](https://git.codeanddice.ru/toutsu/GmRelayBot/issues?state=open&milestone=...) <!-- update milestone link manually -->
|
|
|
|
| Issue | Title | Status |
|
|
|-------|-------|--------|
|
|
| #144 | initData / Login Widget helper for mock Telegram auth | ✅ Done |
|
|
| #145 | Playwright tests for Blazor dashboard with mocked Telegram auth | ✅ Done |
|
|
| #146 | Telegram user client (MTProto) | ✅ Done |
|
|
| #147 | Automate group creation and bot invitation | ✅ Done |
|
|
| #148 | Scenario: /newsession from creation to publication | ✅ Done |
|
|
| #149 | Join/leave, waitlist, reschedule and notification scenarios | ✅ Done |
|
|
| #150 | Dashboard display and editing verification | ✅ Done |
|
|
| #151 | Console runner and cleanup | ⏳ Planned |
|
|
|
|
## Structure
|
|
|
|
```text
|
|
tests/e2e/
|
|
├── README.md
|
|
├── requirements.txt
|
|
├── .gitignore
|
|
├── helpers/
|
|
│ ├── telegram_init_data.py # Build valid Telegram auth payloads
|
|
│ ├── test_telegram_init_data.py # Self-contained sanity tests for the helper
|
|
│ └── __init__.py
|
|
├── dashboard/
|
|
│ ├── test_dashboard_auth_and_sessions.py # Playwright tests for the Blazor dashboard
|
|
│ └── __init__.py
|
|
└── runner/
|
|
├── GmRelay.E2E.Runner.csproj # C# console runner using WTelegramClient (MTProto)
|
|
├── Program.cs # Entry point for quick manual checks
|
|
├── TelegramUserClient.cs # Reusable MTProto user client wrapper
|
|
├── GroupSetupScenario.cs # Create group + invite bot + verify /start
|
|
├── NewSessionScenario.cs # Walk the /newsession wizard end-to-end
|
|
├── JoinLeaveWaitlistRescheduleScenario.cs # Join, waitlist, promotion, leave, reschedule, notifications
|
|
├── DatabaseAssertions.cs # Query PostgreSQL and seed fake participants
|
|
├── RunnerConfig.cs # Configuration model
|
|
├── .env.example # Required environment variables
|
|
├── .gitignore # Ignore .env and session files
|
|
└── packages.lock.json # Restored lock file for the runner project
|
|
```
|
|
|
|
## Install dependencies
|
|
|
|
### Python (dashboard tests)
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
pip install -r tests/e2e/requirements.txt
|
|
playwright install chromium
|
|
```
|
|
|
|
### C# runner (MTProto)
|
|
|
|
```bash
|
|
dotnet restore tests/e2e/runner/GmRelay.E2E.Runner.csproj
|
|
```
|
|
|
|
## Run helper tests
|
|
|
|
```bash
|
|
python tests/e2e/helpers/test_telegram_init_data.py
|
|
```
|
|
|
|
## Run Playwright dashboard tests
|
|
|
|
1. Start the Web dashboard (and PostgreSQL) locally. The fastest way:
|
|
```bash
|
|
dotnet run --project src/GmRelay.AppHost/GmRelay.AppHost.csproj
|
|
```
|
|
2. Export environment variables that match the running Web instance:
|
|
```bash
|
|
export GMRELAY_E2E_BASE_URL="http://localhost:8080"
|
|
export GMRELAY_E2E_BOT_TOKEN="<same-token-as-web>"
|
|
export GMRELAY_E2E_TELEGRAM_ID="9000000001"
|
|
export GMRELAY_E2E_DATABASE_URL="Host=localhost;Database=gmrelay;Username=postgres;Password=<password>"
|
|
```
|
|
3. Run the tests:
|
|
```bash
|
|
python tests/e2e/dashboard/test_dashboard_auth_and_sessions.py
|
|
```
|
|
|
|
## Run the MTProto user client runner
|
|
|
|
The runner logs in to a real Telegram user account, creates a supergroup, invites the test bot, sends `/start`, waits for a reply, and deletes the group.
|
|
|
|
1. Copy the example environment file and fill in real values:
|
|
```bash
|
|
cp tests/e2e/runner/.env.example tests/e2e/runner/.env
|
|
```
|
|
2. Edit `tests/e2e/runner/.env` with your Telegram `api_id`, `api_hash`, `phone_number`, the bot username/token, and Web URL.
|
|
3. Run:
|
|
```bash
|
|
dotnet run --project tests/e2e/runner/GmRelay.E2E.Runner.csproj
|
|
```
|
|
|
|
**Security notes:**
|
|
- Never commit `.env` or `*.session` files.
|
|
- Use a dedicated test Telegram account, never your personal or production account.
|
|
- The first run will prompt for the Telegram verification code (sent to the phone number).
|
|
- Subsequent runs reuse the persisted `.session` file.
|
|
|
|
## What the dashboard tests cover
|
|
|
|
- `test_dashboard_authenticates_and_shows_groups`
|
|
Builds a valid Mini App initData payload, posts it to `/auth/telegram-webapp`, and verifies that the Blazor home page renders the authenticated greeting.
|
|
- `test_dashboard_session_edit_flow`
|
|
Seeds a player, group, and session directly in PostgreSQL, opens the group details page, clicks through to the session editor, changes the title, join link, max players and publication mode, asserts the updated values appear on the page, and verifies the persisted database state.
|
|
- `test_dashboard_session_delete_flow`
|
|
Seeds a session, opens the group details page, confirms the deletion dialog, asserts the session disappears from the dashboard, and verifies the session was removed from PostgreSQL.
|
|
|
|
## What the MTProto runner currently covers
|
|
|
|
- Login as a Telegram user.
|
|
- Create a supergroup (`Channels_CreateChannel` with `megagroup: true`).
|
|
- Resolve a bot by username and invite it to the group.
|
|
- Send `/start` to the bot inside the group and wait for any reply.
|
|
- Walk `/newsession` from start to published schedule message.
|
|
- Join/leave a session via inline buttons and assert the database state.
|
|
- Join into a waitlist when the active roster is full (using a seeded fake participant).
|
|
- Manually promote a waitlisted player via `/listsessions` and verify promotion.
|
|
- Leave an active session and verify automatic promotion of the next waitlisted player.
|
|
- Initiate a reschedule, propose 2-3 time options, vote, and wait for the background deadline service to apply the new time.
|
|
- Exercise T-24h RSVP confirmation and T-5m join-link reminders by time-travelling `sessions.scheduled_at` from the runner (database-level time-mock).
|
|
- Delete the test supergroup after the scenario (cleanup).
|
|
|
|
## Notes
|
|
|
|
- Authentication is mocked using `helpers/telegram_init_data.py`, which mirrors `GmRelay.Shared.Telegram.TelegramAuthPayloadBuilder`.
|
|
- The Web instance validates HMAC-SHA256 with the same bot token, so the test payload is indistinguishable from a real Telegram Mini App payload.
|
|
- The runner project is intentionally **not** included in `GM-Relay.slnx` so it does not participate in CI builds or Native AOT trimming.
|
|
- The Telegram lifecycle scenario uses **one real test account** plus fake participants seeded directly into PostgreSQL, and a **database-level time-mock** (`UPDATE sessions SET scheduled_at = ...`) so 24-hour and 5-minute reminders fire in minutes instead of hours. This is the locally-runnable approach chosen for issue #149.
|
|
- For headful debugging, change `headless=True` to `headless=False` in the dashboard test file.
|