Skip to content
Snippets Groups Projects
Select Git revision
  • 286bc26724354096c3208c94862fde02bab1f7c6
  • main default protected
  • release
  • anbindung_ed
  • 1.5.0
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
  • 1.0.0
10 results

DocumentManagerApplicationITCase.java

Blame
  • command.effects.spec.ts 17.09 KiB
    import {
      ApiError,
      ApiErrorAction,
      EMPTY_STRING,
      TypedActionCreatorWithProps,
    } from '@alfa-client/tech-shared';
    import { Mock, mock } from '@alfa-client/test-utils';
    import { SnackBarService } from '@alfa-client/ui';
    import { TestBed } from '@angular/core/testing';
    import { provideMockActions } from '@ngrx/effects/testing';
    import { Action, Store, createAction, props } from '@ngrx/store';
    import { TypedAction } from '@ngrx/store/src/models';
    import { provideMockStore } from '@ngrx/store/testing';
    import { Resource } from '@ngxp/rest';
    import { cold, hot } from 'jest-marbles';
    import { ColdObservable } from 'jest-marbles/typings/src/rxjs/cold-observable';
    import {
      createCommandListResource,
      createCommandResource,
      createCreateCommandProps,
    } from 'libs/command-shared/test/command';
    import { createApiError } from 'libs/tech-shared/test/error';
    import { Observable, of } from 'rxjs';
    import { TestScheduler } from 'rxjs/testing';
    import { CommandLinkRel } from '../command.linkrel';
    import { CREATE_COMMAND_MESSAGE_BY_ORDER, CommandErrorMessage } from '../command.message';
    import { CommandListResource, CommandResource, CreateCommandProps } from '../command.model';
    import { CommandRepository } from '../command.repository';
    import {
      CommandProps,
      LoadCommandListSuccessProps,
      SnackBarProps,
      createCommandFailure,
    } from './command.actions';
    import { CommandEffects } from './command.effects';
    
    import * as CommandActions from './command.actions';
    
    describe('CommandEffects', () => {
      let actions: Observable<Action>;
      let effects: CommandEffects;
    
      let repository: Mock<CommandRepository>;
      let snackBarService: Mock<SnackBarService>;
      let store: Mock<Store>;
    
      let testScheduler: TestScheduler;
    
      beforeEach(() => {
        repository = mock(CommandRepository);
        snackBarService = mock(SnackBarService);
        store = mock(Store);
    
        testScheduler = new TestScheduler((actual, expected) => expect(actual).toEqual(expected));
    
        TestBed.configureTestingModule({
          providers: [
            CommandEffects,
            provideMockActions(() => actions),
            provideMockStore(),
            {
              provide: CommandRepository,
              useValue: repository,
            },
            {
              provide: SnackBarService,
              useValue: snackBarService,
            },
            {
              provide: Store,
              useValue: store,
            },
          ],
        });
    
        effects = TestBed.inject(CommandEffects);
      });
    
      describe('loadCommandList', () => {
        const resource: Resource = createCommandResource();
        const linkRel: string = 'LinkRelationOfResource';
    
        const loadSuccess: TypedActionCreatorWithProps<LoadCommandListSuccessProps> = createAction(
          '[Test Action] Load Success',
          props<LoadCommandListSuccessProps>(),
        );
        const loadFailure: TypedActionCreatorWithProps<ApiErrorAction> = createAction(
          '[Test Action] Load Failure',
          props<ApiErrorAction>(),
        );
    
        const loadCommandList: TypedAction<string> = CommandActions.loadCommandList({
          resource,
          linkRel,
          successAction: (commandList) => loadSuccess({ commandList }),
          failureAction: (apiError) => loadFailure({ apiError }),
        });
    
        const commandListResource: CommandListResource = createCommandListResource();
    
        beforeEach(() => {
          repository.getPendingCommands.mockReturnValue(of(commandListResource));
        });
    
        it('should call repository', () => {
          actions = of(loadCommandList);
    
          effects.loadCommandList$.subscribe();
    
          expect(repository.getPendingCommands).toHaveBeenCalledWith(resource, linkRel);
        });
    
        it('should dispatch success action on no error', () => {
          actions = hot('-a', { a: loadCommandList });
    
          const expected: ColdObservable = cold('-b', {
            b: loadSuccess({ commandList: commandListResource }),
          });
          expect(effects.loadCommandList$).toBeObservable(expected);
        });
    
        it('should dispatch failure action on error', () => {
          const apiError: ApiError = createApiError();
          const error = { error: apiError };
          const errorResponse = cold('-#', {}, error);
          repository.getPendingCommands = jest.fn(() => errorResponse);
    
          actions = hot('-a', { a: loadCommandList });
    
          const expected: ColdObservable = cold('--b', { b: loadFailure({ apiError }) });
          expect(effects.loadCommandList$).toBeObservable(expected);
        });
      });
    
      describe('createCommand', () => {
        const createCommandProps: CreateCommandProps = createCreateCommandProps();
        const createCommandAction: TypedAction<string> =
          CommandActions.createCommand(createCommandProps);
    
        const commandResource: CommandResource = createCommandResource();
    
        beforeEach(() => {
          repository.createCommand.mockReturnValue(of(commandResource));
        });
    
        it('should call repository', () => {
          actions = of(createCommandAction);
    
          effects.createCommand$.subscribe();
    
          expect(repository.createCommand).toHaveBeenCalledWith(
            createCommandProps.resource,
            createCommandProps.linkRel,
            createCommandProps.command,
          );
        });
    
        it('should handle createdCommand on success', () => {
          effects.handleCreatedCommand = jest.fn();
    
          actions = of(createCommandAction);
    
          effects.createCommand$.subscribe();
    
          expect(effects.handleCreatedCommand).toHaveBeenCalledWith(
            addCreateCommandActionType(createCommandProps),
            commandResource,
          );
        });
    
        function addCreateCommandActionType(createCommandProps: CreateCommandProps) {
          return { ...createCommandProps, type: '[Command] Create command' };
        }
    
        it('should dispatch failure action on error', () => {
          const error = { error: {} };
          const errorResponse = cold('-#', {}, error);
          repository.createCommand = jest.fn(() => errorResponse);
    
          actions = hot('-a', { a: createCommandAction });
    
          const expected: ColdObservable = cold('--b', {
            b: CommandActions.createCommandFailure({ error, command: createCommandProps.command }),
          });
          expect(effects.createCommand$).toBeObservable(expected);
        });
      });
    
      describe('handleCreatedCommand', () => {
        const createCommandProps: CreateCommandProps = createCreateCommandProps();
    
        it('should return pollCreatedCommand action on pending command', () => {
          const command: CommandResource = createCommandResource([CommandLinkRel.UPDATE]);
    
          const actions: TypedAction<string>[] = effects.handleCreatedCommand(
            createCommandProps,
            command,
          );
    
          expect(actions.length).toBe(1);
          expect(actions[0].type).toBe(CommandActions.pollCreatedCommand.type);
          const pollCreatedCommandAction: CommandActions.PollCommandProps = <any>actions[0];
          expect(pollCreatedCommandAction.command).toBe(command);
          expect(pollCreatedCommandAction.createCommandProps).toBe(createCommandProps);
        });
    
        it('should call handleCreateCommandSuccess on NOT pending command', () => {
          effects.handleCreateCommandSuccess = jest.fn();
          const command: CommandResource = createCommandResource();
    
          effects.handleCreatedCommand(createCommandProps, command);
    
          expect(effects.handleCreateCommandSuccess).toHaveBeenCalledWith(createCommandProps, command);
        });
      });
    
      describe.skip('FIXME: pollCreatedCommand', () => {
        const delay: string = CommandEffects.POLL_DELAY + 'ms';
    
        const command: CommandResource = createCommandResource();
    
        const pollCreateCommandAction: TypedAction<string> = CommandActions.pollCreatedCommand({
          command,
        });
    
        beforeEach(() => {
          repository.getCommand.mockReturnValue(of(command));
        });
    
        it('should call repository', () => {
          actions = hot('-a', { a: pollCreateCommandAction });
    
          effects.pollCreatedCommand$.subscribe(() => {
            console.info('Call repo!?');
            // expect(repository.getCommand).toHaveBeenCalledWith(command);
            fail();
          });
        });
    
        it('should handle createdCommand on no error and pending command', () => {
          // testScheduler.run((helpers) => {
          // const { hot, cold } = helpers;
          repository.getCommand.mockReturnValue(cold('-b|', { b: command }));
    
          effects.handleCreatedCommand = jest.fn();
    
          actions = hot('-a', { a: pollCreateCommandAction });
    
          effects.createCommand$.subscribe(() => {
            console.info('Call handleCreatedCommand!?');
            expect(effects.handleCreatedCommand).toHaveBeenCalledWith(command);
          });
          // });
        });
    
        it('should dispatch failure action on error', () => {
          testScheduler.run((helpers) => {
            const { hot, cold, expectObservable } = helpers;
            const error = { error: {} };
            const errorResponse = cold('-#', {}, error);
            repository.getCommand = jest.fn(() => errorResponse);
    
            actions = hot('-a', { a: pollCreateCommandAction });
    
            expectObservable(effects.pollCreatedCommand$).toBe(delay + ' --c', {
              c: createCommandFailure({ command, error }),
            });
          });
        });
      });
    
      describe('handleCreateCommandSuccess', () => {
        const createCommandProps: CreateCommandProps = createCreateCommandProps();
    
        describe('on non revokeable command without error', () => {
          it('should return createCommandSuccess action', () => {
            const command: CommandResource = createCommandResource();
    
            const actions: TypedAction<string>[] = effects.handleCreateCommandSuccess(
              createCommandProps,
              command,
            );
    
            expect(actions.length).toBe(2);
            const createCommandSuccessAction: CommandActions.CommandProps = <any>actions[0];
            expect(createCommandSuccessAction.command).toBe(command);
            expect(actions[1].type).toBe(CommandActions.showSnackbar.type);
          });
    
          it('should return showSnackbar action', () => {
            const command: CommandResource = createCommandResource();
    
            const actions: TypedAction<string>[] = effects.handleCreateCommandSuccess(
              createCommandProps,
              command,
            );
    
            expect(actions.length).toBe(2);
            const showSnackbarAction: CommandActions.SnackBarProps = <any>actions[1];
            expect(showSnackbarAction.createCommandProps).toBe(createCommandProps);
            expect(showSnackbarAction.command).toBe(command);
          });
        });
    
        describe('on revokeable command', () => {
          it('should return createCommandSuccess action', () => {
            const command: CommandResource = createCommandResource([CommandLinkRel.REVOKE]);
    
            const actions: TypedAction<string>[] = effects.handleCreateCommandSuccess(
              createCommandProps,
              command,
            );
    
            expect(actions.length).toBe(2);
            expect(actions[0].type).toBe(CommandActions.createCommandSuccess.type);
            expect((<any>actions[0]).command).toBe(command);
          });
    
          it('should return showRevokeSnackbar action', () => {
            const command: CommandResource = createCommandResource([CommandLinkRel.REVOKE]);
    
            const actions: TypedAction<string>[] = effects.handleCreateCommandSuccess(
              createCommandProps,
              command,
            );
    
            expect(actions.length).toBe(2);
            expect(actions[1].type).toBe(CommandActions.showRevokeSnackbar.type);
            expect((<any>actions[1]).command).toBe(command);
          });
        });
    
        describe('on error command', () => {
          it('should show snackbar with error', () => {
            const command: CommandResource = {
              ...createCommandResource(),
              errorMessage: CommandErrorMessage.CONCURRENT_MODIFICATION,
            };
    
            effects.handleCreateCommandSuccess(createCommandProps, command);
    
            expect(snackBarService.showError).toHaveBeenCalledWith(
              'Der Vorgang wurde zwischenzeitlich verändert und wurde neu geladen.',
            );
          });
    
          it('should return createCommandSuccess and publishConcurrentModificationAction', () => {
            const command: CommandResource = {
              ...createCommandResource(),
              errorMessage: CommandErrorMessage.CONCURRENT_MODIFICATION,
            };
    
            const actions: TypedAction<string>[] = effects.handleCreateCommandSuccess(
              createCommandProps,
              command,
            );
    
            expect(actions.length).toBe(2);
            expect(actions[0].type).toBe(CommandActions.createCommandSuccess.type);
            expect((<any>actions[0]).command).toBe(command);
            expect(actions[1].type).toBe(CommandActions.publishConcurrentModificationAction.type);
          });
        });
      });
    
      describe('showRevokeSnackbar', () => {
        const command: CommandResource = createCommandResource();
    
        const showRevokeSnackbarAction: TypedAction<string> = CommandActions.showRevokeSnackbar({
          command,
        });
    
        it('should show snackbar', () => {
          actions = of(showRevokeSnackbarAction);
    
          effects.showRevokeSnackbar$.subscribe();
    
          expect(snackBarService.show).toHaveBeenCalled();
        });
      });
    
      describe('showSnackbar', () => {
        const createCommandProps: CreateCommandProps = createCreateCommandProps();
        const command: CommandResource = createCommandResource();
    
        it('should call handle snackbar by command', () => {
          effects.handleSnackbarByCommand = jest.fn();
          const showSnackbarAction: TypedAction<string> = CommandActions.showSnackbar({
            createCommandProps,
            command,
          });
    
          actions = of(showSnackbarAction);
          effects.showSnackbar$.subscribe();
    
          expect(effects.handleSnackbarByCommand).toHaveBeenCalled();
        });
      });
    
      describe('handle snackbar by command', () => {
        const createCommandProps: CreateCommandProps = createCreateCommandProps();
        const command: CommandResource = createCommandResource();
    
        it('should show snackBar on existing snackBarMessage', () => {
          const snackBarProps: SnackBarProps = { createCommandProps, command };
    
          effects.handleSnackbarByCommand(snackBarProps);
    
          expect(snackBarService.show).toHaveBeenCalledWith(
            command,
            createCommandProps.snackBarMessage,
          );
        });
    
        it('should show snackBar on undefined snackBarMessage', () => {
          const snackBarProps: SnackBarProps = {
            createCommandProps: { ...createCommandProps, snackBarMessage: undefined },
            command,
          };
    
          effects.handleSnackbarByCommand(snackBarProps);
    
          expect(snackBarService.show).toHaveBeenCalledWith(
            command,
            CREATE_COMMAND_MESSAGE_BY_ORDER[command.order],
          );
        });
    
        it('should NOT show snackBar on empty snackBarMessage', () => {
          const snackBarProps: SnackBarProps = {
            createCommandProps: { ...createCommandProps, snackBarMessage: EMPTY_STRING },
            command,
          };
    
          effects.handleSnackbarByCommand(snackBarProps);
    
          expect(snackBarService.show).not.toHaveBeenCalled();
        });
    
        it('should NOT show snackBar on existing error message', () => {
          const snackBarProps: SnackBarProps = {
            createCommandProps,
            command: { ...command, errorMessage: 'dummyErrorMessage' },
          };
    
          effects.handleSnackbarByCommand(snackBarProps);
    
          expect(snackBarService.show).not.toHaveBeenCalled();
        });
      });
    
      describe('revokeCommand', () => {
        const command: CommandResource = createCommandResource();
        const revokeCommandAction: TypedAction<string> = CommandActions.revokeCommand({ command });
    
        const getCommand: CommandResource = createCommandResource();
    
        beforeEach(() => {
          repository.revokeCommand.mockReturnValue(of(getCommand));
        });
    
        it('should call repository', () => {
          actions = of(revokeCommandAction);
    
          effects.revokeCommand$.subscribe();
    
          expect(repository.revokeCommand).toHaveBeenCalledWith(command);
        });
    
        it('should handle revokeCommand', () => {
          effects.handleRevokeCommand = jest.fn();
    
          actions = of(revokeCommandAction);
          effects.revokeCommand$.subscribe();
    
          expect(effects.handleRevokeCommand).toHaveBeenCalledWith(getCommand);
        });
    
        it('should dispatch failure action on error', () => {
          const error = { error: {} };
          const errorResponse = cold('-#', {}, error);
          repository.revokeCommand = jest.fn(() => errorResponse);
    
          actions = hot('-a', { a: revokeCommandAction });
    
          const expected: ColdObservable = cold('--b', {
            b: CommandActions.revokeCommandFailure({ command, error }),
          });
          expect(effects.revokeCommand$).toBeObservable(expected);
        });
      });
    
      describe.skip('pollRevokedCommand', () => {
        //TODO Test fuer pollRevokedCommand
      });
    
      describe('handleRevokeCommand', () => {
        it('should return revokeCommandSuccess action', () => {
          const command: CommandResource = createCommandResource();
    
          const actions: (CommandProps & TypedAction<string>)[] = effects.handleRevokeCommand(command);
    
          expect(actions.length).toBe(1);
          expect(actions[0].type).toBe(CommandActions.revokeCommandSuccess.type);
          expect(actions[0].command).toBe(command);
        });
    
        it('should return pollRevokedCommand action on pending command', () => {
          const command: CommandResource = createCommandResource([CommandLinkRel.UPDATE]);
    
          const actions: (CommandProps & TypedAction<string>)[] = effects.handleRevokeCommand(command);
    
          expect(actions.length).toBe(1);
          expect(actions[0].type).toBe(CommandActions.pollRevokedCommand.type);
          expect(actions[0].command).toBe(command);
        });
      });
    });