import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpResponse } from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { FormBuilder } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { of, Subject, from } from 'rxjs';

import { IUnit } from 'app/entities/unit/unit.model';
import { UnitService } from 'app/entities/unit/service/unit.service';
import { UnitConverterService } from '../service/unit-converter.service';
import { IUnitConverter } from '../unit-converter.model';
import { UnitConverterFormService } from './unit-converter-form.service';

import { UnitConverterUpdateComponent } from './unit-converter-update.component';

describe('UnitConverter Management Update Component', () => {
  let comp: UnitConverterUpdateComponent;
  let fixture: ComponentFixture<UnitConverterUpdateComponent>;
  let activatedRoute: ActivatedRoute;
  let unitConverterFormService: UnitConverterFormService;
  let unitConverterService: UnitConverterService;
  let unitService: UnitService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule, UnitConverterUpdateComponent],
      providers: [
        FormBuilder,
        {
          provide: ActivatedRoute,
          useValue: {
            params: from([{}]),
          },
        },
      ],
    })
      .overrideTemplate(UnitConverterUpdateComponent, '')
      .compileComponents();

    fixture = TestBed.createComponent(UnitConverterUpdateComponent);
    activatedRoute = TestBed.inject(ActivatedRoute);
    unitConverterFormService = TestBed.inject(UnitConverterFormService);
    unitConverterService = TestBed.inject(UnitConverterService);
    unitService = TestBed.inject(UnitService);

    comp = fixture.componentInstance;
  });

  describe('ngOnInit', () => {
    it('Should call Unit query and add missing value', () => {
      const unitConverter: IUnitConverter = { id: 456 };
      const fromUnit: IUnit = { id: 8943 };
      unitConverter.fromUnit = fromUnit;
      const toUnit: IUnit = { id: 23724 };
      unitConverter.toUnit = toUnit;

      const unitCollection: IUnit[] = [{ id: 7591 }];
      jest.spyOn(unitService, 'query').mockReturnValue(of(new HttpResponse({ body: unitCollection })));
      const additionalUnits = [fromUnit, toUnit];
      const expectedCollection: IUnit[] = [...additionalUnits, ...unitCollection];
      jest.spyOn(unitService, 'addUnitToCollectionIfMissing').mockReturnValue(expectedCollection);

      activatedRoute.data = of({ unitConverter });
      comp.ngOnInit();

      expect(unitService.query).toHaveBeenCalled();
      expect(unitService.addUnitToCollectionIfMissing).toHaveBeenCalledWith(
        unitCollection,
        ...additionalUnits.map(expect.objectContaining),
      );
      expect(comp.unitsSharedCollection).toEqual(expectedCollection);
    });

    it('Should update editForm', () => {
      const unitConverter: IUnitConverter = { id: 456 };
      const fromUnit: IUnit = { id: 12548 };
      unitConverter.fromUnit = fromUnit;
      const toUnit: IUnit = { id: 19205 };
      unitConverter.toUnit = toUnit;

      activatedRoute.data = of({ unitConverter });
      comp.ngOnInit();

      expect(comp.unitsSharedCollection).toContain(fromUnit);
      expect(comp.unitsSharedCollection).toContain(toUnit);
      expect(comp.unitConverter).toEqual(unitConverter);
    });
  });

  describe('save', () => {
    it('Should call update service on save for existing entity', () => {
      // GIVEN
      const saveSubject = new Subject<HttpResponse<IUnitConverter>>();
      const unitConverter = { id: 123 };
      jest.spyOn(unitConverterFormService, 'getUnitConverter').mockReturnValue(unitConverter);
      jest.spyOn(unitConverterService, 'update').mockReturnValue(saveSubject);
      jest.spyOn(comp, 'previousState');
      activatedRoute.data = of({ unitConverter });
      comp.ngOnInit();

      // WHEN
      comp.save();
      expect(comp.isSaving).toEqual(true);
      saveSubject.next(new HttpResponse({ body: unitConverter }));
      saveSubject.complete();

      // THEN
      expect(unitConverterFormService.getUnitConverter).toHaveBeenCalled();
      expect(comp.previousState).toHaveBeenCalled();
      expect(unitConverterService.update).toHaveBeenCalledWith(expect.objectContaining(unitConverter));
      expect(comp.isSaving).toEqual(false);
    });

    it('Should call create service on save for new entity', () => {
      // GIVEN
      const saveSubject = new Subject<HttpResponse<IUnitConverter>>();
      const unitConverter = { id: 123 };
      jest.spyOn(unitConverterFormService, 'getUnitConverter').mockReturnValue({ id: null });
      jest.spyOn(unitConverterService, 'create').mockReturnValue(saveSubject);
      jest.spyOn(comp, 'previousState');
      activatedRoute.data = of({ unitConverter: null });
      comp.ngOnInit();

      // WHEN
      comp.save();
      expect(comp.isSaving).toEqual(true);
      saveSubject.next(new HttpResponse({ body: unitConverter }));
      saveSubject.complete();

      // THEN
      expect(unitConverterFormService.getUnitConverter).toHaveBeenCalled();
      expect(unitConverterService.create).toHaveBeenCalled();
      expect(comp.isSaving).toEqual(false);
      expect(comp.previousState).toHaveBeenCalled();
    });

    it('Should set isSaving to false on error', () => {
      // GIVEN
      const saveSubject = new Subject<HttpResponse<IUnitConverter>>();
      const unitConverter = { id: 123 };
      jest.spyOn(unitConverterService, 'update').mockReturnValue(saveSubject);
      jest.spyOn(comp, 'previousState');
      activatedRoute.data = of({ unitConverter });
      comp.ngOnInit();

      // WHEN
      comp.save();
      expect(comp.isSaving).toEqual(true);
      saveSubject.error('This is an error!');

      // THEN
      expect(unitConverterService.update).toHaveBeenCalled();
      expect(comp.isSaving).toEqual(false);
      expect(comp.previousState).not.toHaveBeenCalled();
    });
  });

  describe('Compare relationships', () => {
    describe('compareUnit', () => {
      it('Should forward to unitService', () => {
        const entity = { id: 123 };
        const entity2 = { id: 456 };
        jest.spyOn(unitService, 'compareUnit');
        comp.compareUnit(entity, entity2);
        expect(unitService.compareUnit).toHaveBeenCalledWith(entity, entity2);
      });
    });
  });
});
