import {ComponentFixture, TestBed} from '@angular/core/testing'; import {Observable, Subject} from 'rxjs'; import {Activity, CarePlan, Note} from '@nspop/gm-web-facade-api'; import {Component, forwardRef, Input} from '@angular/core'; import {ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule} from '@angular/forms'; import {AngularMaterialModule} from '../../modules/angular-material.module'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {NoteModalComponent} from './note-modal.component'; import {ActivitiesService} from '../activities.service'; import {CarePlanService} from '../../api/care-plan.service'; import {of} from 'rxjs/internal/observable/of'; import {NoteService} from '../../api/note.service'; describe('NoteModalComponent', () => { let component: NoteModalComponent; let fixture: ComponentFixture; let activitiesServiceStub: ActivitiesService; let noteServiceStub: NoteService; let carePlanSubjectStub: Subject; let carePlanUpdateSubscribeStub: { subscribe: (next: () => void, error: () => void) => void}; let careplanService: CarePlanService; const APP_MOCK_ACTIVITY_SELECTOR_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TieToActivityStubModalComponent), multi: true }; @Component({selector: 'app-tie-to-activity-modal', template: '', providers: [APP_MOCK_ACTIVITY_SELECTOR_VALUE_ACCESSOR]}) class TieToActivityStubModalComponent implements ControlValueAccessor{ registerOnChange(fn: any): void { } registerOnTouched(fn: any): void { } writeValue(obj: any): void { } } const APP_MOCK_DATE_PICKER_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DatePickerStubComponent), multi: true }; @Component({selector: 'app-date-picker', template: '', providers: [APP_MOCK_DATE_PICKER_VALUE_ACCESSOR]}) class DatePickerStubComponent implements ControlValueAccessor{ registerOnChange(fn: any): void { } registerOnTouched(fn: any): void { } writeValue(obj: any): void { } } @Component({selector: 'app-modal', template: '
'}) class ModalComponent { @Input() public header = ''; private isModalVisible = false; public setVisible(isVisible: boolean): void { this.isModalVisible = isVisible; } } beforeEach(async () => { activitiesServiceStub = { carePlan: { id: '123', version: 456, activities: [ { id: '1', version: 1, status: 'expected'}, { id: '2', version: 2, status: 'planned'}, ] } } as any; noteServiceStub = { createOrUpdateNote(activityId: string, note: Note, measurementDate: Date | undefined): Observable { return of({}); }, update(resource: any, id: string, version?: string): Observable { return of({}); }, createNoteForActivity(activityId: string, resource: Note): Observable { return of({}); } } as any; carePlanSubjectStub = new Subject(); carePlanUpdateSubscribeStub = careplanService = { carePlan$: carePlanSubjectStub.asObservable(), update: (carePlan: CarePlan, id: string, version: string) => carePlanSubjectStub.asObservable(), refresh: () => { }, activities$: of([ { id: '1', version: 1, status: 'expected'}, { id: '2', version: 2, status: 'planned'}, ]) } as any; await TestBed.configureTestingModule({ declarations: [NoteModalComponent, ModalComponent, DatePickerStubComponent, TieToActivityStubModalComponent], imports: [ ReactiveFormsModule, FormsModule, ReactiveFormsModule, AngularMaterialModule, BrowserAnimationsModule, ], providers: [ {provide: ActivitiesService, useValue: activitiesServiceStub}, {provide: CarePlanService, useValue: careplanService}, {provide: NoteService, useValue: noteServiceStub}, ] }) .compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(NoteModalComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('closes modal if submitting carePlan is a success', () => { const activity = { id: '1', status: 'expected'} as any as Activity; component.setActivity(activity); component.setVisible(true); component.form?.setValue({title: 'Ultralydscanning', content: 'vi scanner og alt det der'}); component.submit(component.form, component.formDirective); carePlanSubjectStub.next(null); expect(component.isVisible()).toBe(false); }); it('does not submit if there is no activity set', () => { spyOn(noteServiceStub, 'createOrUpdateNote'); component.activity = undefined; component.setVisible(true); component.form?.setValue({title: 'Ultralydscanning', content: 'vi scanner og alt det der'}); component.submit(component.form, component.formDirective); expect(noteServiceStub.createOrUpdateNote).toHaveBeenCalledTimes(0); }); it('does not submit if form is invalid', () => { spyOn(noteServiceStub, 'createOrUpdateNote'); component.activity = {status: 'expected', id: '1'} as Activity; component.setVisible(true); component.form?.setValue({title: 'Ultralydscanning', content: ''}); component.submit(component.form, component.formDirective); expect(noteServiceStub.createOrUpdateNote).toHaveBeenCalledTimes(0); }); it('sets editMode = true if there is a note attached to the activity, when setting Activity', () => { expect(component.isEditMode).toBeFalsy(); const activity = {status: 'expected', id: '1', note: {content: 'vi scanner og alt det der'}} as Activity; component.setActivity(activity); expect(component.isEditMode).toBe(true); }); it('sets editMode = false if there is no note attached to the activity, when setting Activity', () => { const activityWithNote = {status: 'expected', id: '1', note: {content: 'vi scanner og alt det der'}} as Activity; component.setActivity(activityWithNote); expect(component.isEditMode).toBe(true); const activityWithoutNote = {status: 'planned', id: '2'} as Activity; component.setActivity(activityWithoutNote); expect(component.isEditMode).toBe(false); }); it('should disable date field', () => { component.isDateDisabled({status: 'finished'} as any); }); it('should set the modal state', () => { const activity = {status: 'expected', id: '1', note: {content: 'vi scanner og alt det der'}} as Activity; component.setNoteModalState(true, activity, true); expect(component.isVisible()).toBeTrue(); expect(component.activity?.status).toBe(activity.status); expect(component.allowActivityChange).toBeTrue(); }); it('should take planned date when activity does NOT have conductedtime', () => { const plannedtime = new Date(2021, 3, 13); const activity = { status: 'finished', id: '2', note: {content: 'vi scanner og alt det der'}, plannedTime: { from: plannedtime } } as Activity; component.setFormValues(activity); expect(component.date).toBe(plannedtime); }); it('should take conductedTime when activity is finished amd conducted exists', () => { const conductedTime = new Date(2022, 5, 20); const activity = { status: 'finished', id: '1', note: {content: 'vi scanner og alt det der'}, conductedTime, } as Activity; component.setFormValues(activity); expect(component.date?.getDate()).toBe(conductedTime.getDate()); }); it('should mark itself as dirty when note changes', () => { expect(component.isDirty).toBeFalse(); component.onNoteContentChange(); expect(component.isDirty).toBeTrue(); }); it('should ', () => { const conductedTime = new Date(2022, 5, 20); const activity = { status: 'finished', id: '1', note: {content: 'vi scanner og alt det der'}, conductedTime, } as Activity; expect(component.activity).toBeUndefined(); component.activity = activity; component.activityChanged(); expect(component.date?.getDate()).toBe(conductedTime.getDate()); }); });