fix/refactor-test #8

Merged
adminoo merged 12 commits from fix/refactor-test into main 2026-08-15 20:41:24 +00:00
Owner

Summary

Fix lesson unlock flow, local auth, and schema. Add e2e CI, extract shared utilities, clean dead code. 92 tests passing.

Bug Fixes

  • Completing a lesson now unlocks the next lesson within the same unit
  • Completing all unit lessons unlocks the next unit and activates its first lesson (was staying locked)
  • Fix completed_lesson_count overflow (seed started at 1, not 0)
  • Auth rewritten to local-only — no backend dependency
  • Add missing password_hash and unlocked_at columns in native DB schema (v1→v2 migration)
  • _onContinue() awaits provider refresh before navigation instead of blind delay

Refactor

  • Extract 3-way duplicated _toEnumName()core/utils/enum_utils.dart
  • Extract 2-way duplicated _hashPassword()core/utils/hash_utils.dart
  • Extract 5-way duplicated DB→Entity mapping → data/mappers/ (4 files)
  • Remove dead code: api_client.dart, 2 unused use cases, 2 dead providers
  • Remove 6 unused dependencies: lottie, fl_chart, dio, intl, path_provider, http_mock_adapter
  • Replace magic numbers with AppConstants

Tests (79 → 92)

  • auth_repository_impl_test.dart (+10): signIn/signUp/signOut, hashing, duplicate email
  • gamification_service_test.dart (+3): next lesson unlock, next unit unlock, first lesson in new unit

CI/CD

  • ci.yml: fix sudo, add pub cache, upload coverage artifact
  • e2e.yml (new): Flutter web build → Chromium headless → Puppeteer — 7 assertions on PR
  • deploy.yml: pipeline gate — teste2edeploy

Files Changed

## Summary Fix lesson unlock flow, local auth, and schema. Add e2e CI, extract shared utilities, clean dead code. 92 tests passing. ### Bug Fixes - Completing a lesson now unlocks the next lesson within the same unit - Completing all unit lessons unlocks the next unit **and activates its first lesson** (was staying locked) - Fix `completed_lesson_count` overflow (seed started at 1, not 0) - Auth rewritten to local-only — no backend dependency - Add missing `password_hash` and `unlocked_at` columns in native DB schema (v1→v2 migration) - `_onContinue()` awaits provider refresh before navigation instead of blind delay ### Refactor - Extract 3-way duplicated `_toEnumName()` → `core/utils/enum_utils.dart` - Extract 2-way duplicated `_hashPassword()` → `core/utils/hash_utils.dart` - Extract 5-way duplicated DB→Entity mapping → `data/mappers/` (4 files) - Remove dead code: `api_client.dart`, 2 unused use cases, 2 dead providers - Remove 6 unused dependencies: `lottie`, `fl_chart`, `dio`, `intl`, `path_provider`, `http_mock_adapter` - Replace magic numbers with `AppConstants` ### Tests (79 → 92) - **`auth_repository_impl_test.dart`** (+10): signIn/signUp/signOut, hashing, duplicate email - **`gamification_service_test.dart`** (+3): next lesson unlock, next unit unlock, first lesson in new unit ### CI/CD - **`ci.yml`**: fix `sudo`, add pub cache, upload coverage artifact - **`e2e.yml`** (new): Flutter web build → Chromium headless → Puppeteer — 7 assertions on PR - **`deploy.yml`**: pipeline gate — `test` → `e2e` → `deploy` ### Files Changed
- Rewrite auth to local-only (no backend dependency)
- Fix lesson unlock: completing a lesson now unlocks next lesson in same unit
- Fix unit unlock: newly unlocked unit now also activates its first lesson
- Fix seed data: completed_lesson_count starts at 0 (was 1, causing overflow)
- Add password_hash column to native DB schema (v1→v2 migration)
- Add unlocked_at column to achievements table
- Fix _onContinue to await provider refresh before navigation
- Improve auth error messages (wrong password, duplicate email)
- Suppress dart:html deprecation in web database (web-only, required)
- Exclude server/ from flutter analyze (separate project)
- Fix test annotation: library directive for @TestOn

Analyze: 0 issues, Tests: 79/79 passing
Removed from pubspec.yaml:
- lottie (zero imports in codebase)
- fl_chart (zero imports in codebase)
- intl (zero imports in codebase)
- dio (only used in dead api_client.dart)
- path_provider (unused, sqflite provides getDatabasesPath)
- http_mock_adapter (only useful for dead dio tests)

