201 lines
8.4 KiB
Markdown
201 lines
8.4 KiB
Markdown
# Protocole de test manuel sur téléphone — Swifty Companion
|
||
|
||
> **Objectif :** valider la partie obligatoire (et le bonus) **sur device** avant de figer la branche `soutenance` et le rendu Vogosphere.
|
||
> **Code :** `swiftyCompanion/swifty_companion/` · **Branche travail :** `main` · **Branche portable / rendu :** `soutenance`.
|
||
|
||
**Prérequis PC :**
|
||
|
||
```bash
|
||
cd swiftyCompanion/swifty_companion
|
||
flutter pub get && flutter analyze && flutter test
|
||
flutter devices
|
||
flutter run -d <id_téléphone>
|
||
```
|
||
|
||
`.env` dans `swifty_companion/.env` · OAuth Intra : scopes **public** + **projects** · redirect = `com.example.swiftycompanion://callback`.
|
||
|
||
---
|
||
|
||
## Réponses aux points soulevés (à lire avant de cocher)
|
||
|
||
### A — Déconnexion (icône logout) vs annulation OAuth
|
||
|
||
| Action | Comportement actuel | Faut-il un message « connexion annulée » ? |
|
||
|--------|---------------------|---------------------------------------------|
|
||
| **Annuler** dans le navigateur OAuth (pendant « Se connecter avec 42 ») | Message **« Connexion annulée »** | Déjà géré — `search_screen.dart` (`FlutterAppAuthUserCancelledException`). |
|
||
| **Déconnexion** (icône logout en haut à droite quand connecté) | Retour à l’écran **« Connecte-toi »** sans message | **Non obligatoire** au sujet. C’est une **déconnexion volontaire**, pas une annulation OAuth. Optionnel : SnackBar « Déconnecté » — pas requis pour valider. |
|
||
|
||
**Test A3** du protocole = annuler **pendant** le flux navigateur, pas appuyer sur logout.
|
||
|
||
### B3 — Champs profil : `hidden`, vide, ≥ 4 détails
|
||
|
||
Le sujet demande **au moins quatre détails** parmi login, email, mobile, level, location, wallet, evaluations, etc. **+ photo**.
|
||
|
||
| Ce que tu vois | Conforme ? |
|
||
|----------------|------------|
|
||
| Email affiché | Oui — compte comme 1 détail |
|
||
| Téléphone = **`hidden`** | Oui — c’est la **valeur renvoyée par l’API** (confidentialité), pas un bug |
|
||
| Niveau cursus affiché | Oui |
|
||
| Localisation vide → **`—`** | Oui — souvent pas de poste connecté / pas sur PC école ; encadré sujet confidentialité |
|
||
| Wallet (points) | Oui |
|
||
| **Login** + **photo** (en-tête) | Comptent aussi pour le critère |
|
||
|
||
Tu as **plus de 4 lignes utiles** même si certaines sont `hidden` ou `—`. **Pas besoin d’ajouter** d’autres champs (evaluation_points, etc.) sauf choix perso.
|
||
|
||
Autres champs possibles dans l’API (non requis) : `displayname`, `correction_point`, `pool_month`, … — le sujet ne impose pas de tout afficher.
|
||
|
||
### B4 — « Niveau entier » pour les skills
|
||
|
||
L’API envoie un niveau **décimal** (ex. `8.42`).
|
||
|
||
| Affichage app | Signification |
|
||
|---------------|----------------|
|
||
| **Niveau 8** | Partie **entière** (`floor`) — c’est le « niveau entier » du sujet |
|
||
| **(42 %)** | Partie décimale × 100 — le **pourcentage** du sujet |
|
||
|
||
Exemple ligne UI : `Algorithms — niveau 8 (42 %)`.
|
||
|
||
Code : `IntraProfileService._skillFromLevel` · affichage `_SkillsCard` dans `profile_screen.dart`.
|
||
|
||
Plusieurs skills affichés = **mieux** ; le sujet exige le **format** niveau + % sur les skills montrés.
|
||
|
||
### C5 — Profil ouvert + réseau coupé (cache)
|
||
|
||
| Comportement | Explication |
|
||
|--------------|-------------|
|
||
| Profil **déjà chargé** reste visible sans réseau | Cache mémoire ~2 min (`IntraProfileService`) + données déjà en RAM — **normal** |
|
||
| Erreur réseau au **retour** puis nouvelle recherche | Couvre le critère « erreur réseau » |
|
||
| Erreur + **Réessayer** si chargement profil échoue | Déjà implémenté (`_ErrorBody`) |
|
||
|
||
Le sujet **n’exige pas** un rafraîchissement automatique du profil quand le réseau tombe. Test **C5 = optionnel** (amélioration possible plus tard, pas bloquant soutenance).
|
||
|
||
### F — Après déconnexion
|
||
|
||
Comportement attendu et **correct** :
|
||
|
||
- Plus de session → écran **connexion OAuth** uniquement ;
|
||
- **Pas** de recherche tant que tu ne t’es pas reconnecté (`IntraNotAuthenticatedException` si tu forçais une recherche — l’UI masque le formulaire tant que déconnecté).
|
||
|
||
---
|
||
|
||
## Grille de test — à cocher sur le téléphone
|
||
|
||
Légende : **O** = OK · **N** = échec · **—** = non testé / optionnel
|
||
|
||
### Préparation
|
||
|
||
| ID | Vérification | O / N / — |
|
||
|----|--------------|-----------|
|
||
| P1 | `flutter test` vert sur la branche testée | |
|
||
| P2 | `.env` présent, app démarre sans erreur config | |
|
||
| P3 | App installée via `flutter run` (debug) | |
|
||
|
||
### A — OAuth
|
||
|
||
| ID | Action | Résultat attendu | O / N / — |
|
||
|----|--------|------------------|-----------|
|
||
| A1 | **Se connecter avec 42** (succès) | Session affichée, formulaire recherche visible | |
|
||
| A2 | **Déconnexion** (icône logout) | Écran connexion, **sans** message obligatoire | |
|
||
| A3 | Reconnecter, lancer OAuth puis **annuler** dans le navigateur | Message **« Connexion annulée »** (pas confondre avec A2) | |
|
||
| A4 | Reconnexion réussie | Session OK | |
|
||
|
||
### B — Parcours nominal
|
||
|
||
| ID | Action | Résultat attendu | O / N / — |
|
||
|----|--------|------------------|-----------|
|
||
| B1 | Recherche login valide | Écran profil | |
|
||
| B2 | Photo | Image visible (ou initiale si API sans URL — expliquer à l’oral) | |
|
||
| B3 | Carte informations | ≥ 4 lignes (email, tel même `hidden`, niveau, wallet, etc.) | |
|
||
| B4 | Skills | Au moins une ligne `niveau X (Y %)` | |
|
||
| B5 | Projets | Au moins un validé et idéalement un **failed** | |
|
||
| B6 | Retour arrière | Recherche, **toujours connecté** | |
|
||
| B7 | 2ᵉ recherche (autre login) | Profil sans nouveau OAuth | |
|
||
|
||
### C — Erreurs
|
||
|
||
| ID | Action | Résultat attendu | O / N / — |
|
||
|----|--------|------------------|-----------|
|
||
| C1 | Recherche login vide | Message « Saisis un login » | |
|
||
| C2 | `zzzzinvalid` | Message, pas de profil vide | |
|
||
| C3 | Mode avion → **rechercher** | Message réseau | |
|
||
| C4 | Réseau OK → recherche à nouveau | Profil OK | |
|
||
| C5 | *(Optionnel)* Profil ouvert → couper réseau | Données en cache OK ; pas exigé par le sujet | — |
|
||
|
||
### D — Layout
|
||
|
||
| ID | Action | Résultat attendu | O / N / — |
|
||
|----|--------|------------------|-----------|
|
||
| D1 | Rotation paysage (profil) | Lisible / 2 colonnes si large | |
|
||
| D2 | Clavier sur écran recherche | Scroll OK | |
|
||
|
||
### E — Bonus (optionnel)
|
||
|
||
| ID | Action | Résultat attendu | O / N / — |
|
||
|----|--------|------------------|-----------|
|
||
| E1 | DEBUG simuler token expiré | Message debug | |
|
||
| E2 | Rechercher ensuite | Profil sans navigateur OAuth | |
|
||
|
||
### F — Session (complément)
|
||
|
||
| ID | Action | Résultat attendu | O / N / — |
|
||
|----|--------|------------------|-----------|
|
||
| F1 | Déconnecté : pas de champ recherche utilisable | Uniquement bouton connexion | |
|
||
|
||
---
|
||
|
||
## Validation sujet (après grille)
|
||
|
||
| # | Critère | Validé si… | O / N |
|
||
|---|---------|------------|-------|
|
||
| 1 | 2 vues | B1, B6 | |
|
||
| 2 | Erreurs | C1–C4 (+ A3) | |
|
||
| 3 | Profil si login existe | C2 vs B1 | |
|
||
| 4 | 4 détails + photo | B2, B3 | |
|
||
| 5 | Skills niveau + % | B4 | |
|
||
| 6 | Projets + failed | B5 | |
|
||
| 7 | Retour vue 1 | B6 | |
|
||
| 8 | Layout | D1 ou D2 | |
|
||
| 9 | Un token | B7 | |
|
||
| Bonus | Refresh | E1–E2 | |
|
||
|
||
**Décision :** si tous les **O / N** obligatoires sont **O** → passer à la **mise à jour branche `soutenance`** (voir ci-dessous).
|
||
|
||
---
|
||
|
||
## Après validation manuelle — branche `soutenance`
|
||
|
||
1. `git checkout main` → `git push origin main` (si pas déjà fait).
|
||
2. Aligner `main` / `soutenance` si besoin (ex. un seul `.env.example` sur `main`).
|
||
3. `git checkout soutenance` → vérifier commit photo (`eaacef0` ou plus récent).
|
||
4. **Re-test sur `soutenance` :**
|
||
|
||
```bash
|
||
cd swiftyCompanion/swifty_companion
|
||
flutter pub get && flutter analyze && flutter test
|
||
flutter run -d <device>
|
||
```
|
||
|
||
5. Refaire **minimum** : A1, B1–B7, C2, B2 (photo).
|
||
6. `git push origin soutenance`.
|
||
|
||
---
|
||
|
||
## Améliorations **non** bloquantes (ne pas faire avant validation sauf si tu veux)
|
||
|
||
| Idée | Priorité |
|
||
|------|----------|
|
||
| SnackBar « Déconnecté » au logout | Cosmétique |
|
||
| Pull-to-refresh profil quand réseau revient | Hors sujet |
|
||
| Afficher `evaluation_points` | Optionnel sujet |
|
||
| Invalider cache profil à la perte réseau | Optionnel |
|
||
|
||
---
|
||
|
||
## Liens
|
||
|
||
- [fiche-soutenance-orale.md](fiche-soutenance-orale.md) — oral + repères code
|
||
- [etape-06-checklist-soutenance.md](etape-06-checklist-soutenance.md) — rendu Git
|
||
- [guide-soutenance-realisation.md](guide-soutenance-realisation.md) — sujet ↔ fichiers
|
||
|
||
*Dernière mise à jour : retours test device (logout, hidden, cache profil, skills).*
|