From 5156689e138a202e9f8f1abf7b71085f9246a7bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Eduardo=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Thu, 8 Jan 2026 00:31:16 -0500 Subject: [PATCH] fix(frontend): enforce no-explicit-any and fix test stability - Change ESLint no-explicit-any from 'warn' to 'error' - Replace 'any' with 'unknown as string' in initials.pipe.spec - Fix StudentService tests to handle Apollo watchQuery multiple emissions - Add filter for loading state before asserting in tests Stricter type checking improves code quality. --- src/frontend/eslint.config.mjs | 2 +- .../app/core/services/student.service.spec.ts | 22 +++++++++++++++---- .../app/shared/pipes/initials.pipe.spec.ts | 5 +++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/frontend/eslint.config.mjs b/src/frontend/eslint.config.mjs index baaed4e..cb6df02 100644 --- a/src/frontend/eslint.config.mjs +++ b/src/frontend/eslint.config.mjs @@ -25,7 +25,7 @@ export default [ ...tseslint.configs.recommended.rules, "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-explicit-any": "error", "@angular-eslint/directive-selector": ["error", { type: "attribute", prefix: "app", style: "camelCase" }], "@angular-eslint/component-selector": ["error", { type: "element", prefix: "app", style: "kebab-case" }], }, diff --git a/src/frontend/src/app/core/services/student.service.spec.ts b/src/frontend/src/app/core/services/student.service.spec.ts index ebcc0a0..305f035 100644 --- a/src/frontend/src/app/core/services/student.service.spec.ts +++ b/src/frontend/src/app/core/services/student.service.spec.ts @@ -1,5 +1,6 @@ import { TestBed } from '@angular/core/testing'; import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing'; +import { filter, take } from 'rxjs'; import { StudentService } from './student.service'; import { GET_STUDENTS, GET_STUDENT } from '@core/graphql/queries/students.queries'; import { CREATE_STUDENT, DELETE_STUDENT } from '@core/graphql/mutations/students.mutations'; @@ -29,7 +30,11 @@ describe('StudentService', () => { { id: 2, name: 'María García', email: 'maria@test.com', totalCredits: 3, enrollments: [] }, ]; - service.getStudents().subscribe((result) => { + // Filter for the response with data (loading = false) + service.getStudents().pipe( + filter(result => !result.loading && result.data.length > 0), + take(1) + ).subscribe((result) => { expect(result.data).toEqual(mockStudents); done(); }); @@ -40,7 +45,10 @@ describe('StudentService', () => { }); it('should return empty array when no students', (done) => { - service.getStudents().subscribe((result) => { + service.getStudents().pipe( + filter(result => !result.loading), + take(1) + ).subscribe((result) => { expect(result.data).toEqual([]); done(); }); @@ -57,7 +65,10 @@ describe('StudentService', () => { totalCredits: 6, enrollments: [] }; - service.getStudent(1).subscribe((result) => { + service.getStudent(1).pipe( + filter(result => !result.loading && result.data !== null), + take(1) + ).subscribe((result) => { expect(result.data).toEqual(mockStudent); done(); }); @@ -68,7 +79,10 @@ describe('StudentService', () => { }); it('should return null when student not found', (done) => { - service.getStudent(999).subscribe((result) => { + service.getStudent(999).pipe( + filter(result => !result.loading), + take(1) + ).subscribe((result) => { expect(result.data).toBeNull(); done(); }); diff --git a/src/frontend/src/app/shared/pipes/initials.pipe.spec.ts b/src/frontend/src/app/shared/pipes/initials.pipe.spec.ts index a8b1991..9d0a962 100644 --- a/src/frontend/src/app/shared/pipes/initials.pipe.spec.ts +++ b/src/frontend/src/app/shared/pipes/initials.pipe.spec.ts @@ -28,8 +28,9 @@ describe('InitialsPipe', () => { }); it('should handle null-like values', () => { - expect(pipe.transform(null as any)).toBe(''); - expect(pipe.transform(undefined as any)).toBe(''); + // Test runtime safety for edge cases (null/undefined passed from templates) + expect(pipe.transform(null as unknown as string)).toBe(''); + expect(pipe.transform(undefined as unknown as string)).toBe(''); }); it('should uppercase initials', () => {