Skip to content

Commit 1b11467

Browse files
authored
Merge pull request #122 from CenterForOpenScience/test/fixed-unit-tests
fix(unit-tests): fixed unit tests
2 parents 21e8438 + aa8a2d0 commit 1b11467

File tree

29 files changed

+226
-151
lines changed

29 files changed

+226
-151
lines changed

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = {
66
'^@core/(.*)$': '<rootDir>/src/app/core/$1',
77
'^@shared/(.*)$': '<rootDir>/src/app/shared/$1',
88
'^@styles/(.*)$': '<rootDir>/assets/styles/$1',
9+
'^src/environments/environment$': '<rootDir>/src/environments/environment.ts',
910
},
1011
transform: {
1112
'^.+\\.(ts|mjs|js|html)$': [

src/app/app.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { provideStore, Store } from '@ngxs/store';
22

3+
import { MockComponents } from 'ng-mocks';
4+
35
import { provideHttpClient } from '@angular/common/http';
46
import { provideHttpClientTesting } from '@angular/common/http/testing';
57
import { ComponentFixture, TestBed } from '@angular/core/testing';
68
import { By } from '@angular/platform-browser';
79

810
import { GetCurrentUser, UserState } from '@core/store/user';
911

12+
import { FullScreenLoaderComponent, ToastComponent } from './shared/components';
1013
import { AppComponent } from './app.component';
1114

1215
describe('AppComponent', () => {
@@ -15,7 +18,7 @@ describe('AppComponent', () => {
1518

1619
beforeEach(async () => {
1720
await TestBed.configureTestingModule({
18-
imports: [AppComponent],
21+
imports: [AppComponent, ...MockComponents(ToastComponent, FullScreenLoaderComponent)],
1922
providers: [provideStore([UserState]), provideHttpClient(), provideHttpClientTesting()],
2023
}).compileComponents();
2124

src/app/core/components/header/header.component.spec.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { provideStore } from '@ngxs/store';
1+
import { Store } from '@ngxs/store';
22

3-
import { MockComponent } from 'ng-mocks';
3+
import { TranslatePipe } from '@ngx-translate/core';
4+
import { MockComponent, MockPipe, MockProvider } from 'ng-mocks';
45

56
import { provideHttpClient } from '@angular/common/http';
67
import { provideHttpClientTesting } from '@angular/common/http/testing';
8+
import { signal } from '@angular/core';
79
import { ComponentFixture, TestBed } from '@angular/core/testing';
810

9-
import { UserState } from '@osf/core/store/user';
11+
import { UserSelectors } from '@osf/core/store/user';
12+
import { MOCK_STORE, MOCK_USER } from '@osf/shared/mocks';
1013

1114
import { BreadcrumbComponent } from '../breadcrumb/breadcrumb.component';
1215

@@ -17,9 +20,14 @@ describe('HeaderComponent', () => {
1720
let fixture: ComponentFixture<HeaderComponent>;
1821

1922
beforeEach(async () => {
23+
MOCK_STORE.selectSignal.mockImplementation((selector) => {
24+
if (selector === UserSelectors.getCurrentUser) return () => signal(MOCK_USER);
25+
return () => null;
26+
});
27+
2028
await TestBed.configureTestingModule({
21-
imports: [HeaderComponent, MockComponent(BreadcrumbComponent)],
22-
providers: [provideStore([UserState]), provideHttpClient(), provideHttpClientTesting()],
29+
imports: [HeaderComponent, MockComponent(BreadcrumbComponent), MockPipe(TranslatePipe)],
30+
providers: [MockProvider(Store, MOCK_STORE), provideHttpClient(), provideHttpClientTesting()],
2331
}).compileComponents();
2432

2533
fixture = TestBed.createComponent(HeaderComponent);
Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
import { Store } from '@ngxs/store';
1+
import { select } from '@ngxs/store';
22

33
import { TranslatePipe } from '@ngx-translate/core';
44

55
import { ButtonModule } from 'primeng/button';
66
import { MenuModule } from 'primeng/menu';
77

8-
import { map } from 'rxjs';
9-
10-
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
11-
import { toSignal } from '@angular/core/rxjs-interop';
8+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
129
import { Router } from '@angular/router';
1310

1411
import { BreadcrumbComponent } from '@core/components/breadcrumb/breadcrumb.component';
@@ -22,24 +19,16 @@ import { UserSelectors } from '@core/store/user/user.selectors';
2219
changeDetection: ChangeDetectionStrategy.OnPush,
2320
})
2421
export class HeaderComponent {
25-
readonly #store = inject(Store);
26-
readonly #router = inject(Router);
27-
readonly currentUser = this.#store.selectSignal(UserSelectors.getCurrentUser);
22+
currentUser = select(UserSelectors.getCurrentUser);
23+
24+
private readonly router = inject(Router);
2825

2926
items = [
3027
{
3128
label: 'navigation.myProfile',
32-
command: () => this.#router.navigate(['my-profile']),
29+
command: () => this.router.navigate(['my-profile']),
3330
},
3431
{ label: 'navigation.settings', command: () => console.log('Settings') },
3532
{ label: 'navigation.logOut', command: () => console.log('Log out') },
3633
];
37-
38-
#currentUrl = toSignal(this.#router.events.pipe(map(() => this.#router.url)));
39-
40-
protected readonly authButtonText = computed(() =>
41-
this.#currentUrl()?.includes('sign-up') ? 'navigation.signIn' : 'navigation.signUp'
42-
);
43-
44-
protected readonly authButtonLink = computed(() => (this.#currentUrl()?.includes('sign-up') ? '/login' : '/sign-up'));
4534
}

src/app/core/components/root/root.component.spec.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,6 @@ describe('RootComponent', () => {
7777
expect(tabletLayout).toBeTruthy();
7878
});
7979

80-
it('should show breadcrumb in tablet layout when not mobile', () => {
81-
isWebSubject.next(false);
82-
isMobileSubject.next(false);
83-
fixture.detectChanges();
84-
85-
const breadcrumb = fixture.nativeElement.querySelector('osf-breadcrumb');
86-
expect(breadcrumb).toBeTruthy();
87-
});
88-
8980
it('should hide breadcrumb in tablet layout when mobile', () => {
9081
isWebSubject.next(false);
9182
isMobileSubject.next(true);
Lines changed: 17 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { Store } from '@ngxs/store';
22

3-
import { TranslateModule } from '@ngx-translate/core';
4-
import { MockComponent, MockModule, MockProvider } from 'ng-mocks';
5-
6-
import { Button } from 'primeng/button';
3+
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
4+
import { MockComponents, MockPipe, MockProvider } from 'ng-mocks';
75

86
import { BehaviorSubject, of } from 'rxjs';
97

@@ -12,53 +10,21 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
1210
import { By } from '@angular/platform-browser';
1311
import { Router } from '@angular/router';
1412

15-
import { IS_XSMALL } from '@osf/shared/utils';
16-
17-
import { ResetFiltersState } from '../search/components/resource-filters/store';
18-
import { SearchComponent } from '../search/search.component';
19-
import { ResetSearchState } from '../search/store';
13+
import { EducationHistoryComponent, EmploymentHistoryComponent } from '@osf/shared/components';
14+
import { MOCK_USER } from '@osf/shared/mocks';
15+
import { IS_MEDIUM } from '@osf/shared/utils';
2016

17+
import { MyProfileSearchComponent } from './components';
2118
import { MyProfileComponent } from './my-profile.component';
22-
import { SetIsMyProfile } from './store';
2319

2420
describe('MyProfileComponent', () => {
2521
let component: MyProfileComponent;
2622
let fixture: ComponentFixture<MyProfileComponent>;
2723
let store: Partial<Store>;
2824
let router: Partial<Router>;
29-
let isXSmallSubject: BehaviorSubject<boolean>;
25+
let isMediumSubject: BehaviorSubject<boolean>;
3026

31-
const mockUser = {
32-
id: '1',
33-
fullName: 'John Doe',
34-
email: 'john@example.com',
35-
givenName: 'John',
36-
familyName: 'Doe',
37-
middleNames: '',
38-
suffix: '',
39-
dateRegistered: '2024-01-01',
40-
employment: [
41-
{
42-
title: 'Software Engineer',
43-
institution: 'Tech Corp',
44-
startDate: '2020-01-01',
45-
endDate: null,
46-
},
47-
],
48-
education: [
49-
{
50-
degree: 'Bachelor of Science',
51-
institution: 'University of Technology',
52-
startDate: '2016-01-01',
53-
endDate: '2020-01-01',
54-
ongoing: false,
55-
},
56-
],
57-
socials: {
58-
orcid: '0000-0000-0000-0000',
59-
},
60-
link: 'https://example.com/profile',
61-
};
27+
const mockUser = MOCK_USER;
6228

6329
beforeEach(async () => {
6430
store = {
@@ -70,14 +36,19 @@ describe('MyProfileComponent', () => {
7036
navigate: jest.fn(),
7137
};
7238

73-
isXSmallSubject = new BehaviorSubject<boolean>(false);
39+
isMediumSubject = new BehaviorSubject<boolean>(false);
7440

7541
await TestBed.configureTestingModule({
76-
imports: [MyProfileComponent, MockModule(TranslateModule), MockComponent(Button), MockComponent(SearchComponent)],
42+
imports: [
43+
MyProfileComponent,
44+
MockPipe(TranslatePipe),
45+
...MockComponents(MyProfileSearchComponent, EducationHistoryComponent, EmploymentHistoryComponent),
46+
],
7747
providers: [
7848
MockProvider(Store, store),
7949
MockProvider(Router, router),
80-
{ provide: IS_XSMALL, useValue: isXSmallSubject },
50+
MockProvider(TranslateService),
51+
MockProvider(IS_MEDIUM, isMediumSubject),
8152
],
8253
}).compileComponents();
8354

@@ -95,24 +66,8 @@ describe('MyProfileComponent', () => {
9566
expect(router.navigate).toHaveBeenCalledWith(['settings/profile-settings']);
9667
});
9768

98-
it('should handle mobile view correctly', () => {
99-
isXSmallSubject.next(true);
100-
fixture.detectChanges();
101-
102-
const compiled = fixture.nativeElement;
103-
const editButton = compiled.querySelector('.btn-full-width');
104-
expect(editButton).toBeTruthy();
105-
});
106-
107-
it('should clean up store state on destroy', () => {
108-
component.ngOnDestroy();
109-
expect(store.dispatch).toHaveBeenCalledWith(ResetFiltersState);
110-
expect(store.dispatch).toHaveBeenCalledWith(ResetSearchState);
111-
expect(store.dispatch).toHaveBeenCalledWith(new SetIsMyProfile(false));
112-
});
113-
11469
it('should render search component', () => {
115-
const searchComponent = fixture.debugElement.query(By.directive(SearchComponent));
70+
const searchComponent = fixture.debugElement.query(By.directive(MyProfileSearchComponent));
11671
expect(searchComponent).toBeTruthy();
11772
});
11873
});

src/app/features/my-projects/my-projects.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ describe('MyProjectsComponent', () => {
4040
MockProvider(DialogService),
4141
MockProvider(ActivatedRoute, { queryParams: of({}) }),
4242
MockProvider(IS_XSMALL, isXSmallSubject),
43-
MockProvider(IS_MEDIUM, isXSmallSubject),
44-
MockProvider(IS_WEB, isXSmallSubject),
43+
MockProvider(IS_MEDIUM, isMediumSubject),
44+
MockProvider(IS_WEB, isWebSubject),
4545
],
4646
}).compileComponents();
4747

src/app/features/preprints/components/filters/preprints-creators-filter/preprints-creators-filter.component.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
GetAllOptions,
1616
PreprintsResourcesFiltersOptionsSelectors,
1717
} from '@osf/features/preprints/store/preprints-resources-filters-options';
18-
import { mockStore } from '@osf/shared/mocks';
18+
import { MOCK_STORE } from '@osf/shared/mocks';
1919
import { Creator } from '@osf/shared/models';
2020

2121
import { PreprintsCreatorsFilterComponent } from './preprints-creators-filter.component';
@@ -24,7 +24,7 @@ describe('CreatorsFilterComponent', () => {
2424
let component: PreprintsCreatorsFilterComponent;
2525
let fixture: ComponentFixture<PreprintsCreatorsFilterComponent>;
2626

27-
const store = mockStore;
27+
let store: Store;
2828

2929
const mockCreators: Creator[] = [
3030
{ id: '1', name: 'John Doe' },
@@ -33,7 +33,7 @@ describe('CreatorsFilterComponent', () => {
3333
];
3434

3535
beforeEach(async () => {
36-
store.selectSignal.mockImplementation((selector) => {
36+
MOCK_STORE.selectSignal.mockImplementation((selector) => {
3737
if (selector === PreprintsResourcesFiltersOptionsSelectors.getCreators) {
3838
return signal(mockCreators);
3939
}
@@ -47,9 +47,10 @@ describe('CreatorsFilterComponent', () => {
4747

4848
await TestBed.configureTestingModule({
4949
imports: [PreprintsCreatorsFilterComponent],
50-
providers: [MockProvider(Store, store)],
50+
providers: [MockProvider(Store, MOCK_STORE)],
5151
}).compileComponents();
5252

53+
store = TestBed.inject(Store);
5354
fixture = TestBed.createComponent(PreprintsCreatorsFilterComponent);
5455
component = fixture.componentInstance;
5556
fixture.detectChanges();

src/app/features/preprints/components/filters/preprints-institution-filter/preprints-institution-filter.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
GetAllOptions,
1616
PreprintsResourcesFiltersOptionsSelectors,
1717
} from '@osf/features/preprints/store/preprints-resources-filters-options';
18-
import { mockStore } from '@osf/shared/mocks';
18+
import { MOCK_STORE } from '@osf/shared/mocks';
1919
import { InstitutionFilter } from '@osf/shared/models';
2020

2121
import { PreprintsInstitutionFilterComponent } from './preprints-institution-filter.component';
@@ -24,7 +24,7 @@ describe('InstitutionFilterComponent', () => {
2424
let component: PreprintsInstitutionFilterComponent;
2525
let fixture: ComponentFixture<PreprintsInstitutionFilterComponent>;
2626

27-
const store = mockStore;
27+
const store = MOCK_STORE;
2828

2929
const mockInstitutions: InstitutionFilter[] = [
3030
{ id: '1', label: 'Harvard University', count: 15 },

src/app/features/preprints/components/filters/preprints-license-filter/preprints-license-filter.component.spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
GetAllOptions,
1616
PreprintsResourcesFiltersOptionsSelectors,
1717
} from '@osf/features/preprints/store/preprints-resources-filters-options';
18+
import { MOCK_STORE } from '@osf/shared/mocks';
1819
import { LicenseFilter } from '@osf/shared/models';
1920

2021
import { PreprintsLicenseFilterComponent } from './preprints-license-filter.component';
@@ -23,10 +24,7 @@ describe('LicenseFilterComponent', () => {
2324
let component: PreprintsLicenseFilterComponent;
2425
let fixture: ComponentFixture<PreprintsLicenseFilterComponent>;
2526

26-
const mockStore = {
27-
selectSignal: jest.fn(),
28-
dispatch: jest.fn(),
29-
};
27+
const mockStore = MOCK_STORE;
3028

3129
const mockLicenses: LicenseFilter[] = [
3230
{ id: '1', label: 'MIT License', count: 10 },

0 commit comments

Comments
 (0)