Skip to content

Commit

Permalink
feat(stark-core): update routing actions style
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
Due to an improvement on how actions are defined, the enum `StarkRoutingActionsTypes`
became obsolete so it has been removed.

As a result, the following actions have been changed:
- `StarkNavigate(public currentState: string, public newState: string, public params?: RawParams,
  public options?: TransitionOptions)` -> `StarkRoutingActions.navigate({ currentState: string;
  newState: string; params?: RawParams; options?: TransitionOptions })`
- `StarkNavigateSuccess(public previousState: string, public currentState: string,
  public params?: RawParams)` -> `StarkRoutingActions.navigateSuccess({ previousState: string;
  currentState: string; params?: RawParams })`
- `StarkNavigateFailure(public currentState: string, public newState: string,
  public params: RawParams, public error: string)` -> `StarkRoutingActions.navigateFailure({
  currentState: string; newState: string; params?: RawParams; error: string })`
- `StarkNavigateRejection(public currentState: string, public newState: string,
  public params: RawParams, public reason: string)` -> `StarkRoutingActions.navigateRejection({
  currentState: string; newState: string; params: RawParams; reason: string })`
- `StarkNavigationHistoryLimitReached()` -> `StarkRoutingActions.navigationHistoryLimitReached()`
- `StarkReload(public state: string)` -> `StarkRoutingActions.reload({ state: string })`
- `StarkReloadSuccess(public state: string, public params: RawParams)`
  -> `StarkRoutingActions.reloadSuccess({ state: string; params: RawParams })`
- `StarkReloadFailure(public state: string, public params: RawParams)`
  -> `StarkRoutingActions.reloadFailure({ state: string; params: RawParams })`

And also the previous union type has been replaced:
`StarkRoutingActions` -> `StarkRoutingActions.Types`.

Change in effect:

```typescript
// Before
@effect({ dispatch: false })
public starkNavigateSuccess$(): Observable<void> {
    return this.actions$.pipe(
        ofType<StarkNavigateSuccess>(StarkRoutingActionsTypes.NAVIGATE_SUCCESS),
        map((action: StarkNavigateSuccess) => {
            // some logic
        })
    );
}

// After
public starkNavigateSuccess$ = createEffect(
    () => this.actions$.pipe(
        ofType(StarkRoutingActions.navigateSuccess),
        map((action) => {
            // some logic
        })
    ),
    { dispatch: false }
);
```

Change in `action` usage:

```typescript
// Before
this.store.dispatch(new StarkNavigateSuccess(previousState, currentState, params));

// After
this.store.dispatch(StarkRoutingActions.navigateSuccess({
    previousState: previousState,
    currentState: currentState,
    params: params
}));
```
  • Loading branch information
SuperITMan committed May 3, 2021
1 parent 3dd57d2 commit 97b067d
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 197 deletions.
3 changes: 2 additions & 1 deletion packages/stark-core/src/modules/routing/actions.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./actions/routing.actions";
import * as StarkRoutingActions from "./actions/routing.actions";
export { StarkRoutingActions };
206 changes: 74 additions & 132 deletions packages/stark-core/src/modules/routing/actions/routing.actions.ts
Original file line number Diff line number Diff line change
@@ -1,186 +1,128 @@
import { Action } from "@ngrx/store";
import { RawParams, TransitionOptions } from "@uirouter/core";
import { createAction, props, union } from "@ngrx/store";

/**
* Enumeration of Routing NGRX Actions
* Key defined to find the service in a store
*/
export enum StarkRoutingActionTypes {
NAVIGATE = "[StarkRouting] Navigate",
NAVIGATE_SUCCESS = "[StarkRouting] Navigate Success",
NAVIGATE_FAILURE = "[StarkRouting] Navigate Failure",
NAVIGATE_REJECTION = "[StarkRouting] Navigate Rejection",
NAVIGATION_HISTORY_LIMIT_REACHED = "[StarkRouting] Navigation History Limit Reached",
RELOAD = "[StarkRouting] Reload",
RELOAD_SUCCESS = "[StarkRouting] Reload Success",
RELOAD_FAILURE = "[StarkRouting] Reload Failure"
}
const starkRoutingStoreKey = "StarkRouting";

/**
* Triggered when the [StarkRoutingService navigateTo()]{@link StarkRoutingService#navigateTo} method is called, just before starting the navigation.
*
* Parameters:
* - currentState - Name of the current state before the navigation starts.
* - newState - Name of the state to be navigated to.
* - params - State params object to be passed to the navigated state.
* - options - Transition options object to change the behavior of the transition.
*/
export class StarkNavigate implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.NAVIGATE = StarkRoutingActionTypes.NAVIGATE;

