From 07c80609081034755ceccc583f586dffa0f1216c Mon Sep 17 00:00:00 2001 From: Diana Date: Mon, 8 Sep 2025 11:04:47 +0300 Subject: [PATCH 1/4] test(my-projects): added unit tests --- jest.config.js | 1 - .../create-project-dialog.component.spec.ts | 81 +++++++-- .../my-projects/my-projects.component.spec.ts | 164 ++++++++++++++++-- src/testing/mocks/dynamic-dialog-ref.mock.ts | 8 + src/testing/osf.testing.module.ts | 3 + 5 files changed, 223 insertions(+), 34 deletions(-) create mode 100644 src/testing/mocks/dynamic-dialog-ref.mock.ts diff --git a/jest.config.js b/jest.config.js index fe3f13fc9..ea0134d96 100644 --- a/jest.config.js +++ b/jest.config.js @@ -68,7 +68,6 @@ module.exports = { '/src/app/features/project/addons/components/disconnect-addon-modal/', '/src/app/features/project/addons/components/confirm-account-connection-modal/', '/src/app/features/files/', - '/src/app/features/my-projects/', '/src/app/features/preprints/', '/src/app/features/project/contributors/', '/src/app/features/project/overview/', diff --git a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts index 4887cb925..2e0c4eab6 100644 --- a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts +++ b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts @@ -1,43 +1,90 @@ -import { provideStore } from '@ngxs/store'; +import { Store } from '@ngxs/store'; -import { TranslatePipe } from '@ngx-translate/core'; -import { MockPipe, MockProvider } from 'ng-mocks'; +import { MockProvider } from 'ng-mocks'; import { DynamicDialogRef } from 'primeng/dynamicdialog'; -import { provideHttpClient } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { of } from 'rxjs'; + import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { TranslateServiceMock } from '@shared/mocks'; -import { MyResourcesState } from '@shared/stores'; -import { InstitutionsState } from '@shared/stores/institutions'; -import { RegionsState } from '@shared/stores/regions'; +import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; +import { ProjectFormControls } from '@osf/shared/enums'; +import { CreateProject, GetMyProjects } from '@osf/shared/stores'; import { CreateProjectDialogComponent } from './create-project-dialog.component'; +import { OSFTestingModule, OSFTestingStoreModule } from '@testing/osf.testing.module'; + describe('CreateProjectDialogComponent', () => { let component: CreateProjectDialogComponent; let fixture: ComponentFixture; + let store: jest.Mocked; + let dialogRef: { close: jest.Mock }; + + const fillValidForm = ( + title = 'My Project', + description = 'Some description', + template = 'tmpl-1', + storageLocation = 'osfstorage', + affiliations: string[] = ['aff-1', 'aff-2'] + ) => { + component.projectForm.patchValue({ + [ProjectFormControls.Title]: title, + [ProjectFormControls.Description]: description, + [ProjectFormControls.Template]: template, + [ProjectFormControls.StorageLocation]: storageLocation, + [ProjectFormControls.Affiliations]: affiliations, + }); + }; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CreateProjectDialogComponent, MockPipe(TranslatePipe)], - providers: [ - provideStore([MyResourcesState, InstitutionsState, RegionsState]), - provideHttpClient(), - provideHttpClientTesting(), - TranslateServiceMock, - MockProvider(DynamicDialogRef), - ], + imports: [CreateProjectDialogComponent, OSFTestingModule, OSFTestingStoreModule], + providers: [MockProvider(DynamicDialogRef, { close: jest.fn() })], }).compileComponents(); fixture = TestBed.createComponent(CreateProjectDialogComponent); component = fixture.componentInstance; + + store = TestBed.inject(Store) as jest.Mocked; + dialogRef = TestBed.inject(DynamicDialogRef) as unknown as { close: jest.Mock }; + fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should mark all controls touched and not dispatch when form is invalid', () => { + const markAllSpy = jest.spyOn(component.projectForm, 'markAllAsTouched'); + + component.submitForm(); + + expect(markAllSpy).toHaveBeenCalled(); + expect(store.dispatch).not.toHaveBeenCalled(); + }); + + it('should submit, refresh list and close dialog when form is valid', () => { + fillValidForm('Title', 'Desc', 'Tpl', 'Storage', ['a1']); + + store.dispatch.mockReturnValue(of(undefined)); + + component.submitForm(); + + expect(store.dispatch).toHaveBeenCalledWith(new CreateProject('Title', 'Desc', 'Tpl', 'Storage', ['a1'])); + expect(store.dispatch).toHaveBeenCalledWith(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); + expect(dialogRef.close).toHaveBeenCalled(); + }); + + it('should invalidate title when only spaces provided', () => { + fillValidForm(' ', 'Desc', 'Tpl', 'Storage', []); + expect(component.projectForm.get(ProjectFormControls.Title)?.valid).toBe(false); + }); + + it('should be valid when required fields are set', () => { + fillValidForm('Valid title', '', '', 'Storage', []); + expect(component.projectForm.valid).toBe(true); + }); }); diff --git a/src/app/features/my-projects/my-projects.component.spec.ts b/src/app/features/my-projects/my-projects.component.spec.ts index 7f1b2b689..6cbedeeb5 100644 --- a/src/app/features/my-projects/my-projects.component.spec.ts +++ b/src/app/features/my-projects/my-projects.component.spec.ts @@ -1,50 +1,182 @@ -import { provideStore } from '@ngxs/store'; +import { Store } from '@ngxs/store'; -import { TranslateModule } from '@ngx-translate/core'; -import { MockProvider } from 'ng-mocks'; +import { MockComponents, MockProvider } from 'ng-mocks'; import { DialogService } from 'primeng/dynamicdialog'; import { BehaviorSubject, of } from 'rxjs'; -import { provideHttpClient } from '@angular/common/http'; -import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MyProjectsTab } from '@osf/features/my-projects/enums'; +import { SortOrder } from '@osf/shared/enums'; import { IS_MEDIUM } from '@osf/shared/helpers'; -import { MyResourcesState } from '@shared/stores/my-resources/my-resources.state'; - -import { InstitutionsState } from '../../shared/stores/institutions'; +import { GetMyProjects } from '@osf/shared/stores'; +import { MyProjectsTableComponent, SelectComponent, SubHeaderComponent } from '@shared/components'; import { MyProjectsComponent } from './my-projects.component'; -describe.skip('MyProjectsComponent', () => { +import { OSFTestingModule, OSFTestingStoreModule } from '@testing/osf.testing.module'; + +describe('MyProjectsComponent', () => { let component: MyProjectsComponent; let fixture: ComponentFixture; let isMediumSubject: BehaviorSubject; + let queryParamsSubject: BehaviorSubject>; + let store: jest.Mocked; + let router: jest.Mocked; beforeEach(async () => { isMediumSubject = new BehaviorSubject(false); + queryParamsSubject = new BehaviorSubject>({}); await TestBed.configureTestingModule({ - imports: [MyProjectsComponent, TranslateModule.forRoot()], + imports: [ + MyProjectsComponent, + OSFTestingModule, + OSFTestingStoreModule, + ...MockComponents(SubHeaderComponent, MyProjectsTableComponent, SelectComponent), + ], providers: [ - provideStore([MyResourcesState, InstitutionsState]), - provideHttpClient(), - provideHttpClientTesting(), - MockProvider(DialogService), - MockProvider(ActivatedRoute, { queryParams: of({}) }), + MockProvider(DialogService, { open: jest.fn() }), + MockProvider(ActivatedRoute, { queryParams: queryParamsSubject.asObservable() }), + MockProvider(Router, { navigate: jest.fn() }), MockProvider(IS_MEDIUM, isMediumSubject), ], }).compileComponents(); fixture = TestBed.createComponent(MyProjectsComponent); component = fixture.componentInstance; + store = TestBed.inject(Store) as jest.Mocked; + router = TestBed.inject(Router) as jest.Mocked; + + store.dispatch.mockReturnValue(of(undefined)); + fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should update component state from query params', () => { + component.updateComponentState({ page: 2, size: 20, search: 'q', sortColumn: 'name', sortOrder: SortOrder.Desc }); + + expect(component.currentPage()).toBe(2); + expect(component.currentPageSize()).toBe(20); + expect(component.searchControl.value).toBe('q'); + expect(component.sortColumn()).toBe('name'); + expect(component.sortOrder()).toBe(SortOrder.Desc); + expect(component.tableParams().firstRowIndex).toBe(20); + expect(component.tableParams().rows).toBe(20); + }); + + it('should create filters depending on tab', () => { + const filtersProjects = component.createFilters({ + page: 1, + size: 10, + search: 's', + sortColumn: 'name', + sortOrder: SortOrder.Asc, + }); + expect(filtersProjects.searchValue).toBe('s'); + expect(filtersProjects.searchFields).toEqual(['title', 'tags', 'description']); + + component.selectedTab.set(MyProjectsTab.Preprints); + const filtersPreprints = component.createFilters({ + page: 2, + size: 25, + search: 's2', + sortColumn: 'date', + sortOrder: SortOrder.Desc, + }); + expect(filtersPreprints.searchFields).toEqual(['title', 'tags']); + }); + + it('should fetch data for projects tab and stop loading', () => { + jest.clearAllMocks(); + store.dispatch.mockReturnValue(of(undefined)); + + component.fetchDataForCurrentTab({ page: 1, size: 10, search: 's', sortColumn: 'name', sortOrder: SortOrder.Asc }); + + expect(store.dispatch).toHaveBeenCalledWith(expect.any(GetMyProjects)); + expect(component.isLoading()).toBe(false); + }); + + it('should handle search and update query params', () => { + jest.clearAllMocks(); + queryParamsSubject.next({ sortColumn: 'name', sortOrder: 'desc', size: '25' }); + + component.handleSearch('query'); + + expect(router.navigate).toHaveBeenCalledWith([], { + relativeTo: expect.anything(), + queryParams: { page: '1', size: '25', search: 'query', sortColumn: 'name', sortOrder: 'desc' }, + }); + }); + + it('should paginate and update query params', () => { + jest.clearAllMocks(); + queryParamsSubject.next({ sortColumn: 'title', sortOrder: 'asc' }); + + component.onPageChange({ first: 30, rows: 15 } as any); + + expect(router.navigate).toHaveBeenCalledWith([], { + relativeTo: expect.anything(), + queryParams: { page: '3', size: '15', sortColumn: 'title', sortOrder: 'asc' }, + }); + }); + + it('should sort and update query params', () => { + jest.clearAllMocks(); + + component.onSort({ field: 'updated', order: SortOrder.Desc } as any); + + expect(router.navigate).toHaveBeenCalledWith([], { + relativeTo: expect.anything(), + queryParams: { sortColumn: 'updated', sortOrder: 'desc' }, + }); + }); + + it('should clear and reset on tab change', () => { + jest.clearAllMocks(); + queryParamsSubject.next({ size: '50' }); + + component.onTabChange(1); + + expect(router.navigate).toHaveBeenCalledWith([], { + relativeTo: expect.anything(), + queryParams: { page: '1', size: '50' }, + }); + + expect(store.dispatch).toHaveBeenCalled(); + }); + + it('should open create project dialog with responsive width', () => { + const openSpy = jest.spyOn(component.dialogService, 'open'); + + isMediumSubject.next(false); + component.createProject(); + expect(openSpy).toHaveBeenCalledWith(expect.any(Function), expect.objectContaining({ width: '95vw' })); + + openSpy.mockClear(); + isMediumSubject.next(true); + component.createProject(); + expect(openSpy).toHaveBeenCalledWith(expect.any(Function), expect.objectContaining({ width: '850px' })); + }); + + it('should navigate to project and set active project', () => { + const project = { id: 'p1' } as any; + component.navigateToProject(project); + expect(component.activeProject()).toEqual(project); + expect(router.navigate).toHaveBeenCalledWith(['p1']); + }); + + it('should navigate to registry and set active project', () => { + const reg = { id: 'r1' } as any; + component.navigateToRegistry(reg); + expect(component.activeProject()).toEqual(reg); + expect(router.navigate).toHaveBeenCalledWith(['r1']); + }); }); diff --git a/src/testing/mocks/dynamic-dialog-ref.mock.ts b/src/testing/mocks/dynamic-dialog-ref.mock.ts new file mode 100644 index 000000000..091508d9e --- /dev/null +++ b/src/testing/mocks/dynamic-dialog-ref.mock.ts @@ -0,0 +1,8 @@ +import { DynamicDialogRef } from 'primeng/dynamicdialog'; + +export const DynamicDialogRefMock = { + provide: DynamicDialogRef, + useValue: { + close: jest.fn(), + }, +}; diff --git a/src/testing/osf.testing.module.ts b/src/testing/osf.testing.module.ts index fd30cfa44..8f8f49b5c 100644 --- a/src/testing/osf.testing.module.ts +++ b/src/testing/osf.testing.module.ts @@ -13,6 +13,8 @@ import { StoreMock } from './mocks/store.mock'; import { ToastServiceMock } from './mocks/toast.service.mock'; import { TranslationServiceMock } from './mocks/translation.service.mock'; +import { DynamicDialogRefMock } from '@testing/mocks/dynamic-dialog-ref.mock'; + @NgModule({ imports: [NoopAnimationsModule, BrowserModule, CommonModule, TranslateModule.forRoot()], providers: [ @@ -21,6 +23,7 @@ import { TranslationServiceMock } from './mocks/translation.service.mock'; provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting(), TranslationServiceMock, + DynamicDialogRefMock, EnvironmentTokenMock, ], }) From 8934767a88cbdc8482430e39773c32b6f0affa71 Mon Sep 17 00:00:00 2001 From: Diana Date: Mon, 8 Sep 2025 12:11:11 +0300 Subject: [PATCH 2/4] test(create-project-dialog): fixed errors --- .../create-project-dialog.component.spec.ts | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts index 2e0c4eab6..c6e4d8097 100644 --- a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts +++ b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts @@ -8,19 +8,22 @@ import { of } from 'rxjs'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { UserSelectors } from '@osf/core/store/user'; import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; import { ProjectFormControls } from '@osf/shared/enums'; -import { CreateProject, GetMyProjects } from '@osf/shared/stores'; +import { MOCK_STORE } from '@osf/shared/mocks'; +import { CreateProject, GetMyProjects, InstitutionsSelectors, MyResourcesSelectors } from '@osf/shared/stores'; +import { ProjectsSelectors } from '@osf/shared/stores/projects/projects.selectors'; import { CreateProjectDialogComponent } from './create-project-dialog.component'; -import { OSFTestingModule, OSFTestingStoreModule } from '@testing/osf.testing.module'; +import { OSFTestingModule } from '@testing/osf.testing.module'; describe('CreateProjectDialogComponent', () => { let component: CreateProjectDialogComponent; let fixture: ComponentFixture; - let store: jest.Mocked; - let dialogRef: { close: jest.Mock }; + let store: Store; + let dialogRef: DynamicDialogRef; const fillValidForm = ( title = 'My Project', @@ -39,16 +42,29 @@ describe('CreateProjectDialogComponent', () => { }; beforeEach(async () => { + (MOCK_STORE.selectSignal as jest.Mock).mockImplementation((selector) => { + if (selector === MyResourcesSelectors.isProjectSubmitting) return () => false; + if (selector === InstitutionsSelectors.getUserInstitutions) return () => []; + if (selector === InstitutionsSelectors.areUserInstitutionsLoading) return () => false; + if (selector === InstitutionsSelectors.getResourceInstitutions) return () => []; + if (selector === InstitutionsSelectors.areResourceInstitutionsLoading) return () => false; + if (selector === InstitutionsSelectors.areResourceInstitutionsSubmitting) return () => false; + if (selector === ProjectsSelectors.getProjects) return () => []; + if (selector === ProjectsSelectors.getProjectsLoading) return () => false; + if (selector === UserSelectors.getCurrentUser) return () => null; + return () => undefined; + }); + await TestBed.configureTestingModule({ - imports: [CreateProjectDialogComponent, OSFTestingModule, OSFTestingStoreModule], - providers: [MockProvider(DynamicDialogRef, { close: jest.fn() })], + imports: [CreateProjectDialogComponent, OSFTestingModule], + providers: [MockProvider(Store, MOCK_STORE)], }).compileComponents(); fixture = TestBed.createComponent(CreateProjectDialogComponent); component = fixture.componentInstance; - store = TestBed.inject(Store) as jest.Mocked; - dialogRef = TestBed.inject(DynamicDialogRef) as unknown as { close: jest.Mock }; + store = TestBed.inject(Store); + dialogRef = TestBed.inject(DynamicDialogRef); fixture.detectChanges(); }); @@ -60,6 +76,8 @@ describe('CreateProjectDialogComponent', () => { it('should mark all controls touched and not dispatch when form is invalid', () => { const markAllSpy = jest.spyOn(component.projectForm, 'markAllAsTouched'); + (store.dispatch as unknown as jest.Mock).mockClear(); + component.submitForm(); expect(markAllSpy).toHaveBeenCalled(); @@ -69,13 +87,13 @@ describe('CreateProjectDialogComponent', () => { it('should submit, refresh list and close dialog when form is valid', () => { fillValidForm('Title', 'Desc', 'Tpl', 'Storage', ['a1']); - store.dispatch.mockReturnValue(of(undefined)); + (MOCK_STORE.dispatch as jest.Mock).mockReturnValue(of(undefined)); component.submitForm(); - expect(store.dispatch).toHaveBeenCalledWith(new CreateProject('Title', 'Desc', 'Tpl', 'Storage', ['a1'])); - expect(store.dispatch).toHaveBeenCalledWith(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); - expect(dialogRef.close).toHaveBeenCalled(); + expect(MOCK_STORE.dispatch).toHaveBeenCalledWith(new CreateProject('Title', 'Desc', 'Tpl', 'Storage', ['a1'])); + expect(MOCK_STORE.dispatch).toHaveBeenCalledWith(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); + expect((dialogRef as any).close).toHaveBeenCalled(); }); it('should invalidate title when only spaces provided', () => { From 1ccbc3ff56bc4105af452c069a1cd47b10a0c165 Mon Sep 17 00:00:00 2001 From: Diana Date: Mon, 8 Sep 2025 12:30:38 +0300 Subject: [PATCH 3/4] test(my-projects): fixed errors --- jest.config.js | 1 - .../my-projects/my-projects.component.spec.ts | 26 ++++++++++++++++--- src/testing/osf.testing.module.ts | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/jest.config.js b/jest.config.js index 49577581b..ccef4bc7e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -70,7 +70,6 @@ module.exports = { '/src/app/features/files/components', '/src/app/features/files/pages/community-metadata', '/src/app/features/files/pages/file-detail', - '/src/app/features/my-projects/', '/src/app/features/preprints/', '/src/app/features/project/contributors/', '/src/app/features/project/overview/', diff --git a/src/app/features/my-projects/my-projects.component.spec.ts b/src/app/features/my-projects/my-projects.component.spec.ts index 6cbedeeb5..037918721 100644 --- a/src/app/features/my-projects/my-projects.component.spec.ts +++ b/src/app/features/my-projects/my-projects.component.spec.ts @@ -12,12 +12,13 @@ import { ActivatedRoute, Router } from '@angular/router'; import { MyProjectsTab } from '@osf/features/my-projects/enums'; import { SortOrder } from '@osf/shared/enums'; import { IS_MEDIUM } from '@osf/shared/helpers'; -import { GetMyProjects } from '@osf/shared/stores'; +import { MOCK_STORE } from '@osf/shared/mocks'; +import { BookmarksSelectors, GetMyProjects, MyResourcesSelectors } from '@osf/shared/stores'; import { MyProjectsTableComponent, SelectComponent, SubHeaderComponent } from '@shared/components'; import { MyProjectsComponent } from './my-projects.component'; -import { OSFTestingModule, OSFTestingStoreModule } from '@testing/osf.testing.module'; +import { OSFTestingModule } from '@testing/osf.testing.module'; describe('MyProjectsComponent', () => { let component: MyProjectsComponent; @@ -31,14 +32,33 @@ describe('MyProjectsComponent', () => { isMediumSubject = new BehaviorSubject(false); queryParamsSubject = new BehaviorSubject>({}); + (MOCK_STORE.selectSignal as jest.Mock).mockImplementation((selector) => { + if ( + selector === MyResourcesSelectors.getTotalProjects || + selector === MyResourcesSelectors.getTotalRegistrations || + selector === MyResourcesSelectors.getTotalPreprints || + selector === MyResourcesSelectors.getTotalBookmarks + ) + return () => 0; + if (selector === BookmarksSelectors.getBookmarksCollectionId) return () => null; + if ( + selector === MyResourcesSelectors.getProjects || + selector === MyResourcesSelectors.getRegistrations || + selector === MyResourcesSelectors.getPreprints || + selector === MyResourcesSelectors.getBookmarks + ) + return () => []; + return () => undefined; + }); + await TestBed.configureTestingModule({ imports: [ MyProjectsComponent, OSFTestingModule, - OSFTestingStoreModule, ...MockComponents(SubHeaderComponent, MyProjectsTableComponent, SelectComponent), ], providers: [ + MockProvider(Store, MOCK_STORE), MockProvider(DialogService, { open: jest.fn() }), MockProvider(ActivatedRoute, { queryParams: queryParamsSubject.asObservable() }), MockProvider(Router, { navigate: jest.fn() }), diff --git a/src/testing/osf.testing.module.ts b/src/testing/osf.testing.module.ts index 718365a25..a4e376233 100644 --- a/src/testing/osf.testing.module.ts +++ b/src/testing/osf.testing.module.ts @@ -8,6 +8,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { NoopAnimationsModule, provideNoopAnimations } from '@angular/platform-browser/animations'; import { provideRouter } from '@angular/router'; +import { DynamicDialogRefMock } from './mocks/dynamic-dialog-ref.mock'; import { EnvironmentTokenMock } from './mocks/environment.token.mock'; import { StoreMock } from './mocks/store.mock'; import { ToastServiceMock } from './mocks/toast.service.mock'; From 749e529a96d821032a761effdb1eb05a36d2f81d Mon Sep 17 00:00:00 2001 From: Diana Date: Mon, 8 Sep 2025 14:08:17 +0300 Subject: [PATCH 4/4] test(create-project-dialog): fixed --- .../create-project-dialog.component.spec.ts | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts index c6e4d8097..8352284b6 100644 --- a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts +++ b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts @@ -1,6 +1,6 @@ import { Store } from '@ngxs/store'; -import { MockProvider } from 'ng-mocks'; +import { MockComponent, MockProvider } from 'ng-mocks'; import { DynamicDialogRef } from 'primeng/dynamicdialog'; @@ -8,12 +8,11 @@ import { of } from 'rxjs'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { UserSelectors } from '@osf/core/store/user'; import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; import { ProjectFormControls } from '@osf/shared/enums'; import { MOCK_STORE } from '@osf/shared/mocks'; -import { CreateProject, GetMyProjects, InstitutionsSelectors, MyResourcesSelectors } from '@osf/shared/stores'; -import { ProjectsSelectors } from '@osf/shared/stores/projects/projects.selectors'; +import { CreateProject, GetMyProjects, MyResourcesSelectors } from '@osf/shared/stores'; +import { AddProjectFormComponent } from '@shared/components'; import { CreateProjectDialogComponent } from './create-project-dialog.component'; @@ -44,19 +43,11 @@ describe('CreateProjectDialogComponent', () => { beforeEach(async () => { (MOCK_STORE.selectSignal as jest.Mock).mockImplementation((selector) => { if (selector === MyResourcesSelectors.isProjectSubmitting) return () => false; - if (selector === InstitutionsSelectors.getUserInstitutions) return () => []; - if (selector === InstitutionsSelectors.areUserInstitutionsLoading) return () => false; - if (selector === InstitutionsSelectors.getResourceInstitutions) return () => []; - if (selector === InstitutionsSelectors.areResourceInstitutionsLoading) return () => false; - if (selector === InstitutionsSelectors.areResourceInstitutionsSubmitting) return () => false; - if (selector === ProjectsSelectors.getProjects) return () => []; - if (selector === ProjectsSelectors.getProjectsLoading) return () => false; - if (selector === UserSelectors.getCurrentUser) return () => null; return () => undefined; }); await TestBed.configureTestingModule({ - imports: [CreateProjectDialogComponent, OSFTestingModule], + imports: [CreateProjectDialogComponent, OSFTestingModule, MockComponent(AddProjectFormComponent)], providers: [MockProvider(Store, MOCK_STORE)], }).compileComponents(); @@ -95,14 +86,4 @@ describe('CreateProjectDialogComponent', () => { expect(MOCK_STORE.dispatch).toHaveBeenCalledWith(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); expect((dialogRef as any).close).toHaveBeenCalled(); }); - - it('should invalidate title when only spaces provided', () => { - fillValidForm(' ', 'Desc', 'Tpl', 'Storage', []); - expect(component.projectForm.get(ProjectFormControls.Title)?.valid).toBe(false); - }); - - it('should be valid when required fields are set', () => { - fillValidForm('Valid title', '', '', 'Storage', []); - expect(component.projectForm.valid).toBe(true); - }); });