Skip to content
This repository has been archived by the owner on Jun 6, 2022. It is now read-only.

Commit

Permalink
test(app): improve sagas coverage (#1053)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangabriele authored May 27, 2020
1 parent 30f4acc commit 2c9e6d4
Show file tree
Hide file tree
Showing 37 changed files with 943 additions and 46 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
"<rootDir>/packages/app/server/**/*.js",
"<rootDir>/packages/app/src/**/*.js",
"!<rootDir>/packages/app/src/svgs/**/*.js",
"!<rootDir>/packages/app/src/store.js",
],
coverageDirectory: "<rootDir>/coverage",
projects: ["<rootDir>/packages/*/jest.config.js"],
Expand Down
6 changes: 3 additions & 3 deletions packages/app/src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export default {
// Multiple comments:
COMMENTS_DELETE: "COMMENTS_DELETE",
COMMENTS_DELETE_FAILURE: "COMMENTS_DELETE_FAILURE",
COMMENTS_LOAD: "COMMENT_LOAD",
COMMENTS_LOAD_FAILURE: "COMMENT_LOAD_FAILURE",
COMMENTS_LOAD_SUCCESS: "COMMENT_LOAD_SUCCESS",
COMMENTS_LOAD: "COMMENTS_LOAD",
COMMENTS_LOAD_FAILURE: "COMMENTS_LOAD_FAILURE",
COMMENTS_LOAD_SUCCESS: "COMMENTS_LOAD_SUCCESS",

// One comment:
COMMENT_CREATE_ONE: "COMMENT_CREATE_ONE",
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/reducers/agreements.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actionTypes } from "../actions/index";