/**
* Class constructor
* @param currentState - Name of the current state before the navigation starts.
* @param newState - Name of the state to be navigated to.
* @param params - State params object to be passed to the navigated state.
* @param options - Transition options object to change the behavior of the transition.
*/
public constructor(
public currentState: string,
public newState: string,
public params?: RawParams,
public options?: TransitionOptions
) {}
}
export const navigate = createAction(
`[${starkRoutingStoreKey}] Navigate`,
props<{ currentState: string; newState: string; params?: RawParams; options?: TransitionOptions }>()
);

/**
* Triggered when a navigation has succeeded and finished.
*
* This action is dispatched for any navigation, including those navigations triggered not by the [StarkRoutingService navigateTo()]{@link StarkRoutingService#navigateTo} method
* but by any other mean such as [StarkRoutingService navigateToPrevious()]{@link StarkRoutingService#navigateToPrevious}, [StarkRoutingService navigateToHome()]{@link StarkRoutingService#navigateToHome},
* [StarkRoutingService reload()]{@link StarkRoutingService#reload}, routing directives for menu links or by direct usage of the router library API.
*
* Parameters:
* - previousState - Name of the initial state where the navigation was started.
* - currentState - Name of the state that was navigated to.
* - params - State params object that was passed to the navigated state.
*/
export class StarkNavigateSuccess implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.NAVIGATE_SUCCESS = StarkRoutingActionTypes.NAVIGATE_SUCCESS;

/**
* Class constructor
* @param previousState - Name of the initial state where the navigation was started.
* @param currentState - Name of the state that was navigated to.
* @param params - State params object that was passed to the navigated state.
*/
public constructor(public previousState: string, public currentState: string, public params?: RawParams) {}
}
export const navigateSuccess = createAction(
`[${starkRoutingStoreKey}] Navigate Success`,
props<{ previousState: string; currentState: string; params?: RawParams }>()
);

/**
* Triggered when a navigation failed.
*
* This action is dispatched for any navigation, including those navigations triggered not by the [StarkRoutingService navigateTo()]{@link StarkRoutingService#navigateTo}
* method but by any other mean such as menu links or by direct usage of the router library API.
*
* Parameters:
* - currentState - Name of the current state before the navigation started.
* - newState - Name of the state tried to be navigated to.
* - params - State params object passed to the navigated state.
* - error - The error describing the reason of the navigation failure.
*/
export class StarkNavigateFailure implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.NAVIGATE_FAILURE = StarkRoutingActionTypes.NAVIGATE_FAILURE;

/**
* Class constructor
* @param currentState - Name of the current state before the navigation started.
* @param newState - Name of the state tried to be navigated to.
* @param params - State params object passed to the navigated state.
* @param error - The error describing the reason of the navigation failure.
*/
public constructor(public currentState: string, public newState: string, public params: RawParams, public error: string) {}
}
export const navigateFailure = createAction(
`[${starkRoutingStoreKey}] Navigate Failure`,
props<{ currentState: string; newState: string; params?: RawParams; error: string }>()
);

/**
* Triggered when a navigation was intentionally rejected with a known rejection reason added via the
* [StarkRoutingService addKnownNavigationRejectionCause()]{@link StarkRoutingService#addKnownNavigationRejectionCause} method.
*
* The custom logic to intentionally reject a transition can be normally be injected via a transition Hook by calling
* the [StarkRoutingService addTransitionHook()]{@link StarkRoutingService#addTransitionHook} method.
*
* Parameters:
* - currentState - Name of the current state before the navigation started.
* - newState - Name of the state tried to be navigated to.
* - params - State params object passed to the navigated state.
* - reason - The reason describing why the navigation was rejected. This is normally a reason already known by the developer.
*/
export class StarkNavigateRejection implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.NAVIGATE_REJECTION = StarkRoutingActionTypes.NAVIGATE_REJECTION;

/**
* Class constructor
* @param currentState - Name of the current state before the navigation started.
* @param newState - Name of the state tried to be navigated to.
* @param params - State params object passed to the navigated state.
* @param reason - The reason describing why the navigation was rejected. This is normally a reason already known by the developer.
*/
public constructor(public currentState: string, public newState: string, public params: RawParams, public reason: string) {}
}
export const navigateRejection = createAction(
`[${starkRoutingStoreKey}] Navigate Rejection`,
props<{ currentState: string; newState: string; params: RawParams; reason: string }>()
);

