Skip to content

Commit 15599db

Browse files
authored
Test/477 shared components continue (#274)
* test(components): added unit tests * test(components): updated tests for list-info-shortener and readonly-input components * test(shared-components): added mocks data, updated existing mocks, added new unit tests * test(shared-components): updated tests and jest config * test(shared-components): added mocks and updated tests * test(shared-components): added new unit tests * test(shared-components): fixed tests * test(shared-components): fixed imports * test(shared-components): added new unit tests * test(shared-components): fixed tests
1 parent 14b069a commit 15599db

File tree

71 files changed

+4773
-606
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+4773
-606
lines changed

jest.config.js

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module.exports = {
6060
'<rootDir>/src/app/app.config.ts',
6161
'<rootDir>/src/app/app.routes.ts',
6262
'<rootDir>/src/app/features/registry/',
63+
'<rootDir>/src/app/features/my-projects/',
6364
'<rootDir>/src/app/features/project/addons',
6465
'<rootDir>/src/app/features/project/analytics/',
6566
'<rootDir>/src/app/features/project/contributors/',
@@ -77,47 +78,18 @@ module.exports = {
7778
'<rootDir>/src/app/features/settings/tokens/mappers/',
7879
'<rootDir>/src/app/features/settings/tokens/store/',
7980
'<rootDir>/src/app/features/settings/tokens/pages/tokens-list/',
80-
'<rootDir>/src/app/shared/components/education-history/',
81-
'<rootDir>/src/app/shared/components/education-history-dialog/',
82-
'<rootDir>/src/app/shared/components/employment-history/',
83-
'<rootDir>/src/app/shared/components/employment-history-dialog/',
8481
'<rootDir>/src/app/shared/components/file-menu/',
8582
'<rootDir>/src/app/shared/components/files-tree/',
86-
'<rootDir>/src/app/shared/components/filter-chips/',
87-
'<rootDir>/src/app/shared/components/form-select/',
88-
'<rootDir>/src/app/shared/components/full-screen-loader/',
89-
'<rootDir>/src/app/shared/components/generic-filter/',
90-
'<rootDir>/src/app/shared/components/icon/',
91-
'<rootDir>/src/app/shared/components/info-icon/',
92-
'<rootDir>/src/app/shared/components/license/',
9383
'<rootDir>/src/app/shared/components/line-chart/',
94-
'<rootDir>/src/app/shared/components/list-info-shortener/',
95-
'<rootDir>/src/app/shared/components/loading-spinner/',
9684
'<rootDir>/src/app/shared/components/make-decision-dialog/',
97-
'<rootDir>/src/app/shared/components/markdown/',
98-
'<rootDir>/src/app/shared/components/password-input-hint/',
9985
'<rootDir>/src/app/shared/components/pie-chart/',
100-
'<rootDir>/src/app/shared/components/readonly-input/',
101-
'<rootDir>/src/app/shared/components/registration-card/',
102-
'<rootDir>/src/app/shared/components/resource-card/',
10386
'<rootDir>/src/app/shared/components/resource-citations/',
104-
'<rootDir>/src/app/shared/components/resource-metadata/',
10587
'<rootDir>/src/app/shared/components/reusable-filter/',
106-
'<rootDir>/src/app/shared/components/search-help-tutorial/',
107-
'<rootDir>/src/app/shared/components/search-input/',
108-
'<rootDir>/src/app/shared/components/search-results-container/',
109-
'<rootDir>/src/app/shared/components/select/',
110-
'<rootDir>/src/app/shared/components/shared-metadata/',
111-
'<rootDir>/src/app/shared/components/statistic-card/',
112-
'<rootDir>/src/app/shared/components/status-badge/',
113-
'<rootDir>/src/app/shared/components/stepper/',
114-
'<rootDir>/src/app/shared/components/sub-header/',
88+
'<rootDir>/src/app/shared/components/shared-metadata/dialogs/affiliated-institutions-dialog/',
89+
'<rootDir>/src/app/shared/components/shared-metadata/dialogs/contributors-dialog/',
90+
'<rootDir>/src/app/shared/components/shared-metadata/shared-metadata',
11591
'<rootDir>/src/app/shared/components/subjects/',
116-
'<rootDir>/src/app/shared/components/tags-input/',
117-
'<rootDir>/src/app/shared/components/text-input/',
118-
'<rootDir>/src/app/shared/components/toast/',
119-
'<rootDir>/src/app/shared/components/truncated-text/',
120-
'<rootDir>/src/app/shared/components/view-only-table/',
121-
'<rootDir>/src/app/shared/components/wiki/',
92+
'<rootDir>/src/app/shared/components/wiki/edit-section/',
93+
'<rootDir>/src/app/shared/components/wiki/wiki-list/',
12294
],
12395
};

src/app/features/moderation/components/moderators-list/moderators-list.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing';
1010
import { ComponentFixture, TestBed } from '@angular/core/testing';
1111
import { ActivatedRoute } from '@angular/router';
1212

13+
import { UserState } from '@core/store/user';
1314
import { ModeratorsTableComponent } from '@osf/features/moderation/components';
1415
import { ModeratorsState } from '@osf/features/moderation/store/moderators';
1516
import { SearchInputComponent } from '@shared/components';
@@ -41,7 +42,7 @@ describe('ModeratorsListComponent', () => {
4142
provide: ActivatedRoute,
4243
useValue: mockRoute,
4344
},
44-
provideStore([ModeratorsState]),
45+
provideStore([ModeratorsState, UserState]),
4546
provideHttpClient(),
4647
provideHttpClientTesting(),
4748
],
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './project-metadata.service';
1+
export * from './metadata.service';

src/app/features/project/wiki/wiki.component.spec.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ import { provideHttpClientTesting } from '@angular/common/http/testing';
1010
import { ComponentFixture, TestBed } from '@angular/core/testing';
1111
import { ActivatedRoute, Router } from '@angular/router';
1212

13+
import { WikiComponent } from '@osf/features/project/wiki/wiki.component';
1314
import { SubHeaderComponent } from '@osf/shared/components';
1415
import { ToastService } from '@osf/shared/services';
15-
16-
import { CompareSectionComponent } from './components/compare-section/compare-section.component';
17-
import { EditSectionComponent } from './components/edit-section/edit-section.component';
18-
import { ViewSectionComponent } from './components/view-section/view-section.component';
19-
import { WikiListComponent } from './components/wiki-list/wiki-list.component';
20-
import { WikiState } from './store';
21-
import { WikiComponent } from './wiki.component';
16+
import {
17+
CompareSectionComponent,
18+
EditSectionComponent,
19+
ViewSectionComponent,
20+
WikiListComponent,
21+
} from '@shared/components/wiki';
22+
import { WikiState } from '@shared/stores';
2223

2324
describe('WikiComponent', () => {
2425
let component: WikiComponent;
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export * from './registry-metadata/registry-metadata.component';
22
export * from './registry-metadata-add/registry-metadata-add.component';
3-
export * from '@osf/features/registry/pages/registry-files/registry-files.component';
43
export * from '@osf/features/registry/pages/registry-overview/registry-overview.component';
54
export * from '@osf/features/registry/pages/registry-resources/registry-resources.component';

src/app/features/settings/notifications/notifications.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import { signal } from '@angular/core';
1111
import { ComponentFixture, TestBed } from '@angular/core/testing';
1212
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
1313

14-
import { UserSettings } from '@osf/core/models';
1514
import { UserSelectors } from '@osf/core/store/user';
1615
import { LoaderService, ToastService } from '@osf/shared/services';
1716
import { SubscriptionEvent, SubscriptionFrequency } from '@shared/enums';
1817
import { MOCK_STORE, MOCK_USER } from '@shared/mocks';
18+
import { UserSettings } from '@shared/models';
1919

2020
import { NotificationsComponent } from './notifications.component';
2121
import { NotificationSubscriptionSelectors } from './store';

src/app/shared/components/add-project-form/add-project-form.component.spec.ts

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

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

66
import { DynamicDialogRef } from 'primeng/dynamicdialog';
77

@@ -13,8 +13,9 @@ import { FormControl, FormGroup, Validators } from '@angular/forms';
1313
import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants/my-projects-table.constants';
1414
import { ProjectFormControls } from '@osf/shared/enums/create-project-form-controls.enum';
1515
import { CustomValidators } from '@osf/shared/helpers';
16-
import { IdName, ProjectForm } from '@osf/shared/models';
16+
import { ProjectForm } from '@osf/shared/models';
1717
import { GetMyProjects, InstitutionsState, MyResourcesState } from '@osf/shared/stores';
18+
import { ProjectSelectorComponent } from '@shared/components';
1819
import { RegionsState } from '@shared/stores/regions';
1920

2021
import { AddProjectFormComponent } from './add-project-form.component';
@@ -34,11 +35,6 @@ describe('AddProjectFormComponent', () => {
3435
{ id: 'aff2', name: 'Affiliation 2', assets: { logo: 'logo2.png' } },
3536
];
3637

37-
const mockTemplates: IdName[] = [
38-
{ id: '1', name: 'Template 1' },
39-
{ id: '2', name: 'Template 2' },
40-
];
41-
4238
const createProjectForm = (): FormGroup<ProjectForm> => {
4339
return new FormGroup<ProjectForm>({
4440
[ProjectFormControls.Title]: new FormControl('', {
@@ -69,7 +65,7 @@ describe('AddProjectFormComponent', () => {
6965

7066
beforeEach(async () => {
7167
await TestBed.configureTestingModule({
72-
imports: [AddProjectFormComponent, MockPipe(TranslatePipe)],
68+
imports: [AddProjectFormComponent, MockPipe(TranslatePipe), MockComponent(ProjectSelectorComponent)],
7369
providers: [
7470
provideStore([MyResourcesState, InstitutionsState, RegionsState]),
7571
provideHttpClient(),
@@ -85,7 +81,6 @@ describe('AddProjectFormComponent', () => {
8581
fixture = TestBed.createComponent(AddProjectFormComponent);
8682
component = fixture.componentInstance;
8783

88-
fixture.componentRef.setInput('templates', mockTemplates);
8984
fixture.componentRef.setInput('projectForm', createProjectForm());
9085

9186
fixture.detectChanges();

src/app/shared/components/addons/addon-terms/addon-terms.component.spec.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,125 @@ describe('AddonTermsComponent', () => {
9191
expect(term.status).not.toContain('{provider}');
9292
});
9393
});
94+
95+
it('should show all terms when isCitationService is false', () => {
96+
const regularAddon: Addon = {
97+
...mockAddon,
98+
supportedFeatures: ['STORAGE', 'FORKING'],
99+
};
100+
101+
mockIsCitationAddon.mockReturnValue(false);
102+
fixture.componentRef.setInput('addon', regularAddon);
103+
104+
const terms = (component as any).terms();
105+
106+
expect(terms.length).toBeGreaterThan(0);
107+
108+
const allTerms = (component as any).getAddonTerms(regularAddon);
109+
expect(terms.length).toBe(allTerms.length);
110+
});
111+
112+
it('should handle citation service without required features', () => {
113+
const citationAddonWithoutFeatures: Addon = {
114+
...mockAddon,
115+
supportedFeatures: [],
116+
};
117+
118+
mockIsCitationAddon.mockReturnValue(true);
119+
fixture.componentRef.setInput('addon', citationAddonWithoutFeatures);
120+
121+
const terms = (component as any).terms();
122+
123+
expect(terms.length).toBeGreaterThan(0);
124+
125+
const hasDangerTerm = terms.some((term: AddonTerm) => term.type === 'danger');
126+
expect(hasDangerTerm).toBe(true);
127+
});
128+
129+
it('should handle citation service with full features', () => {
130+
const citationAddonWithFullFeatures: Addon = {
131+
...mockAddon,
132+
supportedFeatures: ['STORAGE', 'FORKING'],
133+
};
134+
135+
mockIsCitationAddon.mockReturnValue(true);
136+
fixture.componentRef.setInput('addon', citationAddonWithFullFeatures);
137+
138+
const terms = (component as any).terms();
139+
140+
expect(terms.length).toBeGreaterThan(0);
141+
142+
const hasInfoTerm = terms.some((term: AddonTerm) => term.type === 'info');
143+
expect(hasInfoTerm).toBe(true);
144+
});
145+
146+
it('should handle null addon input', () => {
147+
fixture.componentRef.setInput('addon', null);
148+
149+
const terms = (component as any).terms();
150+
151+
expect(terms).toEqual([]);
152+
});
153+
154+
it('should handle undefined addon input', () => {
155+
fixture.componentRef.setInput('addon', undefined);
156+
157+
const terms = (component as any).terms();
158+
159+
expect(terms).toEqual([]);
160+
});
161+
162+
it('should handle addon with empty supportedFeatures', () => {
163+
const addonWithEmptyFeatures: Addon = {
164+
...mockAddon,
165+
supportedFeatures: [],
166+
};
167+
168+
mockIsCitationAddon.mockReturnValue(false);
169+
fixture.componentRef.setInput('addon', addonWithEmptyFeatures);
170+
171+
const terms = (component as any).terms();
172+
173+
expect(terms.length).toBeGreaterThan(0);
174+
175+
terms.forEach((term: AddonTerm) => {
176+
expect(term.type).toBe('danger');
177+
});
178+
});
179+
180+
it('should handle addon with partial features only', () => {
181+
const addonWithPartialOnly: Addon = {
182+
...mockAddon,
183+
supportedFeatures: ['STORAGE_PARTIAL', 'FORKING_PARTIAL'],
184+
};
185+
186+
mockIsCitationAddon.mockReturnValue(false);
187+
fixture.componentRef.setInput('addon', addonWithPartialOnly);
188+
189+
const terms = (component as any).terms();
190+
191+
expect(terms.length).toBeGreaterThan(0);
192+
193+
const hasWarningTerm = terms.some((term: AddonTerm) => term.type === 'warning');
194+
expect(hasWarningTerm).toBe(true);
195+
});
196+
197+
it('should handle addon with mixed features (full, partial, none)', () => {
198+
const addonWithMixedFeatures: Addon = {
199+
...mockAddon,
200+
supportedFeatures: ['STORAGE', 'FORKING_PARTIAL'],
201+
};
202+
mockIsCitationAddon.mockReturnValue(false);
203+
fixture.componentRef.setInput('addon', addonWithMixedFeatures);
204+
205+
const terms = (component as any).terms();
206+
207+
expect(terms.length).toBeGreaterThan(0);
208+
209+
const hasInfoTerm = terms.some((term: AddonTerm) => term.type === 'info');
210+
const hasWarningTerm = terms.some((term: AddonTerm) => term.type === 'warning');
211+
const hasDangerTerm = terms.some((term: AddonTerm) => term.type === 'danger');
212+
213+
expect(hasInfoTerm || hasWarningTerm || hasDangerTerm).toBe(true);
214+
});
94215
});

src/app/shared/components/contributors/contributors-list/contributors-list.component.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,12 @@ describe('ContributorsListComponent', () => {
125125
id: 'minimal-id',
126126
userId: 'minimal-user-id',
127127
type: 'user',
128+
isBibliographic: true,
129+
isCurator: true,
128130
fullName: 'Minimal User',
131+
givenName: 'Minimal User',
132+
familyName: 'Minimal User',
129133
permission: 'read',
130-
isBibliographic: false,
131-
isCurator: false,
132134
education: [],
133135
employment: [],
134136
};

src/app/shared/components/education-history-dialog/education-history-dialog.component.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
import { MockProvider } from 'ng-mocks';
2+
3+
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
4+
15
import { ComponentFixture, TestBed } from '@angular/core/testing';
26

7+
import { TranslateServiceMock } from '@osf/shared/mocks';
8+
39
import { EducationHistoryDialogComponent } from './education-history-dialog.component';
410

511
describe('EducationHistoryDialogComponent', () => {
@@ -9,6 +15,7 @@ describe('EducationHistoryDialogComponent', () => {
915
beforeEach(async () => {
1016
await TestBed.configureTestingModule({
1117
imports: [EducationHistoryDialogComponent],
18+
providers: [MockProvider(DynamicDialogRef), MockProvider(DynamicDialogConfig), TranslateServiceMock],
1219
}).compileComponents();
1320

1421
fixture = TestBed.createComponent(EducationHistoryDialogComponent);
@@ -19,4 +26,11 @@ describe('EducationHistoryDialogComponent', () => {
1926
it('should create', () => {
2027
expect(component).toBeTruthy();
2128
});
29+
30+
it('should call close method successfully', () => {
31+
const dialogRef = TestBed.inject(DynamicDialogRef);
32+
jest.spyOn(dialogRef, 'close');
33+
component.close();
34+
expect(dialogRef.close).toHaveBeenCalledTimes(1);
35+
});
2236
});

0 commit comments

Comments
 (0)