# 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 ``` `.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 ``` 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).*