/**
* Triggered when the [StarkRoutingService navigateToPrevious()]{@link StarkRoutingService#navigateToPrevious} method is called and there are no more
* previous states in the history to navigate to.
*
* This action is just triggered in case the reload was done by calling the [StarkRoutingService reload()]{@link StarkRoutingService#reload} method.
*/
export class StarkNavigationHistoryLimitReached implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.NAVIGATION_HISTORY_LIMIT_REACHED =
StarkRoutingActionTypes.NAVIGATION_HISTORY_LIMIT_REACHED;
}
export const navigationHistoryLimitReached = createAction(`[${starkRoutingStoreKey}] Navigation History Limit Reached`);

/**
* Triggered when the [StarkRoutingService reload()]{@link StarkRoutingService#reload} method is called, just before starting the state reloading.
*
* Parameter:
* - state - Name of the state to be reloaded.
*/
export class StarkReload implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.RELOAD = StarkRoutingActionTypes.RELOAD;

/**
* Class constructor
* @param state - Name of the state to be reloaded.
*/
public constructor(public state: string) {}
}
export const reload = createAction(`[${starkRoutingStoreKey}] Reload`, props<{ state: string }>());

/**
* Triggered when a reload succeeded and finished.
*
* This action is dispatched for any navigation, including those navigations triggered not by the [StarkRoutingService navigateTo()]{@link StarkRoutingService#navigateTo}
* method but by any other mean such as menu links or by direct usage of the router library API.
*
* Parameters:
* - state - Name of the state that was reloaded.
* - params - State params object passed to the reloaded state.
*/
export class StarkReloadSuccess implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.RELOAD_SUCCESS = StarkRoutingActionTypes.RELOAD_SUCCESS;

/**
* Class constructor
* @param state - name of the state that was reloaded.
* @param params - State params object passed to the reloaded state.
*/
public constructor(public state: string, public params: RawParams) {}
}
export const reloadSuccess = createAction(`[${starkRoutingStoreKey}] Reload Success`, props<{ state: string; params: RawParams }>());

/**
* Triggered when a reload failed.
* Triggered when a reload succeeded and finished.
*
* This action is just triggered in case the reload was done by calling the [StarkRoutingService reload()]{@link StarkRoutingService#reload} method.
* This action is dispatched for any navigation, including those navigations triggered not by the [StarkRoutingService navigateTo()]{@link StarkRoutingService#navigateTo}
* method but by any other mean such as menu links or by direct usage of the router library API.
*
* Parameters:
* - state - Name of the state that was reloaded.
* - params - State params object passed to the reloaded state.
*/
export class StarkReloadFailure implements Action {
/**
* The action type
*/
public readonly type: StarkRoutingActionTypes.RELOAD_FAILURE = StarkRoutingActionTypes.RELOAD_FAILURE;

/**
* Class constructor
* @param state - Name of the state tried to be reloaded.
* @param params - State params object passed to the reloaded state.
*/
public constructor(public state: string, public params: RawParams) {}
}
export const reloadFailure = createAction(`[${starkRoutingStoreKey}] Reload Failure`, props<{ state: string; params: RawParams }>());

export type StarkRoutingActions =
| StarkNavigate
| StarkNavigateSuccess
| StarkNavigateFailure
| StarkNavigateRejection
| StarkNavigationHistoryLimitReached
| StarkReload
| StarkReloadSuccess
| StarkReloadFailure;
/**
* @ignore
*/
const all = union({
navigate,
navigateSuccess,
navigateFailure,
navigateRejection,
navigationHistoryLimitReached,
reload,
reloadSuccess,
reloadFailure
});
export type Types = typeof all;
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ import { StarkRoutingServiceImpl } from "./routing.service";
import { StarkApplicationConfig, StarkApplicationConfigImpl } from "../../../configuration/entities/application";
import { StarkStateConfigWithParams } from "./state-config-with-params.intf";
import { StarkRoutingTransitionHook } from "./routing-transition-hook.constants";
import { StarkNavigate, StarkNavigationHistoryLimitReached, StarkRoutingActionTypes } from "../actions";
import { StarkRoutingActions } from "../actions";
import { StarkCoreApplicationState } from "../../../common/store";
import { StarkErrorHandler } from "../../error-handling";
import { StarkRoutingService } from "./routing.service.intf";
import CallInfo = jasmine.CallInfo;
import Spy = jasmine.Spy;
import SpyObj = jasmine.SpyObj;
import { MockStore, provideMockStore } from "@ngrx/store/testing";