Deleted:
- lib/data/datasources/remote/api_client.dart (dead code, no provider)

Analyze: 0 issues, Tests: 79/79 passing
New files:
- core/utils/enum_utils.dart — toEnumName() (was duplicated 3x)
- core/utils/hash_utils.dart — hashPassword() (was duplicated 2x)
- data/mappers/user_mapper.dart — userFromMap()
- data/mappers/lesson_mapper.dart — lessonFromMap()
- data/mappers/course_mapper.dart — unitFromMap(), courseFromMap()
- data/mappers/achievement_mapper.dart — achievementFromMap()

Updated files:
- providers.dart — uses mappers, removed inline DB→Entity mapping,
  removed dead providers (signInProvider, completeLessonProvider)
- auth_repository_impl.dart — uses hashPassword + userFromMap
- seed_data.dart — uses hashPassword
- lesson_repository_impl.dart — uses lessonFromMap
- user_repository_impl.dart — uses userFromMap
- course_repository_impl.dart — uses unitFromMap + courseFromMap

Analyze: 0 issues, Tests: 79/79 passing
Tests cover:
- signIn with correct/wrong credentials
- signIn with non-existent email
- signIn saves tokens and userId
- signUp creates user with correct fields
- signUp rejects duplicate email
- signUp stores password hash in DB
- signOut clears tokens
- getCurrentUser returns null/user

Uses _FakeAuthStorage extending AuthStorage for in-memory testing.
Total tests: 89 (was 79).
New tests:
- unlocks next lesson in same unit after completion
- unlocks next unit when all lessons completed
- unlocks first lesson in newly unlocked unit

Total tests: 92 (was 89).
Magic numbers replaced with AppConstants:
- hintXpPenaltyPercent (0.25 → 25% constant)
- xpPerLesson (50 → constant in profile)
- maxLives (5 → constant in setLives)
- dailyGoalTarget (1 → constant in home)
- maxContentWidth (600 → constant, added to AppConstants)

Dead code removed:
- domain/usecases/sign_in.dart (never used, auth screen uses repo directly)
- domain/usecases/complete_lesson.dart (never used, lesson screen uses gamification service)

Analyze: 0 issues, Tests: 92/92 passing
ci.yml:
- Add sudo for apt-get (ubuntu-latest)
- Add pub cache (actions/cache@v4)
- Add coverage artifact upload

e2e.yml (new):
- Builds Flutter web, serves it, runs Puppeteer e2e tests
- Installs Chromium + Node.js 22
- 7 assertions: lesson completion, unit unlock, UI visibility

deploy.yml:
- Split into test → e2e → deploy pipeline
- E2e must pass before deploy runs

e2e/:
- test-full.mjs: 3-lesson flow with assertions + exit code
- Configurable via CHROME_PATH and APP_URL env vars
chore: add node_modules to gitignore
Some checks failed
CI / validate (pull_request) Failing after 4s
E2E Tests / e2e (pull_request) Failing after 3s
09c9f766b0
fix: remove sudo
Some checks failed
CI / validate (pull_request) Failing after 19s
E2E Tests / e2e (pull_request) Failing after 20s
b91b74c8e3
ci: fix Forgejo runner compatibility
Some checks failed
CI / validate (pull_request) Successful in 4m12s
E2E Tests / e2e (pull_request) Failing after 4m7s
750a1e9579
- Remove actions/cache@v4 (unsupported by Forgejo runner)
- Remove actions/upload-artifact@v4 (unsupported)
- Remove actions/setup-node@v4 (node already in container)
- Remove sudo (container runs as root)
- Hardcode clone URL (no secrets.REPO_URL fallback)
- Add missing deps: xz-utils, zip, libglu1-mesa, chromium
fix: add package-lock.json for e2e npm ci, remove from gitignore
Some checks failed
E2E Tests / e2e (pull_request) Has been cancelled
CI / validate (pull_request) Has been cancelled
a2792b3152
fix: remove node_modules symlink from tracking
All checks were successful
CI / validate (pull_request) Successful in 4m7s
E2E Tests / e2e (pull_request) Successful in 5m6s
cadab729c6
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
adminoo/sysroadmap!8
No description provided.