Skip to content

Commit 2a6b2f1

Browse files
authored
[ENG-10255] Part 3: Added unit tests for pages components in registries (#885)
- Ticket: [ENG-10255] - Feature flag: n/a ## Summary of Changes 1. Added unit tests for components in registries.
1 parent b6e7d56 commit 2a6b2f1

File tree

42 files changed

+2270
-1168
lines changed

Some content is hidden

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

42 files changed

+2270
-1168
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ describe('MyProjectsComponent', () => {
4848
{ selector: MyResourcesSelectors.getTotalProjects, value: 0 },
4949
{ selector: MyResourcesSelectors.getTotalRegistrations, value: 0 },
5050
{ selector: MyResourcesSelectors.getTotalPreprints, value: 0 },
51-
{ selector: MyResourcesSelectors.getTotalBookmarks, value: 0 },
51+
{ selector: BookmarksSelectors.getBookmarksTotalCount, value: 0 },
5252
{ selector: BookmarksSelectors.getBookmarksCollectionId, value: null },
5353
{ selector: MyResourcesSelectors.getProjects, value: [] },
5454
{ selector: MyResourcesSelectors.getRegistrations, value: [] },
5555
{ selector: MyResourcesSelectors.getPreprints, value: [] },
56-
{ selector: MyResourcesSelectors.getBookmarks, value: [] },
56+
{ selector: BookmarksSelectors.getBookmarks, value: [] },
5757
],
5858
}),
5959
{ provide: ActivatedRoute, useValue: mockActivatedRoute },

src/app/features/project/overview/components/overview-collections/overview-collections.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
22

33
import { collectionFilterNames } from '@osf/features/collections/constants';
4-
import { CollectionSubmission } from '@osf/shared/models/collections/collections.models';
4+
import { CollectionSubmission } from '@osf/shared/models/collections/collections.model';
55

66
import { OverviewCollectionsComponent } from './overview-collections.component';
77

src/app/features/registries/components/confirm-continue-editing-dialog/confirm-continue-editing-dialog.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
class="w-12rem btn-full-width"
1111
[label]="'common.buttons.cancel' | translate"
1212
severity="info"
13-
(click)="dialogRef.close()"
13+
(onClick)="dialogRef.close()"
1414
/>
1515
<p-button
1616
class="w-12rem btn-full-width"
1717
[loading]="isSubmitting"
1818
[label]="'common.buttons.submit' | translate"
19-
(click)="submit()"
19+
(onClick)="submit()"
2020
/>
2121
</div>
2222
</form>
Lines changed: 28 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,42 @@
1+
import { Store } from '@ngxs/store';
2+
13
import { MockProvider } from 'ng-mocks';
24

35
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
46

5-
import { of } from 'rxjs';
6-
77
import { ComponentFixture, TestBed } from '@angular/core/testing';
88

99
import { SchemaActionTrigger } from '@osf/features/registries/enums';
10+
import { HandleSchemaResponse } from '@osf/features/registries/store';
1011

1112
import { ConfirmContinueEditingDialogComponent } from './confirm-continue-editing-dialog.component';
1213

13-
import { OSFTestingModule } from '@testing/osf.testing.module';
14+
import { provideDynamicDialogRefMock } from '@testing/mocks/dynamic-dialog-ref.mock';
15+
import { provideOSFCore } from '@testing/osf.testing.provider';
1416
import { provideMockStore } from '@testing/providers/store-provider.mock';
1517

