Skip to content

Commit

Permalink
[OSDEV-1132] implement thanks for submitting screen FE (#436)
Browse files Browse the repository at this point in the history
  • Loading branch information
VadimKovalenkoSNF authored Dec 10, 2024
1 parent 2c1e40b commit 65c1394
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 40 deletions.
1 change: 1 addition & 0 deletions doc/release/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ This issue has been fixed by adding additional requests to delete the appropriat
* [OSDEV-1482](https://opensupplyhub.atlassian.net/browse/OSDEV-1482) - The `GET api/v1/moderation-events/{moderation_id}` endpoint returns a single response instead of an array containing one item.

### What's new
* [OSDEV-1132](https://opensupplyhub.atlassian.net/browse/OSDEV-1132) - Added FE for the "thanks for submitting" screen when user submits production location's data.
* [OSDEV-1373](https://opensupplyhub.atlassian.net/browse/OSDEV-1373) - The tab `Search by Name and Address.` on the Production Location Search screen has been implemented. There are three required properties (name, address, country). The "Search" button becomes clickable after filling out inputs, creates a link with parameters, and allows users to proceed to the results screen.
* [OSDEV-1175](https://opensupplyhub.atlassian.net/browse/OSDEV-1175) - New Moderation Queue Page was integrated with `GET api/v1/moderation-events/` endpoint that include pagination, sorting and filtering.

Expand Down
1 change: 1 addition & 0 deletions src/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"@craco/craco": "6.1.1",
"@material-ui/core": "3.1.0",
"@material-ui/icons": "3.0.1",
"@popperjs/core": "^2.11.8",
"@reduxjs/toolkit": "^2.2.7",
"@rollbar/react": "^0.11.2",
"@turf/distance": "6.0.1",
Expand Down
60 changes: 60 additions & 0 deletions src/react/src/__tests__/components/DialogTooltip.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import DialogTooltip from '../../components/Contribute/DialogTooltip';

global.cancelAnimationFrame = jest.fn();

jest.mock('@popperjs/core', () => ({
__esModule: true,
default: jest.fn(() => ({
destroy: jest.fn(),
update: jest.fn(),
scheduleUpdate: jest.fn(),
enableEventListeners: jest.fn(),
disableEventListeners: jest.fn(),
setOptions: jest.fn(),
})),
}));

beforeAll(() => {
global.Node = global.Node || {};
});

describe('DialogTooltip Component', () => {
test('renders tooltip on hover', async () => {
const mockChildComponent = <span>Hover over this element</span>;
const mockText = "You'll be able to claim the location after the moderation is done";

render(
<DialogTooltip text={mockText} childComponent={mockChildComponent} classes={{}} />
);

expect(screen.queryByText(mockText)).not.toBeInTheDocument();

fireEvent.mouseEnter(screen.getByText('Hover over this element'));
await waitFor(() => {
expect(screen.getByText(mockText)).toBeInTheDocument();
});
});

test('hides tooltip on mouse leave', async () => {
const mockChildComponent = <span>Hover over this element</span>;
const mockText = "Test tooltip";

render(
<DialogTooltip text={mockText} childComponent={mockChildComponent} classes={{}} />
);

const element = screen.getByText('Hover over this element');

fireEvent.mouseEnter(element);
await waitFor(() => {
expect(screen.getByText(mockText)).toBeInTheDocument();
});

fireEvent.mouseLeave(element);
await waitFor(() => {
expect(screen.queryByText(mockText)).not.toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { BrowserRouter as Router, useHistory } from 'react-router-dom';
import UserEvent from "user-event";
import ProductionLocationDialog from '../../components/Contribute/ProductionLocationDialog';

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: jest.fn(),
}));

const mockHistoryPush = jest.fn();

beforeEach(() => {
useHistory.mockReturnValue({
push: mockHistoryPush,
});
});

test('renders dialog content', () => {
render(
<Router>
<ProductionLocationDialog classes={{}} />
</Router>
);

expect(screen.getByText(/Thanks for adding data for this production location!/i)).toBeInTheDocument();
expect(screen.getByText(/Facility name/i)).toBeInTheDocument();
expect(screen.getByText(/OS ID/i)).toBeInTheDocument();
expect(screen.getByText(/Pending/i)).toBeInTheDocument();
});

test('should render multiple instances of text element', () => {
const text = "Unifill Composite Dyeing Mills Ltd.";

render(
<Router>
<ProductionLocationDialog classes={{}} />
</Router>
);

const elements = screen.getAllByText(new RegExp(text, 'i'));

expect(elements).toHaveLength(2);
});

test('navigates when "Search OS Hub" button is clicked', () => {
render(
<Router>
<ProductionLocationDialog classes={{}} />
</Router>
);

const button = screen.getByText(/Search OS Hub/i);
UserEvent.click(button);

expect(mockHistoryPush).toHaveBeenCalledWith('/');
});

test('calls console log when "Submit another Location" button is clicked', () => {
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();

render(
<Router>
<ProductionLocationDialog classes={{}} />
</Router>
);

const button = screen.getByText(/Submit another Location/i);
UserEvent.click(button);

expect(consoleLogSpy).toHaveBeenCalledWith('submit another location');
consoleLogSpy.mockRestore();
});
3 changes: 2 additions & 1 deletion src/react/src/components/ConfirmActionButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import { useMergeButtonClickHandler } from './../util/hooks';
import { CONFIRM_ACTION, MERGE_ACTION, REJECT_ACTION } from '../util/constants';
import COLOURS from '../util/COLOURS';

const actionDialogStates = Object.freeze({
none: 'none',
Expand Down Expand Up @@ -151,7 +152,7 @@ const ConfirmActionButton = ({
<div key={facilityMatchToReject.id}>
<li>name: {facilityMatchToReject?.name}</li>
<li>address: {facilityMatchToReject?.address}</li>
<hr color="#E7E8EA" />
<hr color={COLOURS.ACCENT_GREY} />
</div>
))}
</ul>
Expand Down
58 changes: 58 additions & 0 deletions src/react/src/components/Contribute/DialogTooltip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useState } from 'react';
import { shape, string, node } from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Tooltip from '@material-ui/core/Tooltip';
import { makeDialogTooltipStyles } from '../../util/styles';

const DialogTooltip = ({ text, childComponent, classes }) => {
const [arrowRef, setArrowRef] = useState(null);
return (
<Tooltip
aria-label={text}
enterDelay={200}
leaveDelay={200}
title={
<>
{text}
<span className={classes.arrow} ref={setArrowRef} />
</>
}
classes={{
tooltip: classes.tooltipStyles,
popper: classes.popperStyles,
tooltipPlacementLeft: classes.placementLeft,
tooltipPlacementRight: classes.placementRight,
tooltipPlacementTop: classes.placementTop,
tooltipPlacementBottom: classes.placementBottom,
}}
PopperProps={{
popperOptions: {
modifiers: {
arrow: {
enabled: Boolean(arrowRef),
element: arrowRef,
},
},
},
}}
>
{childComponent}
</Tooltip>
);
};

DialogTooltip.propTypes = {
text: string.isRequired,
childComponent: node.isRequired,
classes: shape({
arrow: shape({}).isRequired,
tooltipStyles: shape({}).isRequired,
popperStyles: shape({}).isRequired,
placementLeft: shape({}).isRequired,
placementRight: shape({}).isRequired,
placementTop: shape({}).isRequired,
placementBottom: shape({}).isRequired,
}).isRequired,
};

export default withStyles(makeDialogTooltipStyles)(DialogTooltip);
Loading

0 comments on commit 65c1394

Please sign in to comment.