Comments (4)
^ indeed that's the problem, as long as the root component (aka the Container) doesn't get mounted, then the store doesn't get initialized. In a next version I think I could change the implementation so that it uses portals and gets rid of that container.
Closing the issue for now as it's not a bug on the component's end.
from react-notifications-component.
I believe that's happening because the Store
is not initialized. In order to be initialized it should be called on register
method with the needed parameters. Try to log Store
to see if it's undefined or if the fields within class are undefined - I suspect the latter to be your issue.
When ran in browser, it calls register
on this line - maybe that part is not called in your tests? Hard to say, v1 had plenty of tests but the breaking changes required to discard the old tests and I havent' written any from v2 onwards.
So the solution is to make sure the Container
's componentDidMount
runs successfully so that you have your store registered - post a more detailed part of the test so I can make an idea over it.
from react-notifications-component.
Sure, here is my full test with the non-relevant parts removed.
import React from 'react';
import {
render,
screen,
within,
fireEvent,
cleanup,
waitFor,
} from '@testing-library/react';
import '@testing-library/jest-dom';
import '@testing-library/react/dont-cleanup-after-each';
import Modal from 'react-modal';
import userEvent from '@testing-library/user-event';
import { Store } from 'react-notifications-component';
import BagModal from './BagModal';
import * as APIFunctions from '../../utils/APIFunctions';
const mockedEmptyFn = jest.fn();
const mockBaseProps = {
openBagConsumption: true,
setOpenBagConsumption: mockedEmptyFn,
activeOrder: {
bagID: '265-1514b-19',
bagsOrdered: 20825,
bagsPerPallet: 49,
// ... lots more properties in here that don't matter
},
customStyles: {
content: {
backgroundColor: 'var(--color-primary)',
border: '1px solid #ccc',
boxShadow: '-2rem 2rem 2rem rgba(0, 0, 0, 0.5)',
color: 'rgba(var(--RGB-text), 0.8)',
filter: 'blur(0)',
fontSize: '1.1em',
fontWeight: 'bold',
margin: '50px auto',
opacity: 1,
outline: 0,
position: 'relative',
visibility: 'visible',
width: '500px',
},
overlay: {
backgroundColor: 'rgba(255, 255, 255, 0.9)',
},
},
};
const mockBasePropsHidden = {
...mockBaseProps,
openBagConsumption: false,
};
Modal.setAppElement('body');
const Component = (props) => (
<BagModal {...mockBaseProps} {...props} />
);
const HiddenModal = (props) => (
<BagModal {...mockBasePropsHidden} {...props} />
);
describe('Bag Modal tests with editable inputs', () => {
afterAll(() => {
cleanup();
});
// removed all the tests that are passing, this is the only failing test
test('Submitting a filed form should not show an error message', async (object, method) => {
render(<Component />);
jest
.spyOn(APIFunctions, 'insertBagHistory')
.mockResolvedValue('success');
jest.spyOn(Store, 'addNotification').mockResolvedValue('success');
const bagBatchInput = await screen.findByLabelText(
/bag batch number/i
);
await userEvent.type(bagBatchInput, 'Test');
const palletNumberInput = await screen.findByLabelText(
/carton number/i
);
await userEvent.type(palletNumberInput, 'Test');
const submitButton = await screen.getByText(/submit/i);
await userEvent.click(submitButton);
expect(screen.queryByTestId('error-msg')).not.toBeInTheDocument();
});
});
And then here is the BagModal that I am testing:
import ReactModal from 'react-modal';
import React, { useRef, useState } from 'react';
import PropTypes from 'prop-types';
import CloseButton from './CloseButton';
import { Store } from 'react-notifications-component';
import { Scrollbars } from 'rc-scrollbars';
import { insertBagHistory } from '../../utils/APIFunctions';
const initialState = {
caseID: '',
palletID: '',
};
const BagModal = (props) => {
const {
openBagConsumption,
setOpenBagConsumption,
activeOrder,
customStyles,
} = props;
const [userInput, setUserInput] = useState(initialState);
const [inputError, setInputError] = useState('');
const form = useRef();
const handleTextChange = (evt) => {
setInputError('');
const { name, value } = evt.target;
setUserInput({ ...userInput, [name]: value });
};
const validate = () => {
return form.current.reportValidity();
};
const handleSubmit = async (evt) => {
evt.preventDefault();
// validate input fields
if (!validate()) {
setInputError('Please enter the Case ID and the Pallet ID.');
form.current.querySelectorAll('input').forEach((element) => {
if (element.checkValidity()) {
if (element.type === 'text') {
element.classList.remove('error-input');
} else if (element.type === 'radio') {
const divEl = element.closest('div');
divEl.classList.remove('error-input');
}
} else {
if (element.type === 'text') {
element.classList.add('error-input');
} else if (element.type === 'radio') {
const divEl = element.closest('div');
divEl.classList.add('error-input');
}
}
});
} else {
// form is validated!
// save to database
const bagHistoryData = {
orderID: activeOrder.orderNumber,
caseID: userInput.caseID,
palletID: userInput.palletID,
};
await insertBagHistory(bagHistoryData);
Store.addNotification({
type: 'success',
title: 'Bag consumption added!',
message: 'A new bag consumption has been added.',
insert: 'top',
container: 'top-center',
animationIn: ['animated', 'bounceIn'],
animationOut: ['animated', 'fadeOut'],
dismiss: {
duration: 4000,
onScreen: true,
},
});
setOpenBagConsumption(false);
}
};
const cleanUp = () => {
setUserInput(initialState);
setInputError('');
};
const handleKeyDown = (e) => {
// if Enter is pressed and the inputs are filled, save the bag consumption
if (e.key === 'Enter') {
handleSubmit(e).then(() => {
// data submitted
});
}
};
return (
<ReactModal
isOpen={openBagConsumption}
style={customStyles}
className={'order-details-modal'}
closeTimeoutMS={1000}
onAfterClose={cleanUp}
>
<CloseButton setOpenModal={setOpenBagConsumption} />
<h2 className={'title'}>
Enter Bag Consumption for Item Number: {activeOrder.title}
</h2>
<Scrollbars autoHeight autoHeightMin={270} autoHeightMax={400}>
<form
className={'form modal-form'}
ref={form}
onSubmit={handleSubmit}
noValidate
>
<label htmlFor={'caseID'}>D.O.R / Bag Batch Number:</label>
<input
type={'text'}
className={'form-control mb-4'}
id={'caseID'}
name={'caseID'}
maxLength={50}
placeholder={'DOR / Bag Batch Number'}
value={userInput.caseID}
onChange={handleTextChange}
autoFocus
required
/>
<label htmlFor={'palletID'}>Pallet / Carton Number:</label>
<input
type={'text'}
className={'form-control mb-3'}
id={'palletID'}
name={'palletID'}
maxLength={50}
placeholder={'Pallet / Carton Number'}
value={userInput.palletID}
onChange={handleTextChange}
onKeyDown={handleKeyDown}
required
/>
{inputError && (
<p className={'text-warning'} data-testid={'error-msg'}>
{inputError}
</p>
)}
<br />
<input
className={'btn btn-primary d-block mx-auto mb-2'}
type={'submit'}
value={'Submit'}
/>
</form>
</Scrollbars>
</ReactModal>
);
};
BagModal.propTypes = {
openBagConsumption: PropTypes.bool.isRequired,
setOpenBagConsumption: PropTypes.func.isRequired,
activeOrder: PropTypes.object.isRequired,
customStyles: PropTypes.object.isRequired,
};
export default BagModal;
The handleSubmit function is where the notification happens.
from react-notifications-component.
@mdodge-ecgrow I came across this same issue in my tests. For me, the issue was that I wasn't mounting the <ReactNotifications>
component. During typical use this is mounted at the top level of the application, however when testing a component this isn't the case as only the component you're testing is being mounted, in your case BagModal
. Easy to overlook.
A quick fix is to place your test component alongside the ReactNotification component:
render(
<>
<ReactNotifications />
<EntryForm />
</>
);
from react-notifications-component.
Related Issues (20)
- How to give width to notification in percentage HOT 2
- Project breaking due to "Removed default export" HOT 1
- TypeError: Cannot read properties of undefined (reading 'addNotification') HOT 2
- Does not display any notifications
- Scrolling when screen is full of notifications HOT 2
- Please fix typo HOT 1
- Notifications are not auto dismissed when browser tab is inactive HOT 3
- Unable to resolve dependency tree error when installing npm packages HOT 4
- Fade In animation suddenly appears instead of playing the animation HOT 3
- uncompatibility with animate.css library HOT 6
- Notifications created in rapid succession may not be removed from the DOM when dismissed HOT 4
- Not all styles are renamed HOT 1
- npm ERR! Missing script: "build:library:dev" HOT 3
- compatibility issue
- The component's test for closing by timeout failed HOT 1
- 'message' property renders only string, not component HOT 1
- Notification blinks when it appears HOT 2
- Add `top: 0` to rnc__base
- Desktop Notifications as an option
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-notifications-component.