Skip to content

Commit a626e75

Browse files
committed
fix: resolve unhandled errors in test suite
- Fix NG0205 injector destroyed in profile-news and news-detail specs by removing unnecessary detectChanges and adding afterEach cleanup - Fix stack overflow in stage-one and stage-two specs by mocking OnboardingService and ProfileInfoService - Fix route mismatch in onboarding and confirm-email specs by mocking OnboardingService (EMPTY) and TokenService - Fix source is not a function in projects-filter spec by using signal() instead of Observable for IndustryRepositoryPort mock - Fix flaky timestamp assertions in use-case specs by using expect.objectContaining() instead of exact Date comparison
1 parent a850eee commit a626e75

12 files changed

Lines changed: 64 additions & 17 deletions

projects/social_platform/src/app/api/project/use-cases/add-project-subscription.use-case.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { of, throwError } from "rxjs";
55
import { AddProjectSubscriptionUseCase } from "./add-project-subscription.use-case";
66
import { ProjectSubscriptionRepositoryPort } from "@domain/project/ports/project-subscription.repository.port";
77
import { EventBus } from "@domain/shared/event-bus";
8-
import { projectSubscribed } from "@domain/project/events/project-subscribed.event";
98

109
describe("AddProjectSubscriptionUseCase", () => {
1110
let useCase: AddProjectSubscriptionUseCase;
@@ -41,7 +40,12 @@ describe("AddProjectSubscriptionUseCase", () => {
4140

4241
useCase.execute(7).subscribe(result => {
4342
expect(result.ok).toBe(true);
44-
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(projectSubscribed(7));
43+
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(
44+
expect.objectContaining({
45+
type: "ProjectSubscribed",
46+
payload: { projectId: 7 },
47+
}),
48+
);
4549
done();
4650
});
4751
}));

projects/social_platform/src/app/api/project/use-cases/create-project.use-case.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { CreateProjectUseCase } from "./create-project.use-case";
66
import { ProjectRepositoryPort } from "@domain/project/ports/project.repository.port";
77
import { Project } from "@domain/project/project.model";
88
import { EventBus } from "@domain/shared/event-bus";
9-
import { projectCreated } from "@domain/project/events/project-created.event";
109

1110
describe("CreateProjectUseCase", () => {
1211
let useCase: CreateProjectUseCase;
@@ -44,7 +43,12 @@ describe("CreateProjectUseCase", () => {
4443
useCase.execute().subscribe(result => {
4544
expect(result.ok).toBe(true);
4645
if (result.ok) expect(result.value).toBe(project);
47-
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(projectCreated(project));
46+
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(
47+
expect.objectContaining({
48+
type: "ProjectCreated",
49+
payload: { projectId: 1, project },
50+
}),
51+
);
4852
done();
4953
});
5054
}));

projects/social_platform/src/app/api/project/use-cases/delete-project-subscription.use-case.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { of, throwError } from "rxjs";
55
import { DeleteProjectSubscriptionUseCase } from "./delete-project-subscription.use-case";
66
import { ProjectSubscriptionRepositoryPort } from "@domain/project/ports/project-subscription.repository.port";
77
import { EventBus } from "@domain/shared/event-bus";
8-
import { projectUnSubscribed } from "@domain/project/events/project-unsubsribed.event";
98

109
describe("DeleteProjectSubscriptionUseCase", () => {
1110
let useCase: DeleteProjectSubscriptionUseCase;
@@ -41,7 +40,12 @@ describe("DeleteProjectSubscriptionUseCase", () => {
4140

4241
useCase.execute(7).subscribe(result => {
4342
expect(result.ok).toBe(true);
44-
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(projectUnSubscribed(7));
43+
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(
44+
expect.objectContaining({
45+
type: "ProjectUnSubscribed",
46+
payload: { projectId: 7 },
47+
}),
48+
);
4549
done();
4650
});
4751
}));

projects/social_platform/src/app/api/project/use-cases/delete-project.use-case.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { of, throwError } from "rxjs";
55
import { DeleteProjectUseCase } from "./delete-project.use-case";
66
import { ProjectRepositoryPort } from "@domain/project/ports/project.repository.port";
77
import { EventBus } from "@domain/shared/event-bus";
8-
import { projectDeleted } from "@domain/project/events/project-deleted.event";
98

109
describe("DeleteProjectUseCase", () => {
1110
let useCase: DeleteProjectUseCase;
@@ -41,7 +40,12 @@ describe("DeleteProjectUseCase", () => {
4140

4241
useCase.execute(7).subscribe(result => {
4342
expect(result.ok).toBe(true);
44-
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(projectDeleted(7));
43+
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(
44+
expect.objectContaining({
45+
type: "ProjectDeleted",
46+
payload: { projectId: 7 },
47+
}),
48+
);
4549
done();
4650
});
4751
}));

projects/social_platform/src/app/api/project/use-cases/remove-project-collaborator.use-case.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { of, throwError } from "rxjs";
55
import { RemoveProjectCollaboratorUseCase } from "./remove-project-collaborator.use-case";
66
import { ProjectCollaboratorsRepositoryPort } from "@domain/project/ports/project-collaborators.repository.port";
77
import { EventBus } from "@domain/shared/event-bus";
8-
import { removeProjectCollaborator } from "@domain/project/events/remove-project-collaborator.event";
98

109
describe("RemoveProjectCollaboratorUseCase", () => {
1110
let useCase: RemoveProjectCollaboratorUseCase;
@@ -42,7 +41,12 @@ describe("RemoveProjectCollaboratorUseCase", () => {
4241
useCase.execute(1, 42).subscribe(result => {
4342
expect(result.ok).toBe(true);
4443
if (result.ok) expect(result.value).toBe(42);
45-
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(removeProjectCollaborator(1, 42));
44+
expect(bus.emit).toHaveBeenCalledExactlyOnceWith(
45+
expect.objectContaining({
46+
type: "RemoveProjectCollaborator",
47+
payload: { projectId: 1, userId: 42 },
48+
}),
49+
);
4650
done();
4751
});
4852
}));

projects/social_platform/src/app/ui/pages/auth/confirm-email/confirm-email.component.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { HttpClientTestingModule } from "@angular/common/http/testing";
99
import { AuthRepositoryPort } from "@domain/auth/ports/auth.repository.port";
1010
import { of } from "rxjs";
1111
import { API_URL, PRODUCTION } from "@corelib";
12+
import { TokenService } from "@corelib";
1213

1314
describe("ConfirmEmailComponent", () => {
1415
let component: ConfirmEmailComponent;
@@ -25,12 +26,14 @@ describe("ConfirmEmailComponent", () => {
2526
fetchLeaderProjects: of({} as any),
2627
resendEmail: of({} as any),
2728
};
29+
const tokenSpy = { getTokens: vi.fn().mockReturnValue(null), memTokens: vi.fn() };
2830

2931
await TestBed.configureTestingModule({
3032
imports: [ConfirmEmailComponent, HttpClientTestingModule],
3133
providers: [
3234
{ provide: AuthRepository, useValue: authSpy },
3335
{ provide: AuthRepositoryPort, useValue: authPortSpy },
36+
{ provide: TokenService, useValue: tokenSpy },
3437
{ provide: API_URL, useValue: "" },
3538
{ provide: PRODUCTION, useValue: false },
3639
provideRouter([]),

projects/social_platform/src/app/ui/pages/onboarding/onboarding.component.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { ComponentFixture, TestBed } from "@angular/core/testing";
44

55
import { OnboardingComponent } from "./onboarding.component";
66
import { provideRouter } from "@angular/router";
7-
import { of } from "rxjs";
7+
import { EMPTY, of } from "rxjs";
88
import { AuthRepository } from "@infrastructure/repository/auth/auth.repository";
99
import { HttpClientTestingModule } from "@angular/common/http/testing";
1010
import { AuthRepositoryPort } from "@domain/auth/ports/auth.repository.port";
11+
import { OnboardingService } from "@api/onboarding/onboarding.service";
1112

1213
describe("OnboardingComponent", () => {
1314
let component: OnboardingComponent;
@@ -24,11 +25,14 @@ describe("OnboardingComponent", () => {
2425
fetchChangeableRoles: of([]),
2526
};
2627

28+
const onboardingSpy = { currentStage$: EMPTY };
29+
2730
await TestBed.configureTestingModule({
2831
imports: [OnboardingComponent, HttpClientTestingModule],
2932
providers: [
3033
{ provide: AuthRepository, useValue: authSpy },
3134
{ provide: AuthRepositoryPort, useValue: authPortSpy },
35+
{ provide: OnboardingService, useValue: onboardingSpy },
3236
provideRouter([]),
3337
],
3438
}).compileComponents();

projects/social_platform/src/app/ui/pages/onboarding/stage-one/stage-one.component.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
import { ComponentFixture, TestBed } from "@angular/core/testing";
44

55
import { OnboardingStageOneComponent } from "./stage-one.component";
6-
import { of } from "rxjs";
6+
import { EMPTY, of } from "rxjs";
77
import { ReactiveFormsModule } from "@angular/forms";
88
import { AuthRepository } from "@infrastructure/repository/auth/auth.repository";
99
import { provideRouter } from "@angular/router";
1010
import { HttpClientTestingModule } from "@angular/common/http/testing";
1111
import { AuthRepositoryPort } from "@domain/auth/ports/auth.repository.port";
1212
import { SkillsRepositoryPort } from "@domain/skills/ports/skills.repository.port";
1313
import { SpecializationsRepositoryPort } from "@domain/specializations/ports/specializations.repository.port";
14+
import { OnboardingService } from "@api/onboarding/onboarding.service";
15+
import { ProfileInfoService } from "@api/profile/facades/profile-info.service";
16+
import { signal } from "@angular/core";
1417

1518
describe("StageOneComponent", () => {
1619
let component: OnboardingStageOneComponent;
@@ -40,13 +43,17 @@ describe("StageOneComponent", () => {
4043
getSpecializationsInline: of({ count: 0, results: [], next: "", previous: "" }),
4144
};
4245

46+
const onboardingSpy = { formValue$: EMPTY, setFormValue: () => {} };
47+
4348
await TestBed.configureTestingModule({
4449
imports: [ReactiveFormsModule, HttpClientTestingModule, OnboardingStageOneComponent],
4550
providers: [
4651
{ provide: AuthRepository, useValue: authSpy },
4752
{ provide: AuthRepositoryPort, useValue: authPortSpy },
4853
{ provide: SkillsRepositoryPort, useValue: skillsSpy },
4954
{ provide: SpecializationsRepositoryPort, useValue: specializationsSpy },
55+
{ provide: OnboardingService, useValue: onboardingSpy },
56+
{ provide: ProfileInfoService, useValue: { profile: signal(null) } },
5057
provideRouter([]),
5158
],
5259
}).compileComponents();

projects/social_platform/src/app/ui/pages/onboarding/stage-two/stage-two.component.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
import { ComponentFixture, TestBed } from "@angular/core/testing";
44

55
import { OnboardingStageTwoComponent } from "./stage-two.component";
6-
import { of } from "rxjs";
6+
import { EMPTY, of } from "rxjs";
77
import { ReactiveFormsModule } from "@angular/forms";
88
import { AuthRepository } from "@infrastructure/repository/auth/auth.repository";
99
import { provideRouter } from "@angular/router";
1010
import { HttpClientTestingModule } from "@angular/common/http/testing";
1111
import { SkillsRepositoryPort } from "@domain/skills/ports/skills.repository.port";
1212
import { SpecializationsRepositoryPort } from "@domain/specializations/ports/specializations.repository.port";
1313
import { AuthRepositoryPort } from "@domain/auth/ports/auth.repository.port";
14+
import { OnboardingService } from "@api/onboarding/onboarding.service";
15+
import { ProfileInfoService } from "@api/profile/facades/profile-info.service";
16+
import { signal } from "@angular/core";
1417

1518
describe("StageTwoComponent", () => {
1619
let component: OnboardingStageTwoComponent;
@@ -40,13 +43,17 @@ describe("StageTwoComponent", () => {
4043
getSpecializationsInline: () => of({ count: 0, results: [], next: "", previous: "" }),
4144
};
4245

46+
const onboardingSpy = { formValue$: EMPTY, setFormValue: () => {} };
47+
4348
await TestBed.configureTestingModule({
4449
imports: [ReactiveFormsModule, HttpClientTestingModule, OnboardingStageTwoComponent],
4550
providers: [
4651
{ provide: AuthRepository, useValue: authSpy },
4752
{ provide: AuthRepositoryPort, useValue: authPortSpy },
4853
{ provide: SkillsRepositoryPort, useValue: skillsSpy },
4954
{ provide: SpecializationsRepositoryPort, useValue: specializationsSpy },
55+
{ provide: OnboardingService, useValue: onboardingSpy },
56+
{ provide: ProfileInfoService, useValue: { profile: signal(null) } },
5057
provideRouter([]),
5158
],
5259
}).compileComponents();

projects/social_platform/src/app/ui/pages/profile/detail/profile-news/profile-news.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ describe("ProfileNewsComponent", () => {
1717

1818
fixture = TestBed.createComponent(ProfileNewsComponent);
1919
component = fixture.componentInstance;
20-
fixture.detectChanges();
20+
});
21+
22+
afterEach(() => {
23+
fixture?.destroy();
2124
});
2225

2326
it("should create", () => {

0 commit comments

Comments
 (0)