1// /checkout/cart/assets/js/cart-tester.js 2 3class CartTester { 4 constructor(cartManager, notificationCallback) { 5 this.cart = cartManager; 6 this.showNotification = notificationCallback || this.defaultNotification; 7 this.testArticleId = 17189; // ID par défaut 8 this.availableArticles = []; 9 10 this.init(); 11 } 12 13 init() { 14 this.loadAvailableArticles(); 15 } 16 17 // === GESTION DES ARTICLES DE TEST === 18 19 async loadAvailableArticles() { 20 if (!this.cart || !this.cart.api) { 21 console.warn('?? CartAPI non disponible pour charger les articles'); 22 return; 23 } 24 25 try { 26 this.showNotification('?? Chargement des articles disponibles...', 'info'); 27 28 const response = await this.cart.api.request('/articles'); 29 this.availableArticles = response || []; 30 31 if (this.availableArticles.length > 0) { 32 this.testArticleId = this.availableArticles[0].id_article; 33 this.updateTestSection(); 34 this.showNotification(`? ${this.availableArticles.length} articles trouvés`, 'success'); 35 } else { 36 this.showNotification('?? Aucun article disponible trouvé', 'warning'); 37 } 38 39 } catch (error) { 40 console.error('Erreur chargement articles:', error); 41 this.showNotification('? Impossible de charger les articles', 'error'); 42 } 43 } 44 45 updateTestSection() { 46 const testSection = document.querySelector('.test-section'); 47 if (!testSection) return; 48 49 // Supprimer l'ancienne section s'il y en a une 50 const existingInfo = document.getElementById('articles-info'); 51 if (existingInfo) { 52 existingInfo.remove(); 53 } 54 55 if (this.availableArticles.length > 0) { 56 // Créer la div conteneur 57 const articlesDiv = document.createElement('div'); 58 articlesDiv.id = 'articles-info'; 59 articlesDiv.style.cssText = 'margin: 15px 0; padding: 15px; background: #f8f9fa; border-radius: 8px; border: 1px solid #e9ecef;'; 60 61 // Créer le titre 62 const title = document.createElement('h4'); 63 title.style.cssText = 'margin: 0 0 10px 0; color: #495057;'; 64 title.textContent = '?? Articles de test disponibles'; 65 articlesDiv.appendChild(title); 66 67 // Créer le select 68 const select = document.createElement('select'); 69 select.id = 'articleSelect'; 70 select.style.cssText = 'margin: 8px 0; padding: 8px; width: 100%; border: 1px solid #ced4da; border-radius: 4px;'; 71 72 // Ajouter les options 73 this.availableArticles.forEach(art => { 74 const option = document.createElement('option'); 75 option.value = art.id_article; 76 option.textContent = `#${art.id_article} - ${art.designation || 'Article sans nom'} (${art.prix || '0'}â¬)`; 77 if (art.id_article == this.testArticleId) { 78 option.selected = true; 79 } 80 select.appendChild(option); 81 }); 82 83 // Ajouter l'événement change 84 select.addEventListener('change', (e) => { 85 this.changeTestArticle(e.target.value); 86 }); 87 88 articlesDiv.appendChild(select); 89 90 // Créer le paragraphe d'info 91 const info = document.createElement('p'); 92 info.style.cssText = 'margin: 5px 0 0 0; font-size: 14px; color: #6c757d;'; 93 info.innerHTML = `<strong>Article de test actuel :</strong> #${this.testArticleId}`; 94 articlesDiv.appendChild(info); 95 96 // Insérer après le paragraphe de description 97 const description = testSection.querySelector('p'); 98 if (description) { 99 description.parentNode.insertBefore(articlesDiv, description.nextSibling); 100 } 101 } 102 } 103 104 changeTestArticle(newArticleId) { 105 if (newArticleId) { 106 this.testArticleId = parseInt(newArticleId); 107 } else { 108 const select = document.getElementById('articleSelect'); 109 if (select) { 110 this.testArticleId = parseInt(select.value); 111 } 112 } 113 114 this.showNotification(`Article de test: #${this.testArticleId}`, 'info'); 115 116 // Mettre à jour l'affichage de l'article actuel 117 this.updateCurrentArticleDisplay(); 118 } 119 120 updateCurrentArticleDisplay() { 121 const infoDiv = document.getElementById('articles-info'); 122 if (infoDiv) { 123 const infoParagraph = infoDiv.querySelector('p'); 124 if (infoParagraph) { 125 infoParagraph.innerHTML = `<strong>Article de test actuel :</strong> #${this.testArticleId}`; 126 } 127 } 128 } 129 130 // === TESTS DU PANIER === 131 132 async testAddItem() { 133 if (!this.isCartReady()) return false; 134 135 this.showNotification(`Test ajout article #${this.testArticleId}...`, 'info'); 136 137 try { 138 const success = await this.cart.addItem(this.testArticleId, 1); 139 if (success) { 140 this.showNotification(`? Article #${this.testArticleId} ajouté avec succès`, 'success'); 141 return true; 142 } else { 143 this.showNotification(`? Ãchec ajout article #${this.testArticleId}`, 'error'); 144 return false; 145 } 146 } catch (error) { 147 console.error('Erreur test ajout:', error); 148 this.showNotification(`? Erreur: ${error.message}`, 'error'); 149 return false; 150 } 151 } 152 153 async testUpdateQuantity() { 154 if (!this.isCartReady()) return false; 155 156 const newQty = prompt(`Nouvelle quantité pour l'article #${this.testArticleId}:`, '2'); 157 158 if (newQty !== null && !isNaN(newQty) && parseInt(newQty) >= 0) { 159 try { 160 const quantity = parseInt(newQty); 161 const success = await this.cart.updateQuantity(this.testArticleId, quantity); 162 if (success) { 163 this.showNotification(`? Quantité modifiée pour #${this.testArticleId}`, 'success'); 164 return true; 165 } else { 166 this.showNotification(`? Ãchec modification #${this.testArticleId}`, 'error'); 167 return false; 168 } 169 } catch (error) { 170 console.error('Erreur test update:', error); 171 this.showNotification(`? Erreur: ${error.message}`, 'error'); 172 return false; 173 } 174 } else if (newQty !== null) { 175 this.showNotification('? Quantité invalide', 'error'); 176 } 177 return false; 178 } 179 180 async testRemoveItem() { 181 if (!this.isCartReady()) return false; 182 183 try { 184 const success = await this.cart.removeItem(this.testArticleId); 185 if (success) { 186 this.showNotification(`? Article #${this.testArticleId} supprimé`, 'success'); 187 return true; 188 } else { 189 this.showNotification(`? Ãchec suppression #${this.testArticleId}`, 'error'); 190 return false; 191 } 192 } catch (error) { 193 console.error('Erreur test remove:', error); 194 this.showNotification(`? Erreur: ${error.message}`, 'error'); 195 return false; 196 } 197 } 198 199 async testClearCart() { 200 if (!this.isCartReady()) return false; 201 202 try { 203 const success = await this.cart.clearCart(); 204 if (success) { 205 this.showNotification('? Panier vidé avec succès', 'success'); 206 return true; 207 } else { 208 this.showNotification('? Ãchec vidage du panier', 'error'); 209 return false; 210 } 211 } catch (error) { 212 console.error('Erreur test clear:', error); 213 this.showNotification(`? Erreur: ${error.message}`, 'error'); 214 return false; 215 } 216 } 217 218 // === TESTS TECHNIQUES === 219 220 async testApiConnection() { 221 if (!this.isCartReady()) return false; 222 223 this.showNotification('Test connexion API...', 'info'); 224 225 try { 226 const result = await this.cart.api.testConnection(); 227 if (result.connected) { 228 this.showNotification(`? API connectée (${result.latency}ms)`, 'success'); 229 return true; 230 } else { 231 this.showNotification(`? API déconnectée: ${result.error}`, 'error'); 232 return false; 233 } 234 } catch (error) { 235 console.error('Erreur test connexion:', error); 236 this.showNotification(`? Erreur test: ${error.message}`, 'error'); 237 return false; 238 } 239 } 240 241 testLocalStorage() { 242 try { 243 const testKey = 'cart_test_' + Date.now(); 244 const testValue = 'test_value'; 245 246 localStorage.setItem(testKey, testValue); 247 const retrieved = localStorage.getItem(testKey); 248 localStorage.removeItem(testKey); 249 250 if (retrieved === testValue) { 251 this.showNotification('? localStorage fonctionne parfaitement', 'success'); 252 return true; 253 } else { 254 this.showNotification('? localStorage ne fonctionne pas correctement', 'error'); 255 return false; 256 } 257 } catch (error) { 258 console.error('Erreur localStorage:', error); 259 this.showNotification('? localStorage non disponible', 'error'); 260 return false; 261 } 262 } 263 264 showCartInfo() { 265 if (!this.isCartReady()) return; 266 267 const cart = this.cart.cart; 268 const storage = this.cart.storage.getStorageInfo(); 269 270 const info = ` 271 <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; border: 1px solid #e9ecef;"> 272 <h5 style="margin: 0 0 10px 0; color: #495057;">?? Informations détaillées</h5> 273 <strong>Articles:</strong> ${cart.items.length}<br> 274 <strong>Quantité totale:</strong> ${cart.count}<br> 275 <strong>Total:</strong> ${cart.total.toFixed(2)}â¬<br> 276 <strong>SessionId:</strong> <code>${this.cart.sessionId}</code><br> 277 <strong>Storage disponible:</strong> ${storage && storage.used !== undefined ? 'Oui' : 'Non'}<br> 278 <strong>API URL:</strong> <code>${this.cart.api.baseUrl}</code><br> 279 <strong>Use Proxy:</strong> ${this.cart.api.useProxy ? 'Oui' : 'Non'}<br> 280 ${storage && storage.used !== undefined ? 281 `<strong>Storage utilisé:</strong> ${storage.used} éléments<br>` : '' 282 } 283 </div> 284 `; 285 286 const detailsElement = document.getElementById('cart-details'); 287 if (detailsElement) { 288 detailsElement.innerHTML = info; 289 } 290 291 this.showNotification('?? Informations détaillées affichées', 'info'); 292 } 293 294 // === TESTS AUTOMATISÃS === 295 296 async runAllTests() { 297 if (!this.isCartReady()) return false; 298 299 console.log('?? Démarrage de la suite de tests complète'); 300 this.showNotification('?? Démarrage des tests automatisés...', 'info'); 301 302 const results = { 303 apiConnection: false, 304 localStorage: false, 305 addItem: false, 306 updateQuantity: false, 307 removeItem: false, 308 clearCart: false 309 }; 310 311 try { 312 // Test 1: Connexion API 313 results.apiConnection = await this.testApiConnection(); 314 await this.delay(500); 315 316 // Test 2: localStorage 317 results.localStorage = this.testLocalStorage(); 318 await this.delay(500); 319 320 // Test 3: Ajouter un article 321 results.addItem = await this.testAddItem(); 322 await this.delay(1000); 323 324 // Test 4: Modifier la quantité 325 if (results.addItem) { 326 results.updateQuantity = await this.cart.updateQuantity(this.testArticleId, 3); 327 await this.delay(1000); 328 } 329 330 // Test 5: Supprimer l'article 331 if (results.updateQuantity) { 332 results.removeItem = await this.testRemoveItem(); 333 await this.delay(1000); 334 } 335 336 // Test 6: Vider le panier 337 results.clearCart = await this.testClearCart(); 338 339 // Résumé 340 const successCount = Object.values(results).filter(r => r).length; 341 const totalTests = Object.keys(results).length; 342 343 if (successCount === totalTests) { 344 this.showNotification(`?? Tous les tests réussis (${successCount}/${totalTests})`, 'success'); 345 } else { 346 this.showNotification(`?? Tests partiels (${successCount}/${totalTests} réussis)`, 'warning'); 347 } 348 349 return results; 350 351 } catch (error) { 352 console.error('Erreur suite de tests:', error); 353 this.showNotification('? Erreur lors des tests automatisés', 'error'); 354 return results; 355 } 356 } 357 358 // === UTILITAIRES === 359 360 isCartReady() { 361 if (!this.cart) { 362 this.showNotification('? CartManager non disponible', 'error'); 363 return false; 364 } 365 366 if (!this.cart.cart) { 367 this.showNotification('? Panier non initialisé', 'error'); 368 return false; 369 } 370 371 return true; 372 } 373 374 delay(ms) { 375 return new Promise(resolve => setTimeout(resolve, ms)); 376 } 377 378 defaultNotification(message, type) { 379 console.log(`[${type.toUpperCase()}] ${message}`); 380 } 381 382 // === GETTERS === 383 384 get currentTestArticle() { 385 return this.availableArticles.find(art => art.id_article === this.testArticleId) || null; 386 } 387 388 get cartSummary() { 389 if (!this.isCartReady()) return null; 390 391 const cart = this.cart.cart; 392 return { 393 itemCount: cart.items.length, 394 totalQuantity: cart.count, 395 totalAmount: cart.total, 396 sessionId: this.cart.sessionId, 397 isLoading: this.cart.isLoading 398 }; 399 } 400} 401 402// Export global pour compatibilité 403window.CartTester = CartTester;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.