From 0933f36b689cd51e8a5c15dcb7f057344234ddaa Mon Sep 17 00:00:00 2001 From: Diana Date: Thu, 31 Jul 2025 14:33:51 +0300 Subject: [PATCH 1/3] test(testing): added tests for education, employment, name components --- .../reset-password.component.spec.ts | 23 +--- .../citation-preview.component.spec.ts | 16 ++- .../education-form.component.spec.ts | 26 +++- .../education/education.component.spec.ts | 121 +++++++++++++++-- .../employment-form.component.spec.ts | 25 +++- .../employment/employment.component.spec.ts | 122 ++++++++++++++++-- .../name-form/name-form.component.spec.ts | 19 ++- .../components/name/name.component.spec.ts | 83 ++++++++++-- src/app/shared/mocks/index.ts | 4 + .../shared/mocks/translate.service.mock.ts | 24 +++- 10 files changed, 398 insertions(+), 65 deletions(-) diff --git a/src/app/features/auth/pages/reset-password/reset-password.component.spec.ts b/src/app/features/auth/pages/reset-password/reset-password.component.spec.ts index db0fa1d6c..dd5f6e466 100644 --- a/src/app/features/auth/pages/reset-password/reset-password.component.spec.ts +++ b/src/app/features/auth/pages/reset-password/reset-password.component.spec.ts @@ -1,13 +1,11 @@ -import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { TranslatePipe } from '@ngx-translate/core'; import { MockComponent, MockPipe } from 'ng-mocks'; -import { of } from 'rxjs'; - import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ResetPasswordComponent } from '@osf/features/auth/pages'; import { PasswordInputHintComponent } from '@osf/shared/components'; - -import { ResetPasswordComponent } from './reset-password.component'; +import { TranslateServiceMock } from '@osf/shared/mocks'; describe('ResetPasswordComponent', () => { let component: ResetPasswordComponent; @@ -20,20 +18,7 @@ describe('ResetPasswordComponent', () => { MockComponent(PasswordInputHintComponent), MockPipe(TranslatePipe, (value) => value), ], - providers: [ - { - provide: TranslateService, - useValue: { - get: () => of(''), - instant: (key: string) => key, - onLangChange: of({ lang: 'en' }), - onTranslationChange: of({ translations: {} }), - onDefaultLangChange: of({ lang: 'en' }), - setDefaultLang: jest.fn(), - use: jest.fn(), - }, - }, - ], + providers: [TranslateServiceMock], }).compileComponents(); fixture = TestBed.createComponent(ResetPasswordComponent); diff --git a/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.spec.ts b/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.spec.ts index f9924b069..b1d1ed836 100644 --- a/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.spec.ts @@ -1,18 +1,32 @@ +import { TranslatePipe } from '@ngx-translate/core'; +import { MockPipes } from 'ng-mocks'; + +import { ComponentRef } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MOCK_USER } from '@osf/shared/mocks'; +import { CitationFormatPipe } from '@shared/pipes'; + import { CitationPreviewComponent } from './citation-preview.component'; describe('CitationPreviewComponent', () => { let component: CitationPreviewComponent; + let componentRef: ComponentRef; let fixture: ComponentFixture; + const mockUser = MOCK_USER; + beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CitationPreviewComponent], + imports: [CitationPreviewComponent, MockPipes(TranslatePipe, CitationFormatPipe)], }).compileComponents(); fixture = TestBed.createComponent(CitationPreviewComponent); component = fixture.componentInstance; + componentRef = fixture.componentRef; + + componentRef.setInput('currentUser', mockUser); + fixture.detectChanges(); }); diff --git a/src/app/features/settings/profile-settings/components/education-form/education-form.component.spec.ts b/src/app/features/settings/profile-settings/components/education-form/education-form.component.spec.ts index 5d56b15d4..5cfe049fa 100644 --- a/src/app/features/settings/profile-settings/components/education-form/education-form.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/education-form/education-form.component.spec.ts @@ -1,18 +1,42 @@ +import { TranslatePipe } from '@ngx-translate/core'; +import { MockComponent, MockPipe } from 'ng-mocks'; + +import { ComponentRef } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormControl, FormGroup } from '@angular/forms'; + +import { MOCK_EDUCATION } from '@osf/shared/mocks'; +import { TextInputComponent } from '@shared/components'; import { EducationFormComponent } from './education-form.component'; describe('EducationFormComponent', () => { let component: EducationFormComponent; + let componentRef: ComponentRef; let fixture: ComponentFixture; + let mockFormGroup: FormGroup; beforeEach(async () => { + mockFormGroup = new FormGroup({ + institution: new FormControl(MOCK_EDUCATION[0].institution), + department: new FormControl(MOCK_EDUCATION[0].department), + degree: new FormControl(MOCK_EDUCATION[0].degree), + startDate: new FormControl(new Date(2021, 8, 1)), + endDate: new FormControl(new Date(2025, 4, 1)), + ongoing: new FormControl(false), + }); + await TestBed.configureTestingModule({ - imports: [EducationFormComponent], + imports: [EducationFormComponent, MockPipe(TranslatePipe), MockComponent(TextInputComponent)], }).compileComponents(); fixture = TestBed.createComponent(EducationFormComponent); component = fixture.componentInstance; + componentRef = fixture.componentRef; + + componentRef.setInput('group', mockFormGroup); + componentRef.setInput('index', 0); + fixture.detectChanges(); }); diff --git a/src/app/features/settings/profile-settings/components/education/education.component.spec.ts b/src/app/features/settings/profile-settings/components/education/education.component.spec.ts index 9cc290c63..f1220bb62 100644 --- a/src/app/features/settings/profile-settings/components/education/education.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/education/education.component.spec.ts @@ -7,10 +7,16 @@ import { of } from 'rxjs'; import { provideHttpClient } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { signal } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MOCK_STORE } from '@shared/mocks'; +import { UpdateProfileSettingsEducation, UserSelectors } from '@core/store/user'; +import { + CustomConfirmationServiceMock, + MOCK_EDUCATION, + MockCustomConfirmationServiceProvider, + TranslateServiceMock, +} from '@osf/shared/mocks'; +import { ToastService } from '@shared/services'; import { EducationComponent } from './education.component'; @@ -18,31 +24,122 @@ describe('EducationComponent', () => { let component: EducationComponent; let fixture: ComponentFixture; - beforeEach(async () => { - const store = MOCK_STORE; - store.selectSignal.mockImplementation(() => { - return signal([]); - }); - store.dispatch.mockImplementation(() => { - return of(); - }); + const mockStore = { + selectSignal: jest.fn().mockImplementation((selector) => { + if (selector === UserSelectors.getEducation) { + return () => MOCK_EDUCATION; + } + return () => null; + }), + dispatch: jest.fn().mockReturnValue(of({})), + }; + beforeEach(async () => { await TestBed.configureTestingModule({ imports: [EducationComponent, MockPipe(TranslatePipe)], providers: [ + TranslateServiceMock, + MockCustomConfirmationServiceProvider, + MockProvider(ToastService), + MockProvider(Store, mockStore), provideHttpClient(), provideHttpClientTesting(), - MockProvider(TranslatePipe), - MockProvider(Store, store), ], }).compileComponents(); fixture = TestBed.createComponent(EducationComponent); component = fixture.componentInstance; + fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should handle invalid index in removeEducation method', () => { + const initialLength = component.educations.length; + + component.removeEducation(100); + + expect(component.educations.length).toBe(initialLength); + }); + + it('should not add education when form is invalid', () => { + component.educations.at(0).get('institution')?.setValue(''); + component.educations.at(0).get('institution')?.updateValueAndValidity(); + const initialLength = component.educations.length; + + expect(component.educationForm.invalid).toBe(true); + + component.addEducation(); + + expect(component.educations.length).toBe(initialLength); + }); + + it('should add new education form when form is valid', () => { + const initialLength = component.educations.length; + + component.addEducation(); + + expect(component.educations.length).toBe(initialLength + 1); + + const newEducation = component.educations.at(initialLength); + expect(newEducation).toBeDefined(); + expect(newEducation.get('institution')?.value).toBe(''); + expect(newEducation.get('department')?.value).toBe(''); + expect(newEducation.get('degree')?.value).toBe(''); + expect(newEducation.get('startDate')?.value).toBe(null); + expect(newEducation.get('endDate')?.value).toBe(null); + expect(newEducation.get('ongoing')?.value).toBe(false); + }); + + it('should detect changes when form field is modified', () => { + component.educations.at(0).get('institution')?.setValue('New Institution'); + + component.discardChanges(); + + expect(CustomConfirmationServiceMock.confirmDelete).toHaveBeenCalled(); + }); + + it('should mark all fields as touched when form is invalid', () => { + component.educations.at(0).get('institution')?.setValue(''); + component.educations.at(1).get('degree')?.setValue(''); + + component.saveEducation(); + + expect(component.educationForm.touched).toBe(true); + expect(component.educations.at(0).get('institution')?.touched).toBe(true); + expect(component.educations.at(1).get('degree')?.touched).toBe(true); + }); + + it('should map form data to correct education format', () => { + const education = component.educations.at(0); + education.get('institution')?.setValue('Test University'); + education.get('department')?.setValue('Engineering'); + education.get('degree')?.setValue('Bachelor'); + education.get('startDate')?.setValue(new Date(2020, 0)); + education.get('endDate')?.setValue(new Date(2024, 5)); + education.get('ongoing')?.setValue(false); + + component.saveEducation(); + + expect(mockStore.dispatch).toHaveBeenCalledWith( + new UpdateProfileSettingsEducation({ + education: [ + { + institution: 'Test University', + department: 'Engineering', + degree: 'Bachelor', + startYear: 2020, + startMonth: 1, + endYear: 2024, + endMonth: 6, + ongoing: false, + }, + expect.any(Object), + ], + }) + ); + }); }); diff --git a/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.spec.ts b/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.spec.ts index 6621a37e8..47b37bd0f 100644 --- a/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/employment-form/employment-form.component.spec.ts @@ -1,18 +1,41 @@ +import { TranslatePipe } from '@ngx-translate/core'; +import { MockComponent, MockPipe } from 'ng-mocks'; + +import { ComponentRef } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormControl, FormGroup } from '@angular/forms'; + +import { MOCK_EDUCATION, MOCK_EMPLOYMENT } from '@osf/shared/mocks'; +import { TextInputComponent } from '@shared/components'; import { EmploymentFormComponent } from './employment-form.component'; describe('EmploymentFormComponent', () => { let component: EmploymentFormComponent; + let componentRef: ComponentRef; let fixture: ComponentFixture; + let mockFormGroup: FormGroup; beforeEach(async () => { + mockFormGroup = new FormGroup({ + title: new FormControl(MOCK_EMPLOYMENT[0].title), + institution: new FormControl(MOCK_EDUCATION[0].institution), + department: new FormControl(MOCK_EDUCATION[0].department), + startDate: new FormControl(new Date(2021, 8, 1)), + endDate: new FormControl(new Date(2025, 4, 1)), + ongoing: new FormControl(false), + }); + await TestBed.configureTestingModule({ - imports: [EmploymentFormComponent], + imports: [EmploymentFormComponent, MockPipe(TranslatePipe), MockComponent(TextInputComponent)], }).compileComponents(); fixture = TestBed.createComponent(EmploymentFormComponent); component = fixture.componentInstance; + componentRef = fixture.componentRef; + + componentRef.setInput('group', mockFormGroup); + componentRef.setInput('index', 0); fixture.detectChanges(); }); diff --git a/src/app/features/settings/profile-settings/components/employment/employment.component.spec.ts b/src/app/features/settings/profile-settings/components/employment/employment.component.spec.ts index 95e002c4e..0ea72671f 100644 --- a/src/app/features/settings/profile-settings/components/employment/employment.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/employment/employment.component.spec.ts @@ -1,16 +1,22 @@ import { Store } from '@ngxs/store'; import { TranslatePipe } from '@ngx-translate/core'; -import { MockPipe, MockProvider } from 'ng-mocks'; +import { MockComponent, MockPipe, MockProvider } from 'ng-mocks'; import { of } from 'rxjs'; import { provideHttpClient } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { signal } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MOCK_STORE } from '@shared/mocks'; +import { UpdateProfileSettingsEmployment, UserSelectors } from '@core/store/user'; +import { EmploymentFormComponent } from '@osf/features/settings/profile-settings/components'; +import { + CustomConfirmationServiceMock, + MOCK_EMPLOYMENT, + MockCustomConfirmationServiceProvider, +} from '@osf/shared/mocks'; +import { ToastService } from '@shared/services'; import { EmploymentComponent } from './employment.component'; @@ -18,22 +24,26 @@ describe('EmploymentComponent', () => { let component: EmploymentComponent; let fixture: ComponentFixture; - beforeEach(async () => { - const store = MOCK_STORE; - store.selectSignal.mockImplementation(() => { - return signal([]); - }); - store.dispatch.mockImplementation(() => { - return of(); - }); + const mockStore = { + selectSignal: jest.fn().mockImplementation((selector) => { + if (selector === UserSelectors.getEmployment) { + return () => MOCK_EMPLOYMENT; + } + return () => null; + }), + dispatch: jest.fn().mockReturnValue(of({})), + }; + beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [EmploymentComponent, MockPipe(TranslatePipe)], + imports: [EmploymentComponent, MockPipe(TranslatePipe), MockComponent(EmploymentFormComponent)], providers: [ + MockCustomConfirmationServiceProvider, + MockProvider(ToastService), provideHttpClient(), provideHttpClientTesting(), MockProvider(TranslatePipe), - MockProvider(Store, store), + MockProvider(Store, mockStore), ], }).compileComponents(); @@ -45,4 +55,90 @@ describe('EmploymentComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should handle invalid index in removePosition method', () => { + const initialLength = component.positions.length; + + component.removePosition(100); + + expect(component.positions.length).toBe(initialLength); + }); + + it('should not add position when form is invalid', () => { + component.positions.at(0).get('title')?.setValue(''); + component.positions.at(0).get('title')?.updateValueAndValidity(); + const initialLength = component.positions.length; + + expect(component.employmentForm.invalid).toBe(true); + + component.addPosition(); + + expect(component.positions.length).toBe(initialLength); + }); + + it('should add new employment form when form is valid', () => { + const initialLength = component.positions.length; + + component.addPosition(); + + expect(component.positions.length).toBe(initialLength + 1); + + const newEducation = component.positions.at(initialLength); + expect(newEducation).toBeDefined(); + expect(newEducation.get('title')?.value).toBe(''); + expect(newEducation.get('institution')?.value).toBe(''); + expect(newEducation.get('department')?.value).toBe(''); + expect(newEducation.get('startDate')?.value).toBe(null); + expect(newEducation.get('endDate')?.value).toBe(null); + expect(newEducation.get('ongoing')?.value).toBe(false); + }); + + it('should detect changes when form field is modified', () => { + component.positions.at(0).get('institution')?.setValue('New Institution'); + + component.discardChanges(); + + expect(CustomConfirmationServiceMock.confirmDelete).toHaveBeenCalled(); + }); + + it('should mark all fields as touched when form is invalid', () => { + component.positions.at(0).get('institution')?.setValue(''); + component.positions.at(1).get('title')?.setValue(''); + + component.saveEmployment(); + + expect(component.employmentForm.touched).toBe(true); + expect(component.positions.at(0).get('institution')?.touched).toBe(true); + expect(component.positions.at(1).get('title')?.touched).toBe(true); + }); + + it('should map form data to correct education format', () => { + const education = component.positions.at(0); + education.get('title')?.setValue('Software Engineer Intern'); + education.get('institution')?.setValue('Test University'); + education.get('department')?.setValue('Engineering'); + education.get('startDate')?.setValue(new Date(2020, 0)); + education.get('endDate')?.setValue(new Date(2024, 5)); + education.get('ongoing')?.setValue(false); + + component.saveEmployment(); + + expect(mockStore.dispatch).toHaveBeenCalledWith( + new UpdateProfileSettingsEmployment({ + employment: [ + { + title: 'Software Engineer Intern', + institution: 'Test University', + department: 'Engineering', + startYear: 2020, + startMonth: 1, + endYear: 2024, + endMonth: 6, + ongoing: false, + }, + expect.any(Object), + ], + }) + ); + }); }); diff --git a/src/app/features/settings/profile-settings/components/name-form/name-form.component.spec.ts b/src/app/features/settings/profile-settings/components/name-form/name-form.component.spec.ts index 1ae418419..45ef3fdfe 100644 --- a/src/app/features/settings/profile-settings/components/name-form/name-form.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/name-form/name-form.component.spec.ts @@ -1,18 +1,35 @@ +import { TranslatePipe } from '@ngx-translate/core'; +import { MockComponent, MockPipe } from 'ng-mocks'; + import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormControl, FormGroup } from '@angular/forms'; + +import { NameForm } from '@osf/features/settings/profile-settings/models'; +import { TextInputComponent } from '@shared/components'; import { NameFormComponent } from './name-form.component'; describe('NameFormComponent', () => { let component: NameFormComponent; let fixture: ComponentFixture; + let mockForm: FormGroup; beforeEach(async () => { + mockForm = new FormGroup({ + fullName: new FormControl('John Doe', { nonNullable: true }), + givenName: new FormControl('John', { nonNullable: true }), + middleNames: new FormControl('William', { nonNullable: true }), + familyName: new FormControl('Doe', { nonNullable: true }), + suffix: new FormControl('Jr.', { nonNullable: true }), + }); await TestBed.configureTestingModule({ - imports: [NameFormComponent], + imports: [NameFormComponent, MockComponent(TextInputComponent), MockPipe(TranslatePipe)], }).compileComponents(); fixture = TestBed.createComponent(NameFormComponent); component = fixture.componentInstance; + fixture.componentRef.setInput('form', mockForm); + fixture.detectChanges(); }); diff --git a/src/app/features/settings/profile-settings/components/name/name.component.spec.ts b/src/app/features/settings/profile-settings/components/name/name.component.spec.ts index 7b3ade86f..b243e5b59 100644 --- a/src/app/features/settings/profile-settings/components/name/name.component.spec.ts +++ b/src/app/features/settings/profile-settings/components/name/name.component.spec.ts @@ -1,16 +1,18 @@ import { Store } from '@ngxs/store'; import { TranslatePipe } from '@ngx-translate/core'; -import { MockPipe, MockProvider } from 'ng-mocks'; +import { MockComponents, MockPipe, MockProvider } from 'ng-mocks'; import { of } from 'rxjs'; import { provideHttpClient } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { signal } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MOCK_STORE } from '@shared/mocks'; +import { UpdateProfileSettingsUser, UserSelectors } from '@core/store/user'; +import { CitationPreviewComponent, NameFormComponent } from '@osf/features/settings/profile-settings/components'; +import { MOCK_USER, MockCustomConfirmationServiceProvider } from '@osf/shared/mocks'; +import { ToastService } from '@shared/services'; import { NameComponent } from './name.component'; @@ -18,22 +20,28 @@ describe('NameComponent', () => { let component: NameComponent; let fixture: ComponentFixture; + const mockStore = { + selectSignal: jest.fn().mockImplementation((selector) => { + if (selector === UserSelectors.getUserNames) { + return () => MOCK_USER; + } + return () => null; + }), + dispatch: jest.fn().mockReturnValue(of({})), + }; + beforeEach(async () => { - const store = MOCK_STORE; - store.selectSignal.mockImplementation(() => { - return signal([]); - }); - store.dispatch.mockImplementation(() => { - return of(); - }); + jest.clearAllMocks(); await TestBed.configureTestingModule({ - imports: [NameComponent, MockPipe(TranslatePipe)], + imports: [NameComponent, MockPipe(TranslatePipe), ...MockComponents(CitationPreviewComponent, NameFormComponent)], providers: [ + MockCustomConfirmationServiceProvider, + MockProvider(ToastService), provideHttpClient(), provideHttpClientTesting(), MockProvider(TranslatePipe), - MockProvider(Store, store), + MockProvider(Store, mockStore), ], }).compileComponents(); @@ -42,7 +50,58 @@ describe('NameComponent', () => { fixture.detectChanges(); }); + afterEach(() => { + jest.clearAllMocks(); + }); + it('should create', () => { expect(component).toBeTruthy(); }); + + it('should not proceed when form is invalid', () => { + component.form.get('fullName')?.setValue(''); + component.form.get('fullName')?.setErrors({ required: true }); + + component.saveChanges(); + + expect(mockStore.dispatch).not.toHaveBeenCalled(); + }); + + it('should dispatch updateProfileSettingsUser action with correct data', () => { + const formData = { + fullName: 'John Doe', + givenName: 'John', + middleNames: 'Alexander', + familyName: 'Doe', + suffix: 'Jr.', + }; + + component.form.patchValue(formData); + + component.saveChanges(); + + expect(mockStore.dispatch).toHaveBeenCalledWith( + new UpdateProfileSettingsUser({ + user: formData, + }) + ); + }); + + it('should reset form to current user data', () => { + component.form.patchValue({ + fullName: 'Changed Name', + givenName: 'Changed', + middleNames: 'Changed', + familyName: 'Changed', + suffix: 'Changed', + }); + + component.discardChanges(); + + expect(component.form.get('fullName')?.value).toBe(MOCK_USER.fullName); + expect(component.form.get('givenName')?.value).toBe(MOCK_USER.givenName); + expect(component.form.get('middleNames')?.value).toBe(MOCK_USER.middleNames); + expect(component.form.get('familyName')?.value).toBe(MOCK_USER.familyName); + expect(component.form.get('suffix')?.value).toBe(MOCK_USER.suffix); + }); }); diff --git a/src/app/shared/mocks/index.ts b/src/app/shared/mocks/index.ts index 23d8a20fe..3b7831722 100644 --- a/src/app/shared/mocks/index.ts +++ b/src/app/shared/mocks/index.ts @@ -1,4 +1,8 @@ +export * from './custom-сonfirmation.service.mock'; export { MOCK_USER } from './data.mock'; +export { MOCK_EDUCATION } from './education.mock'; +export { MOCK_EMPLOYMENT } from './employment.mock'; export * from './meeting.mock'; +export { MOCK_MEETING } from './meeting.mock'; export { MOCK_STORE } from './mock-store.mock'; export { TranslateServiceMock } from './translate.service.mock'; diff --git a/src/app/shared/mocks/translate.service.mock.ts b/src/app/shared/mocks/translate.service.mock.ts index e967391d1..fa13d46b1 100644 --- a/src/app/shared/mocks/translate.service.mock.ts +++ b/src/app/shared/mocks/translate.service.mock.ts @@ -1,9 +1,23 @@ import { TranslateService } from '@ngx-translate/core'; -import { MockProvider } from 'ng-mocks'; import { of } from 'rxjs'; -export const TranslateServiceMock = MockProvider(TranslateService, { - instant: (key: string) => key, - get: (key: string) => of(key), -}); +export const TranslateServiceMock = { + provide: TranslateService, + useValue: { + get: jest.fn().mockImplementation((key: string) => of(key)), + instant: jest.fn().mockImplementation((key: string) => key), + onLangChange: of({ lang: 'en' }), + onTranslationChange: of({ translations: {} }), + onDefaultLangChange: of({ lang: 'en' }), + setDefaultLang: jest.fn(), + use: jest.fn(), + getDefaultLang: jest.fn().mockReturnValue('en'), + getBrowserLang: jest.fn().mockReturnValue('en'), + addLangs: jest.fn(), + getLangs: jest.fn().mockReturnValue(['en']), + stream: jest.fn().mockImplementation((key: string) => of(key)), + currentLang: 'en', + defaultLang: 'en', + }, +}; From 636a0de454ac29cfa923d069220d4737c7102c78 Mon Sep 17 00:00:00 2001 From: Diana Date: Thu, 31 Jul 2025 15:18:38 +0300 Subject: [PATCH 2/3] test(testing): added mocks --- ...ustom-\321\201onfirmation.service.mock.ts" | 12 ++++++++++ src/app/shared/mocks/education.mock.ts | 24 +++++++++++++++++++ src/app/shared/mocks/employment.mock.ts | 24 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 "src/app/shared/mocks/custom-\321\201onfirmation.service.mock.ts" create mode 100644 src/app/shared/mocks/education.mock.ts create mode 100644 src/app/shared/mocks/employment.mock.ts diff --git "a/src/app/shared/mocks/custom-\321\201onfirmation.service.mock.ts" "b/src/app/shared/mocks/custom-\321\201onfirmation.service.mock.ts" new file mode 100644 index 000000000..29f7ef25d --- /dev/null +++ "b/src/app/shared/mocks/custom-\321\201onfirmation.service.mock.ts" @@ -0,0 +1,12 @@ +import { CustomConfirmationService } from '@shared/services'; + +export const CustomConfirmationServiceMock = { + confirmDelete: jest.fn(), + confirmAccept: jest.fn(), + confirmContinue: jest.fn(), +}; + +export const MockCustomConfirmationServiceProvider = { + provide: CustomConfirmationService, + useValue: CustomConfirmationServiceMock, +}; diff --git a/src/app/shared/mocks/education.mock.ts b/src/app/shared/mocks/education.mock.ts new file mode 100644 index 000000000..7eca317ca --- /dev/null +++ b/src/app/shared/mocks/education.mock.ts @@ -0,0 +1,24 @@ +import { Education } from '@shared/models'; + +export const MOCK_EDUCATION: Education[] = [ + { + institution: 'University of Technology', + department: 'Computer Science', + degree: 'Bachelor of Science', + startMonth: 9, + startYear: 2021, + endMonth: 5, + endYear: 2025, + ongoing: true, + }, + { + institution: 'Advanced University', + department: 'Software Engineering', + degree: 'Master of Science', + startMonth: 9, + startYear: 2020, + endMonth: null, + endYear: null, + ongoing: false, + }, +]; diff --git a/src/app/shared/mocks/employment.mock.ts b/src/app/shared/mocks/employment.mock.ts new file mode 100644 index 000000000..44aff60cd --- /dev/null +++ b/src/app/shared/mocks/employment.mock.ts @@ -0,0 +1,24 @@ +import { Employment } from '@shared/models'; + +export const MOCK_EMPLOYMENT: Employment[] = [ + { + title: 'Senior Software Engineer', + institution: 'Tech Company Inc.', + department: 'Engineering', + startMonth: 6, + startYear: 2022, + endMonth: null, + endYear: null, + ongoing: true, + }, + { + title: 'Software Engineer Intern', + institution: 'University Research Lab', + department: 'Computer Science', + startMonth: 9, + startYear: 2019, + endMonth: 12, + endYear: 2019, + ongoing: false, + }, +]; From 304a7d71d127601302c2d3b39b4873635a3b9662 Mon Sep 17 00:00:00 2001 From: Diana Date: Fri, 1 Aug 2025 09:41:08 +0300 Subject: [PATCH 3/3] test(testing): updated tab options display test for medium screens --- .../profile-settings/profile-settings.component.spec.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/features/settings/profile-settings/profile-settings.component.spec.ts b/src/app/features/settings/profile-settings/profile-settings.component.spec.ts index 4d5fdb6f2..5cc22407d 100644 --- a/src/app/features/settings/profile-settings/profile-settings.component.spec.ts +++ b/src/app/features/settings/profile-settings/profile-settings.component.spec.ts @@ -44,9 +44,11 @@ describe('ProfileSettingsComponent', () => { expect(fixture.componentInstance['selectedTab']).toBe(newTabIndex); }); - it('should display all tab options', () => { + it('should display all tab options on medium screens', () => { + isMedium.next(true); + fixture.detectChanges(); const tabElements = fixture.debugElement.queryAll(By.css('p-tab')); - expect(tabElements.length).toBe(fixture.componentInstance['tabOptions'].length); + expect(tabElements.length).toBe(component['tabOptions'].length); }); it('should render all tab panels', () => {