Selaa lähdekoodia

Added a basic test for initDashboard thunk

Torkel Ödegaard 6 vuotta sitten
vanhempi
commit
a53c3b45fc

+ 1 - 0
package.json

@@ -85,6 +85,7 @@
     "prettier": "1.9.2",
     "react-hot-loader": "^4.3.6",
     "react-test-renderer": "^16.5.0",
+    "redux-mock-store": "^1.5.3",
     "regexp-replace-loader": "^1.0.1",
     "sass-lint": "^1.10.2",
     "sass-loader": "^7.0.1",

+ 130 - 0
public/app/features/dashboard/state/initDashboard.test.ts

@@ -0,0 +1,130 @@
+import configureMockStore from 'redux-mock-store';
+import thunk from 'redux-thunk';
+import { initDashboard, InitDashboardArgs } from './initDashboard';
+import { DashboardRouteInfo, DashboardLoadingState } from 'app/types';
+
+const mockStore = configureMockStore([thunk]);
+
+interface ScenarioContext {
+  args: InitDashboardArgs;
+  timeSrv: any;
+  annotationsSrv: any;
+  unsavedChangesSrv: any;
+  variableSrv: any;
+  dashboardSrv: any;
+  keybindingSrv: any;
+  setup: (fn: () => void) => void;
+  actions: any[];
+  storeState: any;
+}
+
+type ScenarioFn = (ctx: ScenarioContext) => void;
+
+function describeInitScenario(description: string, scenarioFn: ScenarioFn) {
+  describe(description, () => {
+    const timeSrv = { init: jest.fn() };
+    const annotationsSrv = { init: jest.fn() };
+    const unsavedChangesSrv = { init: jest.fn() };
+    const variableSrv = { init: jest.fn() };
+    const dashboardSrv = { setCurrent: jest.fn() };
+    const keybindingSrv = { setupDashboardBindings: jest.fn() };
+
+    const injectorMock = {
+      get: (name: string) => {
+        switch (name) {
+          case 'timeSrv':
+            return timeSrv;
+          case 'annotationsSrv':
+            return annotationsSrv;
+          case 'unsavedChangesSrv':
+            return unsavedChangesSrv;
+          case 'dashboardSrv':
+            return dashboardSrv;
+          case 'variableSrv':
+            return variableSrv;
+          case 'keybindingSrv':
+            return keybindingSrv;
+          default:
+            throw { message: 'Unknown service ' + name };
+        }
+      },
+    };
+
+    let setupFn = () => {};
+
+    const ctx: ScenarioContext = {
+      args: {
+        $injector: injectorMock,
+        $scope: {},
+        fixUrl: false,
+        routeInfo: DashboardRouteInfo.Normal,
+      },
+      timeSrv,
+      annotationsSrv,
+      unsavedChangesSrv,
+      variableSrv,
+      dashboardSrv,
+      keybindingSrv,
+      actions: [],
+      storeState: {
+        location: {
+          query: {},
+        },
+        user: {},
+      },
+      setup: (fn: () => void) => {
+        setupFn = fn;
+      },
+    };
+
+    beforeEach(async () => {
+      setupFn();
+
+      const store = mockStore(ctx.storeState);
+
+      await store.dispatch(initDashboard(ctx.args));
+
+      ctx.actions = store.getActions();
+    });
+
+    scenarioFn(ctx);
+  });
+}
+
+describeInitScenario('Initializing new dashboard', ctx => {
+  ctx.setup(() => {
+    ctx.storeState.user.orgId = 12;
+    ctx.args.routeInfo = DashboardRouteInfo.New;
+  });
+
+  it('Should send action to set loading state to fetching', () => {
+    expect(ctx.actions[0].type).toBe('SET_DASHBOARD_LOADING_STATE');
+    expect(ctx.actions[0].payload).toBe(DashboardLoadingState.Fetching);
+  });
+
+  it('Should send action to set loading state to Initializing', () => {
+    expect(ctx.actions[1].type).toBe('SET_DASHBOARD_LOADING_STATE');
+    expect(ctx.actions[1].payload).toBe(DashboardLoadingState.Initializing);
+  });
+
+  it('Should update location with orgId query param', () => {
+    expect(ctx.actions[2].type).toBe('UPDATE_LOCATION');
+    expect(ctx.actions[2].payload.query.orgId).toBe(12);
+  });
+
+  it('Should send action to set dashboard model', () => {
+    expect(ctx.actions[3].type).toBe('SET_DASHBOARD_MODEL');
+    expect(ctx.actions[3].payload.title).toBe('New dashboard');
+  });
+
+  it('Should Initializing services', () => {
+    expect(ctx.timeSrv.init).toBeCalled();
+    expect(ctx.annotationsSrv.init).toBeCalled();
+    expect(ctx.variableSrv.init).toBeCalled();
+    expect(ctx.unsavedChangesSrv.init).toBeCalled();
+    expect(ctx.keybindingSrv.setupDashboardBindings).toBeCalled();
+    expect(ctx.dashboardSrv.setCurrent).toBeCalled();
+  });
+});
+
+

+ 3 - 3
public/app/features/dashboard/state/initDashboard.ts

@@ -9,7 +9,6 @@ import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
 import { AnnotationsSrv } from 'app/features/annotations/annotations_srv';
 import { VariableSrv } from 'app/features/templating/variable_srv';
 import { KeybindingSrv } from 'app/core/services/keybindingSrv';
-import { config } from 'app/core/config';
 
 // Actions
 import { updateLocation } from 'app/core/actions';
@@ -150,8 +149,9 @@ export function initDashboard(args: InitDashboardArgs): ThunkResult<void> {
     }
 
     // add missing orgId query param
-    if (!getState().location.query.orgId) {
-      dispatch(updateLocation({ query: { orgId: config.bootData.user.orgId }, partial: true, replace: true }));
+    const storeState = getState() ;
+    if (!storeState.location.query.orgId) {
+      dispatch(updateLocation({ query: { orgId: storeState.user.orgId }, partial: true, replace: true }));
     }
 
     // init services

+ 14 - 0
public/app/features/profile/state/reducers.ts

@@ -0,0 +1,14 @@
+import { UserState } from 'app/types';
+import config from 'app/core/config';
+
+export const initialState: UserState = {
+  orgId: config.bootData.user.orgId,
+};
+
+export const userReducer = (state = initialState, action: any): UserState => {
+  return state;
+};
+
+export default {
+  user: userReducer,
+};

+ 2 - 0
public/app/store/configureStore.ts

@@ -11,6 +11,7 @@ import exploreReducers from 'app/features/explore/state/reducers';
 import pluginReducers from 'app/features/plugins/state/reducers';
 import dataSourcesReducers from 'app/features/datasources/state/reducers';
 import usersReducers from 'app/features/users/state/reducers';
+import userReducers from 'app/features/profile/state/reducers';
 import organizationReducers from 'app/features/org/state/reducers';
 import { setStore } from './store';
 
@@ -25,6 +26,7 @@ const rootReducers = {
   ...pluginReducers,
   ...dataSourcesReducers,
   ...usersReducers,
+  ...userReducers,
   ...organizationReducers,
 };
 

+ 1 - 3
public/app/types/user.ts

@@ -1,5 +1,3 @@
-import { DashboardSearchHit } from './search';
-
 export interface OrgUser {
   avatarUrl: string;
   email: string;
@@ -47,5 +45,5 @@ export interface UsersState {
 }
 
 export interface UserState {
-  starredDashboards: DashboardSearchHit[];
+  orgId: number;
 }

+ 7 - 0
yarn.lock

@@ -14582,6 +14582,13 @@ redux-logger@^3.0.6:
   dependencies:
     deep-diff "^0.3.5"
 
+redux-mock-store@^1.5.3:
+  version "1.5.3"
+  resolved "https://registry.yarnpkg.com/redux-mock-store/-/redux-mock-store-1.5.3.tgz#1f10528949b7ce8056c2532624f7cafa98576c6d"
+  integrity sha512-ryhkkb/4D4CUGpAV2ln1GOY/uh51aczjcRz9k2L2bPx/Xja3c5pSGJJPyR25GNVRXtKIExScdAgFdiXp68GmJA==
+  dependencies:
+    lodash.isplainobject "^4.0.6"
+
 redux-thunk@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"