ngneat / effects

🪄 A framework-agnostic RxJS effects implementation
https://www.netbasal.com
MIT License
63 stars 11 forks source link

Dispatched Actions from Effects getting not emitted though "customActionsStream" #57

Open TobbiAR opened 1 year ago

TobbiAR commented 1 year ago

Which @ngneat/effects-* package(s) are the source of the bug?

effects-ng

Is this a regression?

No

Description

During writing jest tests for effects I've encountered the problem, that actions, which are dispatched by effects are not getting emitted inside customActionsStream. During runtime and regular use (without customActionsStream), this problem does not exist.

The simple test example below illustrates the problem: loadTodos gets dispached and dispatches after completion loadTodos2. The test fails, because loadTodos2 never apprears inside customActionsStream$.

How I've encountered this problem? / Use Case I want to test effects, which are performing store updates. To ensure, that the update process triggered by the effect is properly performed, the effect dispatches a "completion" action. When the completion action is dispatched, I'm able to verify, that the performed state mutations/ async side-effects are properly done.

Reproduction example:

import { TestBed } from '@angular/core/testing';
import { Actions, createAction, createEffect, ofType } from '@ngneat/effects';
import { provideEffects, provideEffectsManager } from '@ngneat/effects-ng';
import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core';

const loadTodos = createAction('[Todos] Load Todos');
const loadTodos2 = createAction('[Todos] Load Todos2');

@Injectable()
class EffectsOne {
  loadTodos$ = createEffect(
    (actions$) =>
      actions$.pipe(
        ofType(loadTodos),
        map(() => loadTodos2()),
      ),
    { dispatch: true },
  );
}

it('should emit loadTodos2 action', (done) => {
  const customActionsStream$ = new Actions();

  TestBed.configureTestingModule({
    providers: [
      provideEffects(EffectsOne),
      // eslint-disable-next-line rxjs/finnish
      provideEffectsManager({ customActionsStream: customActionsStream$, dispatchByDefault: true }),
    ],
  });

  customActionsStream$.pipe(ofType(loadTodos2)).subscribe((todos) => {
    expect(todos).toBeDefined();
    done();
  });
  customActionsStream$.dispatch(loadTodos());
});

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

Error: thrown: "Exceeded timeout of 5000 ms for a test while waiting for `done()` to be called.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

Please provide the environment you discovered this bug in

jest 29.5.0
@ngneat/effects 2.1.1
@ngneat/effects-ng 3.1.2

Anything else?

No response

Do you want to create a pull request?

No

EricPoul commented 1 year ago

I checked a code. There's a bug when we return an action to dispatch in effect. You're welcome to make a pr. We need to change a little subscribeEffect and check for customActionsStream not only in effect.sourceFn but also while dispatching in the subscribe.

EricPoul commented 1 year ago

@TobbiAR please update to the latest version. I made a little fix so it should work fine now.

TobbiAR commented 1 year ago

I'll test this feature as soon I'm able to migrate my project to angular v16. Thank you!