this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

tests

alice af7b4692 f2789eca

+177 -1
+177 -1
index.test.ts
··· 20 20 } 21 21 22 22 document.body.innerHTML = ` 23 + <div id="addValueForm" class="modal" style="display: none;"> 24 + <div class="modal-content"> 25 + <h3>Add New Value</h3> 26 + <label for="newValueName">Value Name:</label> 27 + <input type="text" id="newValueName" required> 28 + <label for="newValueDesc">Description:</label> 29 + <textarea id="newValueDesc" rows="3"></textarea> 30 + <div class="modal-buttons"> 31 + <button id="saveNewValueBtn">Save</button> 32 + <button id="cancelNewValueBtn">Cancel</button> 33 + </div> 34 + </div> 35 + </div> 23 36 <div id="part1" class="exercise-part">Part 1 Content 24 37 <div data-column="unassigned"><div id="part1-unassignedContainer" class="card-container"></div></div> 25 38 <div data-column="veryImportant"><div id="part1-veryImportantContainer" class="card-container"></div></div> ··· 306 319 window.confirm = originalConfirm; 307 320 }); 308 321 322 + // --- Tests for Adding Custom Values --- 323 + test('saveNewValue adds a custom value card', () => { 324 + // Arrange: Need access to the private method or trigger via UI 325 + // We'll simulate the input values and call the method directly for simplicity 326 + const name = 'MY CUSTOM VALUE'; 327 + const description = 'This is important to me.'; 328 + (document.getElementById('newValueName') as HTMLInputElement).value = name; 329 + (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = description; 330 + const initialCardCount = app.undoManager.getState().cards.length; 331 + 332 + // Act 333 + (app as any).saveNewValue(); // Access private method for test 334 + 335 + // Assert 336 + const newState = app.undoManager.getState(); 337 + expect(newState.cards.length).toBe(initialCardCount + 1); 338 + const newCard = newState.cards[newState.cards.length - 1]; 339 + if (!newCard) throw new Error('Test failed: New card not found after add'); 340 + expect(newCard.name).toBe(name); 341 + expect(newCard.description).toBe(description); 342 + expect(newCard.isCustom).toBe(true); 343 + expect(newCard.column).toBe('unassigned'); 344 + expect(newCard.id).toBeLessThan(0); // Custom IDs are negative 345 + }); 346 + 347 + test('saveNewValue prevents duplicate names', () => { 348 + // Arrange: Add one custom card first 349 + const name = 'MY CUSTOM VALUE'; 350 + (document.getElementById('newValueName') as HTMLInputElement).value = name; 351 + (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = 'Desc 1'; 352 + (app as any).saveNewValue(); 353 + const stateAfterFirstAdd = app.undoManager.getState(); 354 + const cardCountAfterFirst = stateAfterFirstAdd.cards.length; 355 + 356 + // Act: Try to add another with the same name (case-insensitive) 357 + (document.getElementById('newValueName') as HTMLInputElement).value = name.toLowerCase(); 358 + (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = 'Desc 2'; 359 + (app as any).saveNewValue(); 360 + 361 + // Assert: State should not have changed, card count same 362 + const stateAfterSecondAttempt = app.undoManager.getState(); 363 + expect(stateAfterSecondAttempt.cards.length).toBe(cardCountAfterFirst); 364 + // Alert would have been called - we could spy on it if needed 365 + }); 366 + 367 + // --- Tests for Editing Descriptions --- 368 + test('startEditingDescription sets editingDescriptionCardId', () => { 369 + const cardToEditId = app.undoManager.getState().cards[0]!.id; // Use non-null assertion 370 + expect(app.undoManager.getState().editingDescriptionCardId).toBeNull(); 371 + 372 + // Act 373 + (app as any).startEditingDescription(cardToEditId); 374 + 375 + // Assert 376 + expect(app.undoManager.getState().editingDescriptionCardId).toBe(cardToEditId); 377 + }); 378 + 379 + test('saveDescriptionEdit updates card description and clears editingId', () => { 380 + // Arrange: Start editing the first card 381 + const cards = app.undoManager.getState().cards; 382 + const cardToEdit = cards[0]!; // Use non-null assertion 383 + if (!cardToEdit) throw new Error('Test setup failed: No cards found'); 384 + const cardId = cardToEdit.id; 385 + const originalDesc = cardToEdit.description || VALUES.find((v: {name: string}) => v.name === cardToEdit.name)?.description; 386 + const newDesc = 'My edited description.'; 387 + (app as any).startEditingDescription(cardId); 388 + 389 + // Act 390 + (app as any).saveDescriptionEdit(cardId, newDesc); 391 + 392 + // Assert 393 + const newState = app.undoManager.getState(); 394 + expect(newState.editingDescriptionCardId).toBeNull(); 395 + const updatedCard = newState.cards.find(c => c.id === cardId); 396 + if (!updatedCard) throw new Error('Test failed: Updated card not found'); 397 + expect(updatedCard.description).toBe(newDesc); 398 + // Ensure other card descriptions weren't affected (simple check) 399 + if (cards.length > 1) { 400 + const otherCard = newState.cards.find(c => c.id === cards[1]!.id); // Use non-null assertion 401 + if (!otherCard) throw new Error('Test setup failed: Second card not found'); 402 + expect(otherCard.description).not.toBe(newDesc); 403 + } 404 + }); 405 + 406 + test('cancelDescriptionEdit clears editingId without saving', () => { 407 + // Arrange: Start editing the first card 408 + const cards = app.undoManager.getState().cards; 409 + const cardToEdit = cards[0]!; // Use non-null assertion 410 + if (!cardToEdit) throw new Error('Test setup failed: No cards found'); 411 + const cardId = cardToEdit.id; 412 + const originalDesc = cardToEdit.description; // May be undefined initially 413 + (app as any).startEditingDescription(cardId); 414 + // Simulate typing something into the textarea (though it's not rendered here) 415 + 416 + // Act 417 + (app as any).cancelDescriptionEdit(); 418 + 419 + // Assert 420 + const newState = app.undoManager.getState(); 421 + expect(newState.editingDescriptionCardId).toBeNull(); 422 + const notUpdatedCard = newState.cards.find(c => c.id === cardId); 423 + if (!notUpdatedCard) throw new Error('Test failed: Card not found after cancel'); 424 + // Explicitly handle potential undefined originalDesc 425 + if (originalDesc === undefined) { 426 + expect(notUpdatedCard.description).toBeUndefined(); 427 + } else { 428 + expect(notUpdatedCard.description).toBe(originalDesc); 429 + } 430 + }); 431 + 432 + // --- Test Review Page Rendering with Custom/Edited Descriptions --- 433 + test('Review page renders custom and edited descriptions correctly', () => { 434 + // Arrange: 435 + // 1. Add a custom value 436 + const customName = 'CUSTOM VAL'; 437 + const customDesc = 'My custom description'; 438 + (document.getElementById('newValueName') as HTMLInputElement).value = customName; 439 + (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = customDesc; 440 + (app as any).saveNewValue(); 441 + 442 + // 2. Edit description of a built-in value (e.g., ACCEPTANCE) 443 + let state = app.undoManager.getState(); 444 + const builtInCard = state.cards.find(c => c.name === 'ACCEPTANCE')!; 445 + const builtInCardId = builtInCard.id; 446 + const editedBuiltInDesc = 'My edited acceptance'; 447 + (app as any).saveDescriptionEdit(builtInCardId, editedBuiltInDesc); 448 + 449 + // 3. Move cards to core/additional for review page 450 + state = app.undoManager.getState(); 451 + state.currentPart = 'review'; 452 + state.cards.forEach(card => { 453 + if (card.name === 'ACCEPTANCE' || card.name === customName) { 454 + card.column = 'core'; 455 + } else { 456 + card.column = 'additional'; // Move others somewhere else 457 + } 458 + }); 459 + app.updateState(state); 460 + app = new App(); // Re-render with final state 461 + 462 + // Act: Trigger render (implicitly done by new App() or manually if needed) 463 + // (app as any).render(); // Usually constructor calls render 464 + 465 + // Assert: Check the rendered HTML in the review section 466 + const reviewContent = document.getElementById('reviewContent'); 467 + expect(reviewContent).not.toBeNull(); 468 + const coreSection = reviewContent!.querySelector('.grid-section:first-child'); // Assuming core is first 469 + expect(coreSection).not.toBeNull(); 470 + 471 + const coreNames = Array.from(coreSection!.querySelectorAll('.review-value-name')).map(el => el.textContent); 472 + const coreDescs = Array.from(coreSection!.querySelectorAll('.review-value-description')).map(el => el.textContent); 473 + 474 + // Find the indices based on names (order might vary slightly if sorting changes) 475 + const acceptanceIndex = coreNames.indexOf('ACCEPTANCE'); 476 + const customIndex = coreNames.indexOf(customName); 477 + 478 + expect(acceptanceIndex).toBeGreaterThan(-1); 479 + expect(customIndex).toBeGreaterThan(-1); 480 + expect(coreDescs[acceptanceIndex]).toBe(editedBuiltInDesc); 481 + expect(coreDescs[customIndex]).toBe(customDesc); 482 + }); 483 + 309 484 // Add more tests for other transitions (Part 2 -> 3, 3 -> 4, etc.) 310 485 // Add tests for card movement logic (moveCard) 311 486 // Add tests for final statement input ··· 325 500 { id: 2, name: 'TEST2', column: 'unassigned', order: 1 }, 326 501 ], 327 502 finalStatements: {}, 328 - valueSet: 'limited' 503 + valueSet: 'limited', 504 + editingDescriptionCardId: null // Add missing property 329 505 }; 330 506 um = new UndoManager(initialState); 331 507 });