type CallableRoutingAction = (action: StarkNavigate | StarkNavigationHistoryLimitReached) => void;
type CallableRoutingAction = (
action: typeof StarkRoutingActions.navigate | typeof StarkRoutingActions.navigationHistoryLimitReached
) => void;

@Component({ selector: "test-home", template: "HOME" })
export class HomeComponent {}
Expand All @@ -37,9 +40,7 @@ describe("Service: StarkRoutingService", () => {
let routingService: StarkRoutingServiceImpl;
let mockLogger: MockStarkLoggingService;
let appConfig: StarkApplicationConfig;
const mockStore: SpyObj<Store<StarkCoreApplicationState>> = jasmine.createSpyObj<Store<StarkCoreApplicationState>>("storeSpy", [
"dispatch"
]);
let mockStore: MockStore<StarkCoreApplicationState>;
const mockCorrelationId = "12345";
const requestId = "652d9053-32a0-457c-9eca-162cd301a4e8";

Expand Down Expand Up @@ -362,7 +363,8 @@ describe("Service: StarkRoutingService", () => {
const starkRoutingServiceFactory = (
state: StateService,
transitions: TransitionService,
globals: UIRouterGlobals
globals: UIRouterGlobals,
store: Store<StarkCoreApplicationState>
): StarkRoutingService => {
appConfig = new StarkApplicationConfigImpl();
appConfig.homeStateName = "homepage";
Expand All @@ -374,7 +376,7 @@ describe("Service: StarkRoutingService", () => {
mockLogger,
appConfig,
errorHandler,
<Store<StarkCoreApplicationState>>(<unknown>mockStore),
store,
state,
transitions,
globals
Expand All @@ -392,24 +394,30 @@ describe("Service: StarkRoutingService", () => {
{
provide: StarkRoutingServiceImpl,
useFactory: starkRoutingServiceFactory,
deps: [StateService, TransitionService, UIRouterGlobals]
}
deps: [StateService, TransitionService, UIRouterGlobals, Store]
},
provideMockStore()
],
imports: [routerModule]
});
});

// Inject module dependencies
beforeEach(inject([UIRouter, StarkRoutingServiceImpl], (_router: UIRouter, _routingService: StarkRoutingServiceImpl) => {
router = _router;
$state = router.stateService;
routingService = _routingService;

mockLogger.warn.calls.reset();
mockLogger.debug.calls.reset();
mockLogger.error.calls.reset();
mockStore.dispatch.calls.reset();
}));
beforeEach(inject(
[UIRouter, StarkRoutingServiceImpl, Store],
(_router: UIRouter, _routingService: StarkRoutingServiceImpl, _mockStore: MockStore<StarkCoreApplicationState>) => {
router = _router;
$state = router.stateService;
routingService = _routingService;
mockStore = _mockStore;

mockLogger.warn.calls.reset();
mockLogger.debug.calls.reset();
mockLogger.error.calls.reset();
spyOn(mockStore, "dispatch").and.callThrough();
(<Spy>mockStore.dispatch).calls.reset();
}
));

afterEach(() => {
// IMPORTANT: reset the url after each test,
Expand Down Expand Up @@ -1916,18 +1924,18 @@ describe("Service: StarkRoutingService", () => {
const expectedCalls: number = 16 + 12 + 3 + 1;
expect(mockStore.dispatch).toHaveBeenCalledTimes(expectedCalls);

const actions: ReadonlyArray<CallInfo<CallableRoutingAction>> = mockStore.dispatch.calls.all();
const actions: ReadonlyArray<CallInfo<CallableRoutingAction>> = (<Spy>mockStore.dispatch).calls.all();
const actionIndex: number = 16 + 12;

for (let i = 0; i < actions.length; i++) {
const action: CallInfo<CallableRoutingAction> = actions[i];

if (i === actionIndex) {
expect(action.args[0].type).toBe(StarkRoutingActionTypes.NAVIGATION_HISTORY_LIMIT_REACHED);
expect(action.args[0].type).toBe(StarkRoutingActions.navigationHistoryLimitReached.type);
} else if (i <= actionIndex + 2) {
expect(action.args[0].type).toContain(StarkRoutingActionTypes.NAVIGATE);
expect(action.args[0].type).toContain(StarkRoutingActions.navigate.type);
} else {
expect(action.args[0].type).toBe(StarkRoutingActionTypes.NAVIGATION_HISTORY_LIMIT_REACHED);
expect(action.args[0].type).toBe(StarkRoutingActions.navigationHistoryLimitReached.type);
}
}
}));
Expand Down

0 comments on commit 97b067d

Please sign in to comment.