import { TestBed } from '@angular/core/testing';
import { Store } from '@ngrx/store';
import { HistoryStateFacade } from './history.facade';
import * as actions from './history.actions';
import { OrderHistoryStatus } from '@shelf-store/defs';
import { of } from 'rxjs';
import { take } from 'rxjs/operators';

fdescribe('HistoryStateFacade', () => {
  let facade: HistoryStateFacade;
  let store: jasmine.SpyObj<Store<any>>;

  const orderItemSubsetId = 123;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      providers: [
        HistoryStateFacade,
        {
          provide: Store,
          useValue: jasmine.createSpyObj('store', {
            dispatch: () => {},
          }),
        },
      ],
    });
  });

  beforeEach(() => {
    facade = TestBed.inject(HistoryStateFacade);
    store = TestBed.inject(Store);
  });

  it('should be created', () => {
    expect(facade instanceof HistoryStateFacade).toBeTruthy();
  });

  describe('fetchHistory', () => {
    it('should dispatch initOrderHistory to get the history for the provided orderItemSubsetId', () => {
      const initOrderHistoryAction = actions.initOrderHistory({
        id: orderItemSubsetId,
      });
      facade.fetchHistory(orderItemSubsetId);

      expect(store.dispatch).toHaveBeenCalledWith(initOrderHistoryAction);
    });
  });

  describe('reloadHistory', () => {
    it('should dispatch fetchHistory', () => {
      const fetchHistoryAction = actions.fetchHistory({
        id: orderItemSubsetId,
      });
      facade.reloadHistory(orderItemSubsetId);

      expect(store.dispatch).toHaveBeenCalledWith(fetchHistoryAction);
    });
  });

  describe('hasErrorStatus$', () => {
    it('should call getStatus to get the status', async () => {
      spyOn(facade, 'getStatus$').and.returnValue(of(OrderHistoryStatus.ERROR));

      await facade.hasErrorStatus$(orderItemSubsetId).pipe(take(1)).toPromise();
      expect(facade.getStatus$).toHaveBeenCalledWith(orderItemSubsetId);
    });

    it('should return true if the status is error', async () => {
      spyOn(facade, 'getStatus$').and.returnValue(of(OrderHistoryStatus.ERROR));

      const result = await facade.hasErrorStatus$(orderItemSubsetId).pipe(take(1)).toPromise();

      expect(result).toBe(true);
    });

    it('should return false if the status is available', async () => {
      spyOn(facade, 'getStatus$').and.returnValue(of(OrderHistoryStatus.AVAILABLE));

      const result = await facade.hasErrorStatus$(orderItemSubsetId).pipe(take(1)).toPromise();

      expect(result).toBe(false);
    });
  });
});
