# Guide de Test avec Postman - Xpeditis API ## 📩 Importer la Collection Postman ### Option 1 : Importer le fichier JSON 1. Ouvrez Postman 2. Cliquez sur **"Import"** (en haut Ă  gauche) 3. SĂ©lectionnez le fichier : `postman/Xpeditis_API.postman_collection.json` 4. Cliquez sur **"Import"** ### Option 2 : Collection créée manuellement La collection contient **13 requĂȘtes** organisĂ©es en 3 dossiers : - **Rates API** (4 requĂȘtes) - **Bookings API** (6 requĂȘtes) - **Health & Status** (1 requĂȘte) --- ## 🚀 Avant de Commencer ### 1. DĂ©marrer les Services ```bash # Terminal 1 : PostgreSQL # Assurez-vous que PostgreSQL est dĂ©marrĂ© # Terminal 2 : Redis redis-server # Terminal 3 : Backend API cd apps/backend npm run dev ``` L'API sera disponible sur : **http://localhost:4000** ### 2. Configurer les Variables d'Environnement La collection utilise les variables suivantes : | Variable | Valeur par dĂ©faut | Description | |----------|-------------------|-------------| | `baseUrl` | `http://localhost:4000` | URL de base de l'API | | `rateQuoteId` | (auto) | ID du tarif (sauvegardĂ© automatiquement) | | `bookingId` | (auto) | ID de la rĂ©servation (auto) | | `bookingNumber` | (auto) | NumĂ©ro de rĂ©servation (auto) | **Note :** Les variables `rateQuoteId`, `bookingId` et `bookingNumber` sont automatiquement sauvegardĂ©es aprĂšs les requĂȘtes correspondantes. --- ## 📋 ScĂ©nario de Test Complet ### Étape 1 : Rechercher des Tarifs Maritimes **RequĂȘte :** `POST /api/v1/rates/search` **Dossier :** Rates API → Search Rates - Rotterdam to Shanghai **Corps de la requĂȘte :** ```json { "origin": "NLRTM", "destination": "CNSHA", "containerType": "40HC", "mode": "FCL", "departureDate": "2025-02-15", "quantity": 2, "weight": 20000, "isHazmat": false } ``` **Codes de port courants :** - `NLRTM` - Rotterdam, Pays-Bas - `CNSHA` - Shanghai, Chine - `DEHAM` - Hamburg, Allemagne - `USLAX` - Los Angeles, États-Unis - `SGSIN` - Singapore - `USNYC` - New York, États-Unis - `GBSOU` - Southampton, Royaume-Uni **Types de conteneurs :** - `20DRY` - Conteneur 20 pieds standard - `20HC` - Conteneur 20 pieds High Cube - `40DRY` - Conteneur 40 pieds standard - `40HC` - Conteneur 40 pieds High Cube (le plus courant) - `40REEFER` - Conteneur 40 pieds rĂ©frigĂ©rĂ© - `45HC` - Conteneur 45 pieds High Cube **RĂ©ponse attendue (200 OK) :** ```json { "quotes": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "carrierId": "...", "carrierName": "Maersk Line", "carrierCode": "MAERSK", "origin": { "code": "NLRTM", "name": "Rotterdam", "country": "Netherlands" }, "destination": { "code": "CNSHA", "name": "Shanghai", "country": "China" }, "pricing": { "baseFreight": 1500.0, "surcharges": [ { "type": "BAF", "description": "Bunker Adjustment Factor", "amount": 150.0, "currency": "USD" } ], "totalAmount": 1700.0, "currency": "USD" }, "containerType": "40HC", "mode": "FCL", "etd": "2025-02-15T10:00:00Z", "eta": "2025-03-17T14:00:00Z", "transitDays": 30, "route": [...], "availability": 85, "frequency": "Weekly" } ], "count": 5, "fromCache": false, "responseTimeMs": 234 } ``` **✅ Tests automatiques :** - VĂ©rifie le status code 200 - VĂ©rifie la prĂ©sence du tableau `quotes` - VĂ©rifie le temps de rĂ©ponse < 3s - **Sauvegarde automatiquement le premier `rateQuoteId`** pour l'Ă©tape suivante **💡 Note :** Le `rateQuoteId` est **indispensable** pour crĂ©er une rĂ©servation ! --- ### Étape 2 : CrĂ©er une RĂ©servation **RequĂȘte :** `POST /api/v1/bookings` **Dossier :** Bookings API → Create Booking **PrĂ©requis :** Avoir exĂ©cutĂ© l'Ă©tape 1 pour obtenir un `rateQuoteId` **Corps de la requĂȘte :** ```json { "rateQuoteId": "{{rateQuoteId}}", "shipper": { "name": "Acme Corporation", "address": { "street": "123 Main Street", "city": "Rotterdam", "postalCode": "3000 AB", "country": "NL" }, "contactName": "John Doe", "contactEmail": "john.doe@acme.com", "contactPhone": "+31612345678" }, "consignee": { "name": "Shanghai Imports Ltd", "address": { "street": "456 Trade Avenue", "city": "Shanghai", "postalCode": "200000", "country": "CN" }, "contactName": "Jane Smith", "contactEmail": "jane.smith@shanghai-imports.cn", "contactPhone": "+8613812345678" }, "cargoDescription": "Electronics and consumer goods for retail distribution", "containers": [ { "type": "40HC", "containerNumber": "ABCU1234567", "vgm": 22000, "sealNumber": "SEAL123456" } ], "specialInstructions": "Please handle with care. Delivery before 5 PM." } ``` **RĂ©ponse attendue (201 Created) :** ```json { "id": "550e8400-e29b-41d4-a716-446655440001", "bookingNumber": "WCM-2025-ABC123", "status": "draft", "shipper": {...}, "consignee": {...}, "cargoDescription": "Electronics and consumer goods for retail distribution", "containers": [ { "id": "...", "type": "40HC", "containerNumber": "ABCU1234567", "vgm": 22000, "sealNumber": "SEAL123456" } ], "specialInstructions": "Please handle with care. Delivery before 5 PM.", "rateQuote": { "id": "550e8400-e29b-41d4-a716-446655440000", "carrierName": "Maersk Line", "origin": {...}, "destination": {...}, "pricing": {...} }, "createdAt": "2025-02-15T10:00:00Z", "updatedAt": "2025-02-15T10:00:00Z" } ``` **✅ Tests automatiques :** - VĂ©rifie le status code 201 - VĂ©rifie la prĂ©sence de `id` et `bookingNumber` - VĂ©rifie le format du numĂ©ro : `WCM-YYYY-XXXXXX` - VĂ©rifie que le statut initial est `draft` - **Sauvegarde automatiquement `bookingId` et `bookingNumber`** **Statuts de rĂ©servation possibles :** - `draft` → Brouillon (modifiable) - `pending_confirmation` → En attente de confirmation transporteur - `confirmed` → ConfirmĂ© par le transporteur - `in_transit` → En transit - `delivered` → LivrĂ© (Ă©tat final) - `cancelled` → AnnulĂ© (Ă©tat final) --- ### Étape 3 : Consulter une RĂ©servation par ID **RequĂȘte :** `GET /api/v1/bookings/{{bookingId}}` **Dossier :** Bookings API → Get Booking by ID **PrĂ©requis :** Avoir exĂ©cutĂ© l'Ă©tape 2 Aucun corps de requĂȘte nĂ©cessaire. Le `bookingId` est automatiquement utilisĂ© depuis les variables d'environnement. **RĂ©ponse attendue (200 OK) :** MĂȘme structure que la crĂ©ation --- ### Étape 4 : Consulter une RĂ©servation par NumĂ©ro **RequĂȘte :** `GET /api/v1/bookings/number/{{bookingNumber}}` **Dossier :** Bookings API → Get Booking by Booking Number **PrĂ©requis :** Avoir exĂ©cutĂ© l'Ă©tape 2 Exemple de numĂ©ro : `WCM-2025-ABC123` **Avantage :** Format plus convivial que l'UUID pour les utilisateurs finaux. --- ### Étape 5 : Lister les RĂ©servations avec Pagination **RequĂȘte :** `GET /api/v1/bookings?page=1&pageSize=20` **Dossier :** Bookings API → List Bookings (Paginated) **ParamĂštres de requĂȘte :** - `page` : NumĂ©ro de page (dĂ©faut : 1) - `pageSize` : Nombre d'Ă©lĂ©ments par page (dĂ©faut : 20, max : 100) - `status` : Filtrer par statut (optionnel) **Exemples d'URLs :** ``` GET /api/v1/bookings?page=1&pageSize=20 GET /api/v1/bookings?page=2&pageSize=10 GET /api/v1/bookings?page=1&pageSize=20&status=draft GET /api/v1/bookings?status=confirmed ``` **RĂ©ponse attendue (200 OK) :** ```json { "bookings": [ { "id": "...", "bookingNumber": "WCM-2025-ABC123", "status": "draft", "shipperName": "Acme Corporation", "consigneeName": "Shanghai Imports Ltd", "originPort": "NLRTM", "destinationPort": "CNSHA", "carrierName": "Maersk Line", "etd": "2025-02-15T10:00:00Z", "eta": "2025-03-17T14:00:00Z", "totalAmount": 1700.0, "currency": "USD", "createdAt": "2025-02-15T10:00:00Z" } ], "total": 25, "page": 1, "pageSize": 20, "totalPages": 2 } ``` --- ## ❌ Tests d'Erreurs ### Test 1 : Code de Port Invalide **RequĂȘte :** Rates API → Search Rates - Invalid Port Code (Error) **Corps de la requĂȘte :** ```json { "origin": "INVALID", "destination": "CNSHA", "containerType": "40HC", "mode": "FCL", "departureDate": "2025-02-15" } ``` **RĂ©ponse attendue (400 Bad Request) :** ```json { "statusCode": 400, "message": [ "Origin must be a valid 5-character UN/LOCODE (e.g., NLRTM)" ], "error": "Bad Request" } ``` --- ### Test 2 : Validation de RĂ©servation **RequĂȘte :** Bookings API → Create Booking - Validation Error **Corps de la requĂȘte :** ```json { "rateQuoteId": "invalid-uuid", "shipper": { "name": "A", "address": { "street": "123", "city": "R", "postalCode": "3000", "country": "INVALID" }, "contactName": "J", "contactEmail": "invalid-email", "contactPhone": "123" }, "consignee": {...}, "cargoDescription": "Short", "containers": [] } ``` **RĂ©ponse attendue (400 Bad Request) :** ```json { "statusCode": 400, "message": [ "Rate quote ID must be a valid UUID", "Name must be at least 2 characters", "Contact email must be a valid email address", "Contact phone must be a valid international phone number", "Country must be a valid 2-letter ISO country code", "Cargo description must be at least 10 characters" ], "error": "Bad Request" } ``` --- ## 📊 Variables d'Environnement Postman ### Configuration RecommandĂ©e 1. CrĂ©ez un **Environment** nommĂ© "Xpeditis Local" 2. Ajoutez les variables suivantes : | Variable | Type | Valeur Initiale | Valeur Courante | |----------|------|-----------------|-----------------| | `baseUrl` | default | `http://localhost:4000` | `http://localhost:4000` | | `rateQuoteId` | default | (vide) | (auto-rempli) | | `bookingId` | default | (vide) | (auto-rempli) | | `bookingNumber` | default | (vide) | (auto-rempli) | 3. SĂ©lectionnez l'environnement "Xpeditis Local" dans Postman --- ## 🔍 Tests Automatiques IntĂ©grĂ©s Chaque requĂȘte contient des **tests automatiques** dans l'onglet "Tests" : ```javascript // Exemple de tests intĂ©grĂ©s pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); pm.test("Response has quotes array", function () { var jsonData = pm.response.json(); pm.expect(jsonData).to.have.property('quotes'); pm.expect(jsonData.quotes).to.be.an('array'); }); // Sauvegarde automatique de variables pm.environment.set("rateQuoteId", pm.response.json().quotes[0].id); ``` **Voir les rĂ©sultats :** - Onglet **"Test Results"** aprĂšs chaque requĂȘte - Indicateurs ✅ ou ❌ pour chaque test --- ## 🚹 DĂ©pannage ### Erreur : "Cannot connect to server" **Cause :** Le serveur backend n'est pas dĂ©marrĂ© **Solution :** ```bash cd apps/backend npm run dev ``` VĂ©rifiez que vous voyez : `[Nest] Application is running on: http://localhost:4000` --- ### Erreur : "rateQuoteId is not defined" **Cause :** Vous essayez de crĂ©er une rĂ©servation sans avoir recherchĂ© de tarif **Solution :** ExĂ©cutez d'abord **"Search Rates - Rotterdam to Shanghai"** --- ### Erreur 500 : "Internal Server Error" **Cause possible :** 1. Base de donnĂ©es PostgreSQL non dĂ©marrĂ©e 2. Redis non dĂ©marrĂ© 3. Variables d'environnement manquantes **Solution :** ```bash # VĂ©rifier PostgreSQL psql -U postgres -h localhost # VĂ©rifier Redis redis-cli ping # Devrait retourner: PONG # VĂ©rifier les variables d'environnement cat apps/backend/.env ``` --- ### Erreur 404 : "Not Found" **Cause :** L'ID ou le numĂ©ro de rĂ©servation n'existe pas **Solution :** VĂ©rifiez que vous avez créé une rĂ©servation avant de la consulter --- ## 📈 Utilisation AvancĂ©e ### ExĂ©cuter Toute la Collection 1. Cliquez sur les **"..."** Ă  cĂŽtĂ© du nom de la collection 2. SĂ©lectionnez **"Run collection"** 3. SĂ©lectionnez les requĂȘtes Ă  exĂ©cuter 4. Cliquez sur **"Run Xpeditis API"** **Ordre recommandĂ© :** 1. Search Rates - Rotterdam to Shanghai 2. Create Booking 3. Get Booking by ID 4. Get Booking by Booking Number 5. List Bookings (Paginated) --- ### Newman (CLI Postman) Pour automatiser les tests en ligne de commande : ```bash # Installer Newman npm install -g newman # ExĂ©cuter la collection newman run postman/Xpeditis_API.postman_collection.json \ --environment postman/Xpeditis_Local.postman_environment.json # Avec rapport HTML newman run postman/Xpeditis_API.postman_collection.json \ --reporters cli,html \ --reporter-html-export newman-report.html ``` --- ## 📚 Ressources SupplĂ©mentaires ### Documentation API ComplĂšte Voir : `apps/backend/docs/API.md` ### Codes de Port UN/LOCODE Liste complĂšte : https://unece.org/trade/cefact/unlocode-code-list-country-and-territory **Codes courants :** - Europe : NLRTM (Rotterdam), DEHAM (Hamburg), GBSOU (Southampton) - Asie : CNSHA (Shanghai), SGSIN (Singapore), HKHKG (Hong Kong) - AmĂ©rique : USLAX (Los Angeles), USNYC (New York), USHOU (Houston) ### Classes IMO (Marchandises Dangereuses) 1. Explosifs 2. Gaz 3. Liquides inflammables 4. Solides inflammables 5. Substances comburantes 6. Substances toxiques 7. MatiĂšres radioactives 8. Substances corrosives 9. MatiĂšres dangereuses diverses --- ## ✅ Checklist de Test - [ ] Recherche de tarifs Rotterdam → Shanghai - [ ] Recherche de tarifs avec autres ports - [ ] Recherche avec marchandises dangereuses - [ ] Test de validation (code port invalide) - [ ] CrĂ©ation de rĂ©servation complĂšte - [ ] Consultation par ID - [ ] Consultation par numĂ©ro de rĂ©servation - [ ] Liste paginĂ©e (page 1) - [ ] Liste avec filtre de statut - [ ] Test de validation (rĂ©servation invalide) - [ ] VĂ©rification des tests automatiques - [ ] Temps de rĂ©ponse acceptable (<3s pour recherche) --- **Version :** 1.0 **DerniĂšre mise Ă  jour :** FĂ©vrier 2025 **Statut :** Phase 1 MVP - Tests Fonctionnels