import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { PersonTypesSandbox } from '@pages/admin/person-types/person-types.sandbox';
import { Store, ActionsSubject } from '@ngrx/store';
import { State } from '@shared/store';
import { UtilService } from '@shared/utility/utility.service';
import { of } from 'rxjs';
import { Router } from '@angular/router';
import * as personTypesActions from '@app/shared/store/actions/admin/person-types.action';
import * as personTypesFormReducer from '@shared/store/reducers/admin/person-types-details-form.reducer';
import { MarkAsTouchedAction } from 'ngrx-forms';

describe('PersonTypesSandbox', () => {
  let service: PersonTypesSandbox;
  let appState: Store<State>;
  let actionSubject: ActionsSubject;
  let utilService: UtilService;
  let router: Router;
  let modalService: NgbModal;

  beforeEach(() => {
    appState = { dispatch: () => {}, pipe: () => of(true), select: () => of(true) } as any;
    actionSubject = { pipe: () => of(true) } as any;
    utilService = { displayNotification() {} } as any;
    router = { navigateByUrl() {} } as any;
    modalService = { open() {} } as any;
    spyOn(appState, 'dispatch').and.callFake(() => {});

    service = new PersonTypesSandbox(appState, actionSubject, router, utilService, modalService);
  });

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

  it('should set DisplayForm property', () => {
    service.setDisplayForm();
    expect(service.displayForm).toBeTruthy();
  });

  it('should dispatch loadPersonTypes Action via loadPersonTypes()', () => {
    service.loadPersonTypes();
    expect(appState.dispatch).toHaveBeenCalledWith(personTypesActions.loadPersonTypes());
  });

  it('should dispatch loadPersonType Action via loadPersonType(id)', () => {
    service.loadPersonType('x');
    expect(appState.dispatch).toHaveBeenCalledWith(personTypesActions.loadPersonType({ payload: 'x' }));
  });

  it('should call dispatch for saving an item', () => {
    service.savePersonType();
    expect(appState.dispatch).toHaveBeenCalledWith(new MarkAsTouchedAction(personTypesFormReducer.FORM_ID));
  });

  it('should clear form via clear()', () => {
    service['clear']();
    expect(service.displayForm).toBe(false);
  });

  it('should open modal before deleting a PersonType', () => {
    spyOn(service['modalService'], 'open')
      .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
    service.deletePersonType('x');
    expect(modalService.open).toHaveBeenCalled();
  });

  it('should clear form state when current change is canceled and form state is pristine', () => {
    let spy = spyOn(service,'clear');
    service.currentFormState = {isPristine: true} as any;
    service.cancel();
    expect(spy).toHaveBeenCalled();
  });

  it('should open modal when current change is canceled and form state is not pristine', () => {
    spyOn(service['modalService'], 'open')
      .and.returnValue({componentInstance: {title: ''}, result: {then: () => of(true)}} as any);
    service.currentFormState = {isPristine: false} as any;
    service.cancel();
    expect(modalService.open).toHaveBeenCalled();
  });
});
