442 lines
16 KiB
TypeScript
Executable File
442 lines
16 KiB
TypeScript
Executable File
import React from 'react';
|
|
import { createMemoryHistory, createLocation } from 'history';
|
|
import ProjectBrief from 'organisms/ProjectBrief/ProjectBrief';
|
|
import { cleanup, render, waitForElement, fireEvent, act, wait } from '@testing-library/react';
|
|
import '@testing-library/jest-dom/extend-expect';
|
|
import { Provider } from 'react-redux';
|
|
import projectApi from 'API/projects';
|
|
import productApi from 'API/products';
|
|
import * as productActions from 'modules/products/actions';
|
|
import { Route, Router, match } from 'react-router';
|
|
import configureStore from 'redux-mock-store'; //ES6 modules
|
|
import { Brand, Category } from 'API/projectData';
|
|
import { format } from 'date-fns';
|
|
import useCurrentProject from 'hooks/useCurrentProject';
|
|
import ReactDOM from 'react-dom';
|
|
|
|
afterEach(cleanup);
|
|
const dispatch = jest.fn();
|
|
|
|
//MOCKED DATA
|
|
const category: Category = {
|
|
id: 1,
|
|
name: 'toys',
|
|
};
|
|
const brand: Brand = {
|
|
id: 1,
|
|
name: 'boys',
|
|
};
|
|
const printingFilesDate = '2011-02-01';
|
|
const promoDate = '2011-01-01';
|
|
|
|
const createMockStore = (initialValues: any) => {
|
|
const mockStore = configureStore();
|
|
const store = mockStore({
|
|
projectData: {
|
|
categories: [category],
|
|
brands: [brand],
|
|
},
|
|
users: {
|
|
currentUser: {
|
|
id: 1,
|
|
organization: {
|
|
type: 'supplier',
|
|
},
|
|
},
|
|
usersList: [],
|
|
},
|
|
projects: {
|
|
projectsList: [{ ...initialValues }],
|
|
},
|
|
});
|
|
return store;
|
|
};
|
|
|
|
const routeConfiguration = (path: string, params?: any) => {
|
|
const history = createMemoryHistory({ initialEntries: [path] });
|
|
const match: match = {
|
|
isExact: true,
|
|
path,
|
|
url: path,
|
|
params: params ? params : {},
|
|
};
|
|
const location = createLocation(match.url);
|
|
return { history, match, location };
|
|
};
|
|
|
|
const renderWithProviderAndRoute = (ui: any, { routeOptions, history, store }: any): any => {
|
|
return {
|
|
...render(
|
|
<Provider store={store}>
|
|
<Router history={history}>
|
|
<Route {...routeOptions}>{ui}</Route>
|
|
</Router>
|
|
</Provider>
|
|
),
|
|
};
|
|
};
|
|
|
|
describe('new project', () => {
|
|
const path = `/projects/new`;
|
|
let { history, match, location } = routeConfiguration(path);
|
|
beforeEach(() => (history = createMemoryHistory({ initialEntries: [path] })));
|
|
|
|
const initialValues = {
|
|
id: 1,
|
|
slug: 'test',
|
|
name: 'test',
|
|
products: 'test',
|
|
maxProductStage: 'max',
|
|
published: false,
|
|
updatedAt: new Date(),
|
|
createdAt: new Date(),
|
|
printingFilesDate,
|
|
publishable: false,
|
|
description: 'description',
|
|
category: category.id,
|
|
brand: brand.id,
|
|
promoDate,
|
|
productsAmount: 1,
|
|
};
|
|
const store = createMockStore(initialValues);
|
|
|
|
it('should render blank ProjectBrief on /projects/new ', async () => {
|
|
const { getByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief dispatch={dispatch} history={history} match={match} location={location} />,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
|
|
const categoryDropdown = await waitForElement(() => getByTestId('categoryDropdown'));
|
|
const brandDropdown = await waitForElement(() => getByTestId('brandDropdown'));
|
|
const printingFilesDateField = await waitForElement(() => getByTestId('printingFilesDatePicker'));
|
|
const promotionDateField = await waitForElement(() => getByTestId('poromoDateDatePicker'));
|
|
const saveButton = await waitForElement(() => getByTestId('projectSaveButton'));
|
|
const projectName = await waitForElement(() => getByTestId('projectName'));
|
|
const description = await waitForElement(() => getByTestId('description'));
|
|
expect(projectName).toBeInTheDocument();
|
|
expect(description).toBeInTheDocument();
|
|
expect(printingFilesDateField).toBeInTheDocument();
|
|
expect(promotionDateField).toBeInTheDocument();
|
|
expect(saveButton).toBeInTheDocument();
|
|
expect(brandDropdown).toBeInTheDocument();
|
|
expect(categoryDropdown).toBeInTheDocument();
|
|
});
|
|
it('should allow change form values', async () => {
|
|
const { findByTestId, findByText, findAllByDisplayValue } = renderWithProviderAndRoute(
|
|
<ProjectBrief dispatch={store.dispatch} history={history} match={match} location={location} />,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const brandDropdown = await waitForElement(() => findByTestId('brandDropdown'));
|
|
const categoryDropdown = await waitForElement(() => findByTestId('categoryDropdown'));
|
|
const projectName = await waitForElement(() => findByTestId('projectName'));
|
|
const description = await waitForElement(() => findByTestId('description'));
|
|
const dates = await waitForElement(() => findAllByDisplayValue(format(new Date(), 'yyyy-MM-dd')));
|
|
//CHECK IF DATE CHANGED
|
|
fireEvent.change(dates[0], { target: { value: '2011-02-02' } });
|
|
expect(dates[0]).toHaveValue('2011-02-02');
|
|
fireEvent.change(dates[1], { target: { value: '2011-02-03' } });
|
|
expect(dates[1]).toHaveValue('2011-02-03');
|
|
//CHECK IF PROJECT NAME CHANGED
|
|
fireEvent.change(projectName, { target: { value: 'projectName' } });
|
|
expect(projectName).toHaveValue('projectName');
|
|
//CHECK IF DESCRIPTION CHANGED
|
|
fireEvent.change(description, { target: { value: 'description' } });
|
|
expect(description).toHaveValue('description');
|
|
//CHECK IF BRAND DROPDOWN VALUE CHANGED
|
|
const brandValue = await waitForElement(() => findByTestId('brandValue'));
|
|
expect(brandValue.innerHTML).toEqual('Marka');
|
|
fireEvent.click(brandDropdown);
|
|
const brandItem = await waitForElement(() => findByText(brand.name));
|
|
expect(brandItem.innerHTML).toEqual(brand.name);
|
|
fireEvent.click(brandItem);
|
|
expect(brandValue.innerHTML).toEqual(brandItem.innerHTML);
|
|
//CHECK IF CATEGORY DROPDOWN VALUE CHANGED
|
|
const categoryValue = await waitForElement(() => findByTestId('categoryValue'));
|
|
expect(categoryValue.innerHTML).toEqual('Kategoria');
|
|
fireEvent.click(categoryDropdown);
|
|
const categoryItem = await waitForElement(() => findByText(category.name));
|
|
expect(categoryItem.innerHTML).toEqual(category.name);
|
|
fireEvent.click(categoryItem);
|
|
expect(categoryValue.innerHTML).toEqual(categoryItem.innerHTML);
|
|
});
|
|
it('publish button should not be visible if publishabled is false', async () => {
|
|
const { queryByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief dispatch={store.dispatch} history={history} match={match} location={location} />,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
expect(queryByTestId('publishButton')).toBe(null);
|
|
});
|
|
it('should not submit blank form', async () => {
|
|
const { findByTestId, queryAllByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief dispatch={store.dispatch} history={history} match={match} location={location} />,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
await act(async () => {
|
|
const saveButton = await waitForElement(() => findByTestId('projectSaveButton'));
|
|
fireEvent.click(saveButton);
|
|
});
|
|
const errors = queryAllByTestId('inputError');
|
|
expect(errors).toHaveLength(5);
|
|
});
|
|
it('should save proper form and redirect to /products/${pid}', async () => {
|
|
projectApi.createNewProject.mockReturnValueOnce({
|
|
id: 1,
|
|
});
|
|
productApi.getProductsByURL.mockReturnValueOnce([
|
|
{
|
|
id: 1,
|
|
},
|
|
]);
|
|
const { findByTestId, queryAllByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={store.dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={initialValues}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const saveButton = await waitForElement(() => findByTestId('projectSaveButton'));
|
|
await act(async () => {
|
|
fireEvent.click(saveButton);
|
|
const errors = queryAllByTestId('inputError');
|
|
expect(errors).toHaveLength(0);
|
|
});
|
|
expect(projectApi.createNewProject).toHaveBeenCalledTimes(1);
|
|
expect(productApi.getProductsByURL).toHaveBeenCalledTimes(1);
|
|
expect(history.location.pathname).toBe('/projects/1/products/1');
|
|
});
|
|
|
|
it('should setCurrentStage to 0', () => {
|
|
const spy = jest.spyOn(productActions, 'setCurrentStage');
|
|
renderWithProviderAndRoute(
|
|
<ProjectBrief dispatch={store.dispatch} history={history} match={match} location={location} />,
|
|
{ routeOptions: { exact: true, path: '/projects/new' }, history, store }
|
|
);
|
|
expect(spy).toHaveBeenCalledWith(0);
|
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
describe('existing project not publishable', () => {
|
|
const path = `/projects/1`;
|
|
const { history, match, location } = routeConfiguration(path, { id: 1 });
|
|
const initialValues = {
|
|
id: 1,
|
|
slug: 'test',
|
|
name: 'test',
|
|
products: 'test',
|
|
maxProductStage: 'max',
|
|
published: false,
|
|
updatedAt: new Date(),
|
|
createdAt: new Date(),
|
|
printingFilesDate,
|
|
publishable: false,
|
|
description: 'description',
|
|
category: category.id,
|
|
brand: brand.id,
|
|
promoDate,
|
|
productsAmount: 1,
|
|
};
|
|
const store = createMockStore(initialValues);
|
|
it('should set initial values', async () => {
|
|
const { getByTestId, findByDisplayValue } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={initialValues}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const projectName = await waitForElement(() => getByTestId('projectName'));
|
|
const projectDesc = await waitForElement(() => getByTestId('description'));
|
|
const categoryValue = await waitForElement(() => getByTestId('categoryValue'));
|
|
const brandValue = await waitForElement(() => getByTestId('brandValue'));
|
|
const promoDate = await waitForElement(() => findByDisplayValue(initialValues.printingFilesDate));
|
|
const pfDate = await waitForElement(() => findByDisplayValue(initialValues.promoDate));
|
|
|
|
expect(promoDate).toHaveValue(initialValues.printingFilesDate);
|
|
expect(pfDate).toHaveValue(initialValues.promoDate);
|
|
expect(categoryValue.innerHTML).toBe(category.name);
|
|
expect(brandValue.innerHTML).toBe(brand.name);
|
|
expect(projectName).toHaveValue(initialValues.name);
|
|
expect(projectDesc).toHaveValue(initialValues.description);
|
|
//TODO HOW TO CHECK FORMIK VALUES
|
|
});
|
|
it('should expand dropdown', async () => {
|
|
const { getByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief dispatch={store.dispatch} history={history} match={match} location={location} />,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const brand = await waitForElement(() => getByTestId('brandDropdown'));
|
|
const category = await waitForElement(() => getByTestId('categoryDropdown'));
|
|
fireEvent.click(brand);
|
|
fireEvent.click(category);
|
|
|
|
expect(brand).toHaveClass('is-active');
|
|
expect(category).toHaveClass('is-active');
|
|
});
|
|
});
|
|
describe('existing project publishable', () => {
|
|
beforeAll(() => {
|
|
ReactDOM.createPortal = jest.fn((element, node) => {
|
|
return element;
|
|
});
|
|
});
|
|
afterEach(() => {
|
|
ReactDOM.createPortal.mockClear();
|
|
});
|
|
const path = `/projects/1`;
|
|
const { history, match, location } = routeConfiguration(path, { id: 1 });
|
|
const initialValues = {
|
|
id: 1,
|
|
slug: 'test',
|
|
name: 'test',
|
|
products: 'test',
|
|
maxProductStage: 'max',
|
|
published: false,
|
|
updatedAt: new Date(),
|
|
createdAt: new Date(),
|
|
printingFilesDate,
|
|
publishable: true,
|
|
description: 'description',
|
|
category: category.id,
|
|
brand: brand.id,
|
|
promoDate,
|
|
productsAmount: 1,
|
|
};
|
|
const store = createMockStore(initialValues);
|
|
it('publish button should be in DOM but disabled', async () => {
|
|
useCurrentProject.mockReturnValue({ ...initialValues, publishable: false });
|
|
const { findByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={store.dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={{ ...initialValues, publishable: false }}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const publishButton = await waitForElement(() => findByTestId('publishButton'));
|
|
expect(publishButton).toBeInTheDocument();
|
|
expect(publishButton).toBeDisabled();
|
|
});
|
|
it('publish button should be in DOM and not disabled', async () => {
|
|
useCurrentProject.mockReturnValue(initialValues);
|
|
const { findByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={store.dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={initialValues}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const publishButton = await waitForElement(() => findByTestId('publishButton'));
|
|
expect(publishButton).toBeInTheDocument();
|
|
expect(publishButton).not.toBeDisabled();
|
|
});
|
|
it('should open modal and spin spinner', async () => {
|
|
projectApi.publishProject.mockReturnValueOnce({ ...initialValues, published: true });
|
|
useCurrentProject.mockReturnValue(initialValues);
|
|
productApi.getProductsByURL.mockReturnValueOnce([
|
|
{
|
|
id: 1,
|
|
},
|
|
]);
|
|
const { findByTestId, findByText } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={store.dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={initialValues}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const publishButton = await waitForElement(() => findByTestId('publishButton'));
|
|
expect(publishButton).toBeInTheDocument();
|
|
await act(async () => {
|
|
fireEvent.click(publishButton);
|
|
});
|
|
const modal = await waitForElement(() => findByText('Publikacja projektu'));
|
|
const modalCancel = await waitForElement(() => findByTestId('modalCancel'));
|
|
const modalSubmit = await waitForElement(() => findByTestId('modalSubmit'));
|
|
expect(modal).toBeInTheDocument();
|
|
expect(modalSubmit).toBeInTheDocument();
|
|
expect(modalCancel).toBeInTheDocument();
|
|
fireEvent.click(modalSubmit);
|
|
expect(modalSubmit).toHaveClass('is-loading');
|
|
await wait(() => expect(modalSubmit).not.toHaveClass('is-loading'));
|
|
|
|
expect(modal).not.toBeInTheDocument();
|
|
});
|
|
describe('Published Project', () => {
|
|
const path = `/projects/1`;
|
|
const { history, match, location } = routeConfiguration(path, { id: 1 });
|
|
const initialValues = {
|
|
id: 1,
|
|
slug: 'test',
|
|
name: 'test',
|
|
products: 'test',
|
|
maxProductStage: 'max',
|
|
published: true,
|
|
updatedAt: new Date(),
|
|
createdAt: new Date(),
|
|
printingFilesDate,
|
|
publishable: false,
|
|
description: 'description',
|
|
category: category.id,
|
|
brand: brand.id,
|
|
promoDate,
|
|
productsAmount: 1,
|
|
};
|
|
const store = createMockStore(initialValues);
|
|
it('should not display publish button when published is true', async () => {
|
|
useCurrentProject.mockReturnValue(initialValues);
|
|
const { queryByTestId } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={store.dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={initialValues}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
expect(queryByTestId('publishButton')).toBe(null);
|
|
});
|
|
it('should have disabled fields', async () => {
|
|
useCurrentProject.mockReturnValue(initialValues);
|
|
const { findByText, findByTestId, findByDisplayValue } = renderWithProviderAndRoute(
|
|
<ProjectBrief
|
|
dispatch={store.dispatch}
|
|
history={history}
|
|
match={match}
|
|
location={location}
|
|
currentProject={initialValues}
|
|
/>,
|
|
{ routeOptions: { exact: true, path }, history, store }
|
|
);
|
|
const brandValue = await waitForElement(() => findByTestId('brandValue'));
|
|
const categoryValue = await waitForElement(() => findByTestId('categoryValue'));
|
|
const projectName = await waitForElement(() => findByTestId('projectName'));
|
|
const description = await waitForElement(() => findByTestId('description'));
|
|
const promo = await waitForElement(() => findByDisplayValue(promoDate));
|
|
const pfDate = await waitForElement(() => findByDisplayValue(printingFilesDate));
|
|
|
|
expect(categoryValue.parentElement).toBeDisabled();
|
|
expect(brandValue.parentElement).toBeDisabled();
|
|
expect(promo).toBeDisabled();
|
|
expect(pfDate).toBeDisabled();
|
|
expect(projectName).toBeDisabled();
|
|
expect(description).toBeDisabled();
|
|
});
|
|
});
|
|
});
|