Skip to content
Original file line number Diff line number Diff line change
@@ -1,75 +1,82 @@
import { Store } from '@ngxs/store';

import { MockComponent } from 'ng-mocks';

import { signal, WritableSignal } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';

import { AffiliatedInstitutionSelectComponent } from '@osf/shared/components/affiliated-institution-select/affiliated-institution-select.component';
import { InstitutionsSelectors } from '@osf/shared/stores/institutions';
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
import { Institution } from '@osf/shared/models/institutions/institutions.model';
import {
FetchResourceInstitutions,
FetchUserInstitutions,
InstitutionsSelectors,
UpdateResourceInstitutions,
} from '@osf/shared/stores/institutions';

import { RegistriesAffiliatedInstitutionComponent } from './registries-affiliated-institution.component';

import { OSFTestingModule } from '@testing/osf.testing.module';
import { ActivatedRouteMockBuilder } from '@testing/providers/route-provider.mock';
import { MOCK_INSTITUTION } from '@testing/mocks/institution.mock';
import { provideOSFCore } from '@testing/osf.testing.provider';
import { provideMockStore } from '@testing/providers/store-provider.mock';

describe('RegistriesAffiliatedInstitutionComponent', () => {
let component: RegistriesAffiliatedInstitutionComponent;
let fixture: ComponentFixture<RegistriesAffiliatedInstitutionComponent>;
let mockActivatedRoute: ReturnType<ActivatedRouteMockBuilder['build']>;
let store: Store;
let resourceInstitutionsSignal: WritableSignal<Institution[]>;

beforeEach(async () => {
mockActivatedRoute = ActivatedRouteMockBuilder.create().withParams({ id: 'draft-1' }).build();
beforeEach(() => {
resourceInstitutionsSignal = signal<Institution[]>([]);

await TestBed.configureTestingModule({
imports: [
RegistriesAffiliatedInstitutionComponent,
OSFTestingModule,
MockComponent(AffiliatedInstitutionSelectComponent),
],
TestBed.configureTestingModule({
imports: [RegistriesAffiliatedInstitutionComponent, MockComponent(AffiliatedInstitutionSelectComponent)],
providers: [
{ provide: ActivatedRoute, useValue: mockActivatedRoute },
provideOSFCore(),
provideMockStore({
signals: [
{ selector: InstitutionsSelectors.getUserInstitutions, value: [] },
{ selector: InstitutionsSelectors.areUserInstitutionsLoading, value: false },
{ selector: InstitutionsSelectors.getResourceInstitutions, value: [] },
{ selector: InstitutionsSelectors.getResourceInstitutions, value: resourceInstitutionsSignal },
{ selector: InstitutionsSelectors.areResourceInstitutionsLoading, value: false },
{ selector: InstitutionsSelectors.areResourceInstitutionsSubmitting, value: false },
],
}),
],
}).compileComponents();
});

store = TestBed.inject(Store);
fixture = TestBed.createComponent(RegistriesAffiliatedInstitutionComponent);
component = fixture.componentInstance;
fixture.componentRef.setInput('draftId', 'draft-1');
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should dispatch updateResourceInstitutions on selection', () => {
const actionsMock = {
updateResourceInstitutions: jest.fn(),
fetchUserInstitutions: jest.fn(),
fetchResourceInstitutions: jest.fn(),
} as any;
Object.defineProperty(component, 'actions', { value: actionsMock });
const selected = [{ id: 'i2' }] as any;
component.institutionsSelected(selected);
expect(actionsMock.updateResourceInstitutions).toHaveBeenCalledWith('draft-1', 8, selected);
it('should dispatch fetchUserInstitutions and fetchResourceInstitutions on init', () => {
expect(store.dispatch).toHaveBeenCalledWith(new FetchUserInstitutions());
expect(store.dispatch).toHaveBeenCalledWith(
new FetchResourceInstitutions('draft-1', ResourceType.DraftRegistration)
);
});

it('should fetch user and resource institutions on init', () => {
const actionsMock = {
updateResourceInstitutions: jest.fn(),
fetchUserInstitutions: jest.fn(),
fetchResourceInstitutions: jest.fn(),
} as any;
Object.defineProperty(component, 'actions', { value: actionsMock });
component.ngOnInit();
expect(actionsMock.fetchUserInstitutions).toHaveBeenCalled();
expect(actionsMock.fetchResourceInstitutions).toHaveBeenCalledWith('draft-1', 8);
it('should sync selectedInstitutions when resourceInstitutions emits', () => {
const institutions: Institution[] = [MOCK_INSTITUTION as Institution];
resourceInstitutionsSignal.set(institutions);
fixture.detectChanges();
expect(component.selectedInstitutions()).toEqual(institutions);
});

it('should dispatch updateResourceInstitutions on selection', () => {
(store.dispatch as jest.Mock).mockClear();
const selected: Institution[] = [MOCK_INSTITUTION as Institution];
component.institutionsSelected(selected);
expect(store.dispatch).toHaveBeenCalledWith(
new UpdateResourceInstitutions('draft-1', ResourceType.DraftRegistration, selected)
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { TranslatePipe } from '@ngx-translate/core';

import { Card } from 'primeng/card';

import { ChangeDetectionStrategy, Component, effect, inject, OnInit, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ChangeDetectionStrategy, Component, effect, input, OnInit, signal } from '@angular/core';

import { AffiliatedInstitutionSelectComponent } from '@osf/shared/components/affiliated-institution-select/affiliated-institution-select.component';
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
Expand All @@ -25,8 +24,7 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegistriesAffiliatedInstitutionComponent implements OnInit {
private readonly route = inject(ActivatedRoute);
private readonly draftId = this.route.snapshot.params['id'];
draftId = input.required<string>();

selectedInstitutions = signal<Institution[]>([]);

Expand All @@ -53,10 +51,10 @@ export class RegistriesAffiliatedInstitutionComponent implements OnInit {

ngOnInit() {
this.actions.fetchUserInstitutions();
this.actions.fetchResourceInstitutions(this.draftId, ResourceType.DraftRegistration);
this.actions.fetchResourceInstitutions(this.draftId(), ResourceType.DraftRegistration);
}

institutionsSelected(institutions: Institution[]) {
this.actions.updateResourceInstitutions(this.draftId, ResourceType.DraftRegistration, institutions);
this.actions.updateResourceInstitutions(this.draftId(), ResourceType.DraftRegistration, institutions);
}
}
Loading