1618
describe('ConfirmContinueEditingDialogComponent', () => {
1719
let component: ConfirmContinueEditingDialogComponent;
1820
let fixture: ComponentFixture<ConfirmContinueEditingDialogComponent>;
19-
let mockDialogRef: DynamicDialogRef;
20-
let mockDialogConfig: jest.Mocked<DynamicDialogConfig>;
21+
let store: Store;
22+
let dialogRef: DynamicDialogRef;
2123

2224
const MOCK_REVISION_ID = 'test-revision-id';
2325

24-
beforeEach(async () => {
25-
mockDialogRef = {
26-
close: jest.fn(),
27-
} as any;
28-
29-
mockDialogConfig = {
30-
data: { revisionId: MOCK_REVISION_ID },
31-
} as jest.Mocked<DynamicDialogConfig>;
32-
33-
await TestBed.configureTestingModule({
34-
imports: [ConfirmContinueEditingDialogComponent, OSFTestingModule],
26+
beforeEach(() => {
27+
TestBed.configureTestingModule({
28+
imports: [ConfirmContinueEditingDialogComponent],
3529
providers: [
36-
MockProvider(DynamicDialogRef, mockDialogRef),
37-
MockProvider(DynamicDialogConfig, mockDialogConfig),
38-
provideMockStore({
39-
signals: [],
40-
}),
30+
provideOSFCore(),
31+
provideDynamicDialogRefMock(),
32+
// MockProvider(DynamicDialogRef),
33+
MockProvider(DynamicDialogConfig, { data: { revisionId: MOCK_REVISION_ID } }),
34+
provideMockStore(),
4135
],
42-
}).compileComponents();
36+
});
4337

38+
store = TestBed.inject(Store);
39+
dialogRef = TestBed.inject(DynamicDialogRef);
4440
fixture = TestBed.createComponent(ConfirmContinueEditingDialogComponent);
4541
component = fixture.componentInstance;
4642
fixture.detectChanges();
@@ -54,87 +50,27 @@ describe('ConfirmContinueEditingDialogComponent', () => {
5450
expect(component.isSubmitting).toBe(false);
5551
});
5652

57-
it('should submit with comment', () => {
58-
const testComment = 'Test comment';
59-
component.form.patchValue({ comment: testComment });
60-
61-
const mockActions = {
62-
handleSchemaResponse: jest.fn().mockReturnValue(of({})),
63-
};
64-
65-
Object.defineProperty(component, 'actions', {
66-
value: mockActions,
67-
writable: true,
68-
});
53+
it('should dispatch handleSchemaResponse with comment on submit', () => {
54+
component.form.patchValue({ comment: 'Test comment' });
6955

7056
component.submit();
7157

72-
expect(mockActions.handleSchemaResponse).toHaveBeenCalledWith(
73-
MOCK_REVISION_ID,
74-
SchemaActionTrigger.AdminReject,
75-
testComment
58+
expect(store.dispatch).toHaveBeenCalledWith(
59+
new HandleSchemaResponse(MOCK_REVISION_ID, SchemaActionTrigger.AdminReject, 'Test comment')
7660
);
61+
expect(dialogRef.close).toHaveBeenCalledWith(true);
7762
});
7863

79-
it('should submit with empty comment', () => {
80-
const mockActions = {
81-
handleSchemaResponse: jest.fn().mockReturnValue(of({})),
82-
};
83-
84-
Object.defineProperty(component, 'actions', {
85-
value: mockActions,
86-
writable: true,
87-
});
88-
64+
it('should dispatch handleSchemaResponse with empty comment on submit', () => {
8965
component.submit();
9066

91-
expect(mockActions.handleSchemaResponse).toHaveBeenCalledWith(
92-
MOCK_REVISION_ID,
93-
SchemaActionTrigger.AdminReject,
94-
''
67+
expect(store.dispatch).toHaveBeenCalledWith(
68+
new HandleSchemaResponse(MOCK_REVISION_ID, SchemaActionTrigger.AdminReject, '')
9569
);
9670
});
9771

98-
it('should set isSubmitting to true when submitting', () => {
99-
const mockActions = {
100-
handleSchemaResponse: jest.fn().mockReturnValue(of({}).pipe()),
101-
};
102-
103-
Object.defineProperty(component, 'actions', {
104-
value: mockActions,
105-
writable: true,
106-
});
107-
108-
component.submit();
109-
expect(mockActions.handleSchemaResponse).toHaveBeenCalled();
110-
});
111-
11272
it('should update comment value', () => {
113-
const testComment = 'New comment';
114-
component.form.patchValue({ comment: testComment });
115-
116-
expect(component.form.get('comment')?.value).toBe(testComment);
117-
});
118-
119-
it('should handle different revision IDs', () => {
120-
const differentRevisionId = 'different-revision-id';
121-
(component as any).config.data = { revisionId: differentRevisionId } as any;
122-
123-
const mockActions = {
124-
handleSchemaResponse: jest.fn().mockReturnValue(of({})),
125-
};
126-
127-
Object.defineProperty(component, 'actions', {
128-
value: mockActions,
129-
writable: true,
130-
});
131-
132-
component.submit();
133-
134-
expect(mockActions.handleSchemaResponse).toHaveBeenCalledWith(
135-
differentRevisionId,
136-
SchemaActionTrigger.AdminReject,
137-
''
138-
);
73+
component.form.patchValue({ comment: 'New comment' });
74+
expect(component.form.get('comment')?.value).toBe('New comment');
13975
});
14076
});

src/app/features/registries/components/confirm-continue-editing-dialog/confirm-continue-editing-dialog.component.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,16 @@ import { HandleSchemaResponse } from '../../store';
2323
changeDetection: ChangeDetectionStrategy.OnPush,
2424
})
2525
export class ConfirmContinueEditingDialogComponent {
26-
readonly dialogRef = inject(DynamicDialogRef);
27-
private readonly fb = inject(FormBuilder);
2826
readonly config = inject(DynamicDialogConfig);
29-
private readonly destroyRef = inject(DestroyRef);
27+
readonly dialogRef = inject(DynamicDialogRef);
28+
readonly destroyRef = inject(DestroyRef);
29+
readonly fb = inject(FormBuilder);
3030

31-
actions = createDispatchMap({
32-
handleSchemaResponse: HandleSchemaResponse,
33-
});
31+
actions = createDispatchMap({ handleSchemaResponse: HandleSchemaResponse });
3432

3533
isSubmitting = false;
3634

37-
form: FormGroup = this.fb.group({
38-
comment: [''],
39-
});
35+
form: FormGroup = this.fb.group({ comment: [''] });
4036

4137
submit(): void {
4238
const comment = this.form.value.comment;
Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,50 @@
1+
import { Store } from '@ngxs/store';
2+
13
import { MockProvider } from 'ng-mocks';
24

35
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
46

5-
import { of } from 'rxjs';
7+
import { throwError } from 'rxjs';
68

79
import { ComponentFixture, TestBed } from '@angular/core/testing';
810

911
import { SubmitType } from '@osf/features/registries/enums';
10-
import { RegistriesSelectors } from '@osf/features/registries/store';
12+
import { RegisterDraft, RegistriesSelectors } from '@osf/features/registries/store';
1113

1214
import { ConfirmRegistrationDialogComponent } from './confirm-registration-dialog.component';
1315

14-
import { OSFTestingModule } from '@testing/osf.testing.module';
16+
import { provideDynamicDialogRefMock } from '@testing/mocks/dynamic-dialog-ref.mock';
17+
import { provideOSFCore } from '@testing/osf.testing.provider';
1518
import { provideMockStore } from '@testing/providers/store-provider.mock';
1619

1720
describe('ConfirmRegistrationDialogComponent', () => {
1821
let component: ConfirmRegistrationDialogComponent;
1922
let fixture: ComponentFixture<ConfirmRegistrationDialogComponent>;
20-
let mockDialogRef: DynamicDialogRef;
21-
let mockDialogConfig: jest.Mocked<DynamicDialogConfig>;
23+
let store: Store;
24+
let dialogRef: DynamicDialogRef;
2225

2326
const MOCK_CONFIG_DATA = {
2427
draftId: 'draft-1',
2528
providerId: 'provider-1',
2629
projectId: 'project-1',
27-
components: [],
30+
components: [] as string[],
2831
};
2932

30-
beforeEach(async () => {
31-
mockDialogRef = { close: jest.fn() } as any;
32-
mockDialogConfig = { data: { ...MOCK_CONFIG_DATA } } as any;
33-
34-
await TestBed.configureTestingModule({
35-
imports: [ConfirmRegistrationDialogComponent, OSFTestingModule],
33+
beforeEach(() => {
34+
TestBed.configureTestingModule({
35+
imports: [ConfirmRegistrationDialogComponent],
3636
providers: [
37-
MockProvider(DynamicDialogRef, mockDialogRef),
38-
MockProvider(DynamicDialogConfig, mockDialogConfig),
37+
provideOSFCore(),
38+
provideDynamicDialogRefMock(),
39+
MockProvider(DynamicDialogConfig, { data: { ...MOCK_CONFIG_DATA } }),
3940
provideMockStore({
4041
signals: [{ selector: RegistriesSelectors.isRegistrationSubmitting, value: false }],
4142
}),
4243
],
43-
}).compileComponents();
44+
});
4445

46+
store = TestBed.inject(Store);
47+
dialogRef = TestBed.inject(DynamicDialogRef);
4548
fixture = TestBed.createComponent(ConfirmRegistrationDialogComponent);
4649
component = fixture.componentInstance;
4750
fixture.detectChanges();
@@ -78,44 +81,60 @@ describe('ConfirmRegistrationDialogComponent', () => {
7881
expect(embargoControl?.value).toBeNull();
7982
});
8083

81-
it('should submit with immediate option and close dialog', () => {
82-
const mockActions = {
83-
registerDraft: jest.fn().mockReturnValue(of({})),
84-
};
85-
Object.defineProperty(component, 'actions', { value: mockActions, writable: true });
86-
84+
it('should dispatch registerDraft with immediate option and close dialog', () => {
8785
component.form.get('submitOption')?.setValue(SubmitType.Public);
86+
8887
component.submit();
8988

90-
expect(mockActions.registerDraft).toHaveBeenCalledWith(
91-
MOCK_CONFIG_DATA.draftId,
92-
'',
93-
MOCK_CONFIG_DATA.providerId,
94-
MOCK_CONFIG_DATA.projectId,
95-
MOCK_CONFIG_DATA.components
89+
expect(store.dispatch).toHaveBeenCalledWith(
90+
new RegisterDraft(
91+
MOCK_CONFIG_DATA.draftId,
92+
'',
93+
MOCK_CONFIG_DATA.providerId,
94+
MOCK_CONFIG_DATA.projectId,
95+
MOCK_CONFIG_DATA.components
96+
)
9697
);
97-
expect(mockDialogRef.close).toHaveBeenCalledWith(true);
98+
expect(dialogRef.close).toHaveBeenCalledWith(true);
9899
});
99100

100-
it('should submit with embargo and include ISO embargoDate', () => {
101-
const mockActions = {
102-
registerDraft: jest.fn().mockReturnValue(of({})),
103-
};
104-
Object.defineProperty(component, 'actions', { value: mockActions, writable: true });
105-
101+
it('should dispatch registerDraft with embargo and include ISO embargoDate', () => {
106102
const date = new Date('2025-01-01T00:00:00Z');
107103
component.form.get('submitOption')?.setValue(SubmitType.Embargo);
108104
component.form.get('embargoDate')?.setValue(date);
109105

110106
component.submit();
111107

112-
expect(mockActions.registerDraft).toHaveBeenCalledWith(
113-
MOCK_CONFIG_DATA.draftId,
114-
date.toISOString(),
115-
MOCK_CONFIG_DATA.providerId,
116-
MOCK_CONFIG_DATA.projectId,
117-
MOCK_CONFIG_DATA.components
108+
expect(store.dispatch).toHaveBeenCalledWith(
109+
new RegisterDraft(
110+
MOCK_CONFIG_DATA.draftId,
111+
date.toISOString(),
112+
MOCK_CONFIG_DATA.providerId,
113+
MOCK_CONFIG_DATA.projectId,
114+
MOCK_CONFIG_DATA.components
115+
)
118116
);
119-
expect(mockDialogRef.close).toHaveBeenCalledWith(true);
117+
expect(dialogRef.close).toHaveBeenCalledWith(true);
118+
});
119+
120+
it('should return a date 3 days in the future for minEmbargoDate', () => {
121+
const expected = new Date();
122+
expected.setDate(expected.getDate() + 3);
123+
124+
const result = component.minEmbargoDate();
125+
126+
expect(result.getFullYear()).toBe(expected.getFullYear());
127+
expect(result.getMonth()).toBe(expected.getMonth());
128+
expect(result.getDate()).toBe(expected.getDate());
129+
});
130+
131+
it('should re-enable form on submit error', () => {
132+
(store.dispatch as jest.Mock).mockReturnValueOnce(throwError(() => new Error('fail')));
133+
134+
component.form.get('submitOption')?.setValue(SubmitType.Public);
135+
component.submit();
136+
137+
expect(component.form.enabled).toBe(true);
138+
expect(dialogRef.close).not.toHaveBeenCalled();
120139
});
121140
});

0 commit comments

Comments
 (0)