const initialState = {
export const initialState = {
checked: [],
data: null,
error: null,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/reducers/answers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actionTypes } from "../actions/index";

const initialState = {
export const initialState = {
checked: [],
data: null,
error: null,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/reducers/comments.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actionTypes } from "../actions/index";

const initialState = {
export const initialState = {
answerId: null,
currentIsLoading: false,
currentIsPrivate: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/reducers/legal-references.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actionTypes } from "../actions/index";

const initialState = {
export const initialState = {
category: null,
data: null,
error: null,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/reducers/logs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actionTypes } from "../actions/index";

const initialState = {
export const initialState = {
checked: [],
error: null,
isLoading: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/reducers/questions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { actionTypes } from "../actions/index";

const initialState = {
export const initialState = {
checked: [],
data: null,
error: null,
Expand Down
126 changes: 126 additions & 0 deletions packages/app/src/sagas/agreements/__tests__/load.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import axios from "axios";
import { runSaga } from "redux-saga";

import { initialState } from "../../../reducers/agreements";
import load from "../load";

jest.mock("axios");
const mockedAxios = /** @type {jest.Mocked<import("axios").AxiosInstance>} */ (axios);
mockedAxios.create.mockReturnValue(mockedAxios);

describe(`sagas/agreements/load()`, () => {
let DISPATCHED;

beforeEach(() => {
DISPATCHED = [];
});

describe(`with pageIndex=0`, () => {
describe(`with query=""`, () => {
it(`should behave as expected`, async () => {
const data = [{ name: "An Agreement" }];

mockedAxios.get.mockResolvedValueOnce({
data,
headers: {
"content-range": "0-9/15",
},
});

await runSaga(
{
dispatch: action => DISPATCHED.push(action),
getState: () => initialState,
},
load,
{ meta: { pageIndex: 0, query: "" } },
).toPromise();

expect(mockedAxios.get).toHaveBeenCalledTimes(1);
expect(mockedAxios.get).toHaveBeenCalledWith(
"/agreements?select=*&order=idcc.asc&limit=10&offset=0",
{
headers: { Prefer: "count=exact" },
},
);

expect(DISPATCHED).toHaveLength(1);
expect(DISPATCHED[0]).toEqual({
payload: { list: data, pageIndex: 0, pagesLength: 2 },
type: "AGREEMENTS_LOAD_SUCCESS",
});
});
});

describe(`with query="A Query"`, () => {
it(`should behave as expected`, async () => {
const data = [{ name: "An Agreement" }];

mockedAxios.get.mockResolvedValueOnce({
data,
headers: {
"content-range": "0-9/15",
},
});

await runSaga(
{
dispatch: action => DISPATCHED.push(action),
getState: () => initialState,
},
load,
{ meta: { pageIndex: 0, query: "A Query" } },
).toPromise();

expect(mockedAxios.get).toHaveBeenCalledTimes(1);
expect(mockedAxios.get).toHaveBeenCalledWith(
"/agreements?select=*&name=ilike.*A Query*&order=idcc.asc&limit=10&offset=0",
{
headers: { Prefer: "count=exact" },
},
);

expect(DISPATCHED).toHaveLength(1);
expect(DISPATCHED[0]).toEqual({
payload: { list: data, pageIndex: 0, pagesLength: 2 },
type: "AGREEMENTS_LOAD_SUCCESS",
});
});
});
});

describe(`with pageIndex=-1`, () => {
describe(`with query=""`, () => {
it(`should behave as expected`, async () => {
const data = [{ name: "An Agreement" }];

mockedAxios.get.mockResolvedValueOnce({
data,
headers: {
"content-range": "0-14/15",
},
});

await runSaga(
{
dispatch: action => DISPATCHED.push(action),
getState: () => initialState,
},
load,
{ meta: { pageIndex: -1, query: "" } },
).toPromise();

expect(mockedAxios.get).toHaveBeenCalledTimes(1);
expect(mockedAxios.get).toHaveBeenCalledWith("/agreements?select=*&order=idcc.asc", {
headers: { Prefer: "count=exact" },
});

expect(DISPATCHED).toHaveLength(1);
expect(DISPATCHED[0]).toEqual({
payload: { list: data, pageIndex: -1, pagesLength: -1 },
type: "AGREEMENTS_LOAD_SUCCESS",
});
});
});
});
});
4 changes: 2 additions & 2 deletions packages/app/src/sagas/agreements/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function* load({ meta: { pageIndex, query } }) {
}

if (query.length > 0) {
request.or.ilike("name", query);
request.ilike("name", query);
}

request.orderBy("idcc");
Expand All @@ -30,7 +30,7 @@ export default function* load({ meta: { pageIndex, query } }) {
pagesLength,
}),
);
} catch (err) {
} catch (err) /* istanbul ignore next */ {
if (err.response !== undefined && err.response.status === 416) {
const pageIndex = Math.floor(Number(err.response.headers["content-range"].substr(2)) / 10);

Expand Down
166 changes: 166 additions & 0 deletions packages/app/src/sagas/answers/__tests__/load.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import axios from "axios";
import { runSaga } from "redux-saga";

import getCurrentUser from "../../../libs/getCurrentUser";
import { initialState } from "../../../reducers/answers";
import { getAnswersFilters } from "../../../selectors";
import load from "../load";

jest.mock("axios");
const mockedAxios = /** @type {jest.Mocked<import("axios").AxiosInstance>} */ (axios);
mockedAxios.create.mockReturnValue(mockedAxios);

jest.mock("../../../libs/getCurrentUser");
jest.mock("../../../selectors");

describe(`sagas/answers/load()`, () => {
const DATA = {
answers: [
{ agreement_name: "An Agreement", id: "00000000-0000-4000-8000-000000000001" },
{ agreement_name: null, id: "00000000-0000-4000-8000-000000000002" },
],
answersReferences: [],
};
let DISPATCHED;
let FILTERS;

beforeEach(() => {
DISPATCHED = [];

getAnswersFilters.mockReturnValueOnce(FILTERS);
});

describe(`when the user is a contributor`, () => {
beforeAll(() => {
FILTERS = initialState.filters;

getCurrentUser.mockReturnValue({
agreements: [
"00000000-0000-4000-8000-000000000003",
"00000000-0000-4000-8000-000000000004",
],
id: "00000000-0000-4000-8000-000000000005",
role: "contributor",
});
});

describe(`when the filter {state}=["todo", "draft]`, () => {
it(`should behave as expected`, async () => {
mockedAxios.get.mockResolvedValueOnce({
data: DATA.answers,
headers: {
"content-range": "0-9/15",
},
});
mockedAxios.get.mockResolvedValueOnce({
data: DATA.answersReferences,
headers: {
"content-range": "0-14/15",
},
});

await runSaga(
{
dispatch: action => DISPATCHED.push(action),
getState: () => initialState,
},
load,
{ meta: { pagesIndex: 0 } },
).toPromise();

expect(getAnswersFilters).toHaveBeenCalledTimes(1);

expect(mockedAxios.get).toHaveBeenCalledTimes(2);
expect(mockedAxios.get).toHaveBeenNthCalledWith(
1,
`/full_answers?select=*&state=in.(todo,draft,pending_review,under_review,validated)&agreement_id=in.("00000000-0000-4000-8000-000000000003","00000000-0000-4000-8000-000000000004")&order=question_index.asc,agreement_idcc.asc&limit=10&offset=0`,
{
headers: { Prefer: "count=exact" },
},
);
expect(mockedAxios.get).toHaveBeenNthCalledWith(
2,
`/answers_references?select=*&answer_id=in.(00000000-0000-4000-8000-000000000001,00000000-0000-4000-8000-000000000002)&order=category.asc,value.asc`,
{},
);

const expectedList = [
{
agreement_name: "An Agreement",
id: "00000000-0000-4000-8000-000000000001",
references: [],
},
{ agreement_name: null, id: "00000000-0000-4000-8000-000000000002", references: [] },
];

expect(DISPATCHED).toHaveLength(1);
expect(DISPATCHED[0]).toEqual({
payload: { length: 15, list: expectedList, pagesIndex: 0, pagesLength: 2 },
type: "ANSWERS_LOAD_SUCCESS",
});
});
});

describe(`when the filter {state}=["draft]`, () => {
FILTERS = {
...initialState.filters,
states: ["draft"],
};

it(`should behave as expected`, async () => {
mockedAxios.get.mockResolvedValueOnce({
data: DATA.answers,
headers: {
"content-range": "0-9/15",
},
});
mockedAxios.get.mockResolvedValueOnce({
data: DATA.answersReferences,
headers: {
"content-range": "0-14/15",
},
});

await runSaga(
{
dispatch: action => DISPATCHED.push(action),
getState: () => initialState,
},
load,
{ meta: { pagesIndex: 0 } },
).toPromise();

expect(getAnswersFilters).toHaveBeenCalledTimes(1);

expect(mockedAxios.get).toHaveBeenCalledTimes(2);
expect(mockedAxios.get).toHaveBeenNthCalledWith(
1,
`/full_answers?select=*&state=in.(todo,draft,pending_review,under_review,validated)&agreement_id=in.("00000000-0000-4000-8000-000000000003","00000000-0000-4000-8000-000000000004")&order=question_index.asc,agreement_idcc.asc&limit=10&offset=0`,
{
headers: { Prefer: "count=exact" },
},
);
expect(mockedAxios.get).toHaveBeenNthCalledWith(
2,
`/answers_references?select=*&answer_id=in.(00000000-0000-4000-8000-000000000001,00000000-0000-4000-8000-000000000002)&order=category.asc,value.asc`,
{},
);

const expectedList = [
{
agreement_name: "An Agreement",
id: "00000000-0000-4000-8000-000000000001",
references: [],
},
{ agreement_name: null, id: "00000000-0000-4000-8000-000000000002", references: [] },
];

expect(DISPATCHED).toHaveLength(1);
expect(DISPATCHED[0]).toEqual({
payload: { length: 15, list: expectedList, pagesIndex: 0, pagesLength: 2 },
type: "ANSWERS_LOAD_SUCCESS",
});
});
});
});
});
2 changes: 1 addition & 1 deletion packages/app/src/sagas/answers/addReferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function* addReferences({ meta: { data }, next }) {
yield customPostgrester().post(API_PATH, data);

next();
} catch (err) {
} catch (err) /* istanbul ignore next */ {
toast.error(err.message);
yield put(answers.addReferencesFailure({ message: null }));
}
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/sagas/answers/cancel.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function* cancel({ meta: { ids, next } }) {
);

next();
} catch (err) {
} catch (err) /* istanbul ignore next */ {
toast.error(err.message);
yield put(answers.cancelFailure({ message: null }));
}
Expand Down
Loading

0 comments on commit 2c9e6d4

Please sign in to comment.