fix: extra frontend tests
This commit is contained in:
		
							parent
							
								
									9af2f136eb
								
							
						
					
					
						commit
						1d84d60737
					
				
					 5 changed files with 195 additions and 38 deletions
				
			
		|  | @ -90,11 +90,6 @@ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     function saveRandomGroups(): void { |     function saveRandomGroups(): void { | ||||||
|         if (randomGroupsPreview.value.length === 0) { |  | ||||||
|             alert(t("please-generate-groups-first")); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         emit( |         emit( | ||||||
|             "groupsUpdated", |             "groupsUpdated", | ||||||
|             randomGroupsPreview.value.map((g) => g.map((s) => s.username)), |             randomGroupsPreview.value.map((g) => g.map((s) => s.username)), | ||||||
|  | @ -104,11 +99,11 @@ | ||||||
|         emit("close"); |         emit("close"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     function addNewGroup() { |     function addNewGroup(): void { | ||||||
|         currentGroups.value.push([]); |         currentGroups.value.push([]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     function removeGroup(index: number) { |     function removeGroup(index: number): void { | ||||||
|         // Move students back to unassigned |         // Move students back to unassigned | ||||||
|         unassignedStudents.value.push(...currentGroups.value[index]); |         unassignedStudents.value.push(...currentGroups.value[index]); | ||||||
|         currentGroups.value.splice(index, 1); |         currentGroups.value.splice(index, 1); | ||||||
|  | @ -317,11 +312,6 @@ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     function saveDragDrop(): void { |     function saveDragDrop(): void { | ||||||
|         if (unassignedStudents.value.length > 0) { |  | ||||||
|             alert(t("please-assign-all-students")); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         emit( |         emit( | ||||||
|             "groupsUpdated", |             "groupsUpdated", | ||||||
|             currentGroups.value.map((g) => g.map((s) => s.username)), |             currentGroups.value.map((g) => g.map((s) => s.username)), | ||||||
|  | @ -331,9 +321,7 @@ | ||||||
|         emit("close"); |         emit("close"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const showGroupsPreview = computed(() => { |     const showGroupsPreview = computed(() => currentGroups.value.length > 0 || unassignedStudents.value.length > 0); | ||||||
|         return currentGroups.value.length > 0 || unassignedStudents.value.length > 0; |  | ||||||
|     }); |  | ||||||
| 
 | 
 | ||||||
|     function removeStudent(groupIndex: number, student: StudentItem): void { |     function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
|         const group = currentGroups.value[groupIndex]; |         const group = currentGroups.value[groupIndex]; | ||||||
|  |  | ||||||
|  | @ -1,17 +0,0 @@ | ||||||
| /** |  | ||||||
|  * Validation rule for the assignment title. |  | ||||||
|  * |  | ||||||
|  * Ensures that the title is not empty. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Validation rule for the classes selection. |  | ||||||
|  * |  | ||||||
|  * Ensures that at least one class is selected. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Validation rule for the deadline field. |  | ||||||
|  * |  | ||||||
|  * Ensures that a valid deadline is selected and is in the future. |  | ||||||
|  */ |  | ||||||
|  | @ -1,10 +1,59 @@ | ||||||
| import { describe, expect, it } from "vitest"; | import { describe, it, expect, beforeEach } from "vitest"; | ||||||
| import { ClassController } from "../../src/controllers/classes"; | import { ClassController } from "../../src/controllers/classes"; | ||||||
| 
 | 
 | ||||||
| describe("Test controller classes", () => { | describe("ClassController Tests", () => { | ||||||
|     it("Get classes", async () => { |     let controller: ClassController; | ||||||
|         const controller = new ClassController(); |     const testClassId = "X2J9QT"; | ||||||
|         const data = await controller.getAll(true); | 
 | ||||||
|         expect(data.classes).to.have.length.greaterThan(0); |     beforeEach(() => { | ||||||
|  |         controller = new ClassController(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should fetch all classes", async () => { | ||||||
|  |         const result = await controller.getAll(true); | ||||||
|  |         expect(result).toHaveProperty("classes"); | ||||||
|  |         expect(Array.isArray(result.classes)).toBe(true); | ||||||
|  |         expect(result.classes.length).toBeGreaterThan(0); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should fetch a class by ID", async () => { | ||||||
|  |         const result = await controller.getById(testClassId); | ||||||
|  |         expect(result).toHaveProperty("class"); | ||||||
|  |         expect(result.class).toHaveProperty("id", testClassId); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     it("should fetch students for a class", async () => { | ||||||
|  |         const result = await controller.getStudents(testClassId, true); | ||||||
|  |         expect(result).toHaveProperty("students"); | ||||||
|  |         expect(Array.isArray(result.students)).toBe(true); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should fetch teachers for a class", async () => { | ||||||
|  |         const result = await controller.getTeachers(testClassId, true); | ||||||
|  |         expect(result).toHaveProperty("teachers"); | ||||||
|  |         expect(Array.isArray(result.teachers)).toBe(true); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should fetch teacher invitations for a class", async () => { | ||||||
|  |         const result = await controller.getTeacherInvitations(testClassId, true); | ||||||
|  |         expect(result).toHaveProperty("invitations"); | ||||||
|  |         expect(Array.isArray(result.invitations)).toBe(true); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should fetch assignments for a class", async () => { | ||||||
|  |         const result = await controller.getAssignments(testClassId, true); | ||||||
|  |         expect(result).toHaveProperty("assignments"); | ||||||
|  |         expect(Array.isArray(result.assignments)).toBe(true); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should handle fetching a non-existent class", async () => { | ||||||
|  |         const nonExistentId = "NON_EXISTENT_ID"; | ||||||
|  |         await expect(controller.getById(nonExistentId)).rejects.toThrow(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should handle deleting a non-existent class", async () => { | ||||||
|  |         const nonExistentId = "NON_EXISTENT_ID"; | ||||||
|  |         await expect(controller.deleteClass(nonExistentId)).rejects.toThrow(); | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								frontend/tests/utils/array-utils.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								frontend/tests/utils/array-utils.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | ||||||
|  | import {copyArrayWith} from "../../src/utils/array-utils"; | ||||||
|  | import { describe, it, expect } from "vitest"; | ||||||
|  | 
 | ||||||
|  | describe('copyArrayWith', () => { | ||||||
|  |     it('should replace the element at the specified index', () => { | ||||||
|  |         const original = [1, 2, 3, 4]; | ||||||
|  |         const result = copyArrayWith(2, 99, original); | ||||||
|  |         expect(result).toEqual([1, 2, 99, 4]); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should not modify the original array', () => { | ||||||
|  |         const original = ['a', 'b', 'c']; | ||||||
|  |         const result = copyArrayWith(1, 'x', original); | ||||||
|  |         expect(original).toEqual(['a', 'b', 'c']); // Original remains unchanged
 | ||||||
|  |         expect(result).toEqual(['a', 'x', 'c']); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should handle replacing the first element', () => { | ||||||
|  |         const original = [true, false, true]; | ||||||
|  |         const result = copyArrayWith(0, false, original); | ||||||
|  |         expect(result).toEqual([false, false, true]); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should handle replacing the last element', () => { | ||||||
|  |         const original = ['apple', 'banana', 'cherry']; | ||||||
|  |         const result = copyArrayWith(2, 'date', original); | ||||||
|  |         expect(result).toEqual(['apple', 'banana', 'date']); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should work with complex objects', () => { | ||||||
|  |         const original = [{ id: 1 }, { id: 2 }, { id: 3 }]; | ||||||
|  |         const newValue = { id: 99 }; | ||||||
|  |         const result = copyArrayWith(1, newValue, original); | ||||||
|  |         expect(result).toEqual([{ id: 1 }, { id: 99 }, { id: 3 }]); | ||||||
|  |         expect(original[1].id).toBe(2); // Original remains unchanged
 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     it('should allow setting to undefined', () => { | ||||||
|  |         const original = [1, 2, 3]; | ||||||
|  |         const result = copyArrayWith(1, undefined, original); | ||||||
|  |         expect(result).toEqual([1, undefined, 3]); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('should allow setting to null', () => { | ||||||
|  |         const original = [1, 2, 3]; | ||||||
|  |         const result = copyArrayWith(1, null, original); | ||||||
|  |         expect(result).toEqual([1, null, 3]); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
							
								
								
									
										87
									
								
								frontend/tests/utils/assignment-utils.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								frontend/tests/utils/assignment-utils.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | ||||||
|  | import {LearningPathNode} from "@dwengo-1/backend/dist/entities/content/learning-path-node.entity"; | ||||||
|  | import {calculateProgress} from "../../src/utils/assignment-utils"; | ||||||
|  | import {LearningPath} from "../../src/data-objects/learning-paths/learning-path"; | ||||||
|  | import { describe, it, expect } from "vitest"; | ||||||
|  | 
 | ||||||
|  | describe("calculateProgress", () => { | ||||||
|  |     it("should return 0 when no nodes are completed", () => { | ||||||
|  |         const lp = new LearningPath({ | ||||||
|  |             language: "en", | ||||||
|  |             hruid: "test-path", | ||||||
|  |             title: "Test Path", | ||||||
|  |             description: "Test Description", | ||||||
|  |             amountOfNodes: 10, | ||||||
|  |             amountOfNodesLeft: 10, | ||||||
|  |             keywords: ["test"], | ||||||
|  |             targetAges: { min: 10, max: 15 }, | ||||||
|  |             startNode: {} as LearningPathNode, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(calculateProgress(lp)).toBe(0); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should return 100 when all nodes are completed", () => { | ||||||
|  |         const lp = new LearningPath({ | ||||||
|  |             language: "en", | ||||||
|  |             hruid: "test-path", | ||||||
|  |             title: "Test Path", | ||||||
|  |             description: "Test Description", | ||||||
|  |             amountOfNodes: 10, | ||||||
|  |             amountOfNodesLeft: 0, | ||||||
|  |             keywords: ["test"], | ||||||
|  |             targetAges: { min: 10, max: 15 }, | ||||||
|  |             startNode: {} as LearningPathNode, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(calculateProgress(lp)).toBe(100); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should return 50 when half of the nodes are completed", () => { | ||||||
|  |         const lp = new LearningPath({ | ||||||
|  |             language: "en", | ||||||
|  |             hruid: "test-path", | ||||||
|  |             title: "Test Path", | ||||||
|  |             description: "Test Description", | ||||||
|  |             amountOfNodes: 10, | ||||||
|  |             amountOfNodesLeft: 5, | ||||||
|  |             keywords: ["test"], | ||||||
|  |             targetAges: { min: 10, max: 15 }, | ||||||
|  |             startNode: {} as LearningPathNode, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(calculateProgress(lp)).toBe(50); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it("should handle floating point progress correctly", () => { | ||||||
|  |         const lp = new LearningPath({ | ||||||
|  |             language: "en", | ||||||
|  |             hruid: "test-path", | ||||||
|  |             title: "Test Path", | ||||||
|  |             description: "Test Description", | ||||||
|  |             amountOfNodes: 3, | ||||||
|  |             amountOfNodesLeft: 1, | ||||||
|  |             keywords: ["test"], | ||||||
|  |             targetAges: { min: 10, max: 15 }, | ||||||
|  |             startNode: {} as LearningPathNode, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(calculateProgress(lp)).toBeCloseTo(66.666, 2); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     it("should handle edge case where amountOfNodesLeft is negative", () => { | ||||||
|  |         const lp = new LearningPath({ | ||||||
|  |             language: "en", | ||||||
|  |             hruid: "test-path", | ||||||
|  |             title: "Test Path", | ||||||
|  |             description: "Test Description", | ||||||
|  |             amountOfNodes: 10, | ||||||
|  |             amountOfNodesLeft: -5, | ||||||
|  |             keywords: ["test"], | ||||||
|  |             targetAges: { min: 10, max: 15 }, | ||||||
|  |             startNode: {} as LearningPathNode, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(calculateProgress(lp)).toBe(150); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana