Commit a176e28a authored by Maxime Chaillet's avatar Maxime Chaillet

write tests for periodicrefresher component

parent aff4745b
import React from 'react';
import { Well, Navbar, Nav, NavItem, MenuItem, DropdownButton, Radio, NavDropdown } from 'react-bootstrap';
import { Well, Navbar, Nav, NavItem, MenuItem, Radio, NavDropdown, Checkbox } from 'react-bootstrap';
import EventListMenuButton from './EventListMenuButton';
import { getPDF } from '../../../api/icat/icatPlus';
import { ComboSearch } from 'react-combo-search';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { DOC_VIEW, LIST_VIEW, SORT_EVENTS_FROM_YOUNGEST, SORT_EVENTS_FROM_OLDEST, NEW_EVENT_VISIBLE } from '../../../constants/EventTypes';
import PeriodicRefresherDialogue from './NewlyAvailableEventsDialogue';
import NewlyAvailableEventsDialogue from './NewlyAvailableEventsDialogue';
// styles
......@@ -48,7 +47,6 @@ class EventListMenu extends React.Component {
return sortingFilter.createdAt;
}
}
return (
<Navbar
fluid
......@@ -78,12 +76,16 @@ class EventListMenu extends React.Component {
<MenuItem divider />
<MenuItem eventKey={3.3} onSelect={() => this.sortByDate(SORT_EVENTS_FROM_OLDEST)} > {getCurrentlyPressedSortButton() === SORT_EVENTS_FROM_OLDEST ? <Radio checked readOnly> Oldest log on top</Radio> : <Radio checked={false} readOnly> Oldest log on top</Radio>} </MenuItem>
<MenuItem eventKey={3.4} onSelect={() => this.sortByDate(SORT_EVENTS_FROM_YOUNGEST)} > {getCurrentlyPressedSortButton() === SORT_EVENTS_FROM_YOUNGEST ? <Radio checked readOnly> Latest log on top</Radio> : <Radio checked={false} readOnly> Latest log on top</Radio>} </MenuItem>
<MenuItem divider />
<MenuItem eventKey={3.5} onSelect={() => this.props.setEventListAutorefresh(!this.props.isEventListAutorefreshEnabled)}>
<Checkbox checked={this.props.isEventListAutorefreshEnabled} readOnly > Refresh logs automatically</Checkbox>
</MenuItem>
</NavDropdown>
<NavItem eventKey={4} href={getPDF(sessionId, investigationId, selectionFilter)} target='_blank' className="logbookNavItem" >
<EventListMenuButton text='PDF' glyph='download' tooltipText='Download as PDF' isEnabled={!(isNewEventVisible === undefined || isNewEventVisible === true || numberOfMatchingEventsFound === 0)} />
</NavItem>
<NavItem eventKey={5} className="logbookNavItem">
<NewlyAvailableEventsDialogue latestEvents={this.props.periodicData} eventCountSinceLastRefresh={this.props.eventCountSinceLastRefresh} onIconClicked={this.props.getEvents} />
<NewlyAvailableEventsDialogue latestEvents={this.props.periodicdata} eventCountSinceLastRefresh={this.props.eventCountSinceLastRefresh} onIconClicked={this.props.getEvents} />
</NavItem>
</Nav>
......
......@@ -34,6 +34,8 @@ export function GUI_CONFIG() {
DUAL_EDITOR_MAX_HEIGHT: "270px",
/* Default tag color used in the logbook when tag color is not set */
DEFAULT_TAG_COLOR: "#a6bded"
DEFAULT_TAG_COLOR: "#a6bded",
/* Whehter event list refreshed automaticcaly or not by default. */
AUTOREFRESH_EVENTLIST: false,
}
}
\ No newline at end of file
......@@ -38,6 +38,7 @@ export class LogbookContainer extends React.Component {
eventCountReceptionStatus: 'idle', //idle, fetched, countFetched, allFetched; Used to handle asynchronous data retrieval from the server
eventBeingEdited: null,
isNewEventVisible: false,
isEventListAutorefreshEnabled: GUI_CONFIG().AUTOREFRESH_EVENTLIST,
pageEvents: [], // events currently displayed on the page
selectedEventId: 0,
sortingFilter: GUI_CONFIG().DEFAULT_SORTING_FILTER,
......@@ -53,6 +54,7 @@ export class LogbookContainer extends React.Component {
this.onPageClicked = this.onPageClicked.bind(this);
this.reverseEventsSortingByCreationDate = this.reverseEventsSortingByCreationDate.bind(this);
this.searchEvents = this.searchEvents.bind(this);
this.setEventListAutorefresh = this.setEventListAutorefresh.bind(this);
this.setNewEventVisibility = this.setNewEventVisibility.bind(this);
this.setView = this.setView.bind(this);
}
......@@ -79,8 +81,8 @@ export class LogbookContainer extends React.Component {
<PeriodicRefresher
initialValue={this.state.pageEvents.length}
intervalInMilliSeconds={20000}
isEnabled={true}
intervalInMilliSeconds={1000}
isEnabled={this.state.isEventListAutorefreshEnabled}
periodicCallback={(onSuccess, onFailure) => getEventsByInvestigationIdRequest(user.sessionId, investigationId, GUI_CONFIG().EVENTS_PER_DOWNLOAD, 0, selectionFilter.find, GUI_CONFIG().DEFAULT_SORTING_FILTER, onSuccess, onFailure)}>
<EventListMenu
availableTags={this.props.availableTags}
......@@ -88,12 +90,15 @@ export class LogbookContainer extends React.Component {
getEvents={this.getEvents}
investigationId={investigationId}
isNewEventVisible={this.state.isNewEventVisible}
isEventListAutorefreshEnabled={this.state.isEventListAutorefreshEnabled}
numberOfMatchingEventsFound={this.state.eventCountSinceLastRefreshForCurrentSelectionFilter}
reverseEventsSortingByCreationDate={this.reverseEventsSortingByCreationDate}
searchEvents={this.searchEvents}
sessionId={user.sessionId}
setEventListAutorefresh={this.setEventListAutorefresh}
setNewEventVisibility={this.setNewEventVisibility}
setView={this.setView}
sortingFilter={this.state.sortingFilter}
selectionFilter={selectionFilter}
view={this.state.view}
......@@ -268,6 +273,17 @@ export class LogbookContainer extends React.Component {
});
}
/**
* Set the current event list auto refresh mode
* @param {bool} value new value for the mode
*/
setEventListAutorefresh(value) {
let newChoice = value === undefined ? false : value;
if (this.state.isEventListAutorefreshEnabled !== value) {
this.setState({ isEventListAutorefreshEnabled: value })
}
}
/**
* Change the current view to the requested view
* @param {string} view the requested view
......
import React from 'react';
import PropTypes from 'prop-types';
/* React component which can trigger a call periodically and pass the callback result to its child */
class PeriodicRefresher extends React.Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data
}
this.timer = setInterval(() => { return this.props.periodicCallback(this.onSuccess, this.onFailure) }, this.props.intervalInMilliSeconds);
data: this.props.initialValue
};
this.setRepetition = this.setRepetition.bind(this);
if (this.props.isEnabled === true) { this.setRepetition() };
}
render() {
return React.cloneElement(this.props.children, { periodicData: this.state.data, initialValue: this.props.initialValue });
return React.cloneElement(this.props.children, { periodicdata: this.state.data });
}
componentDidUpdate() {
if (this.props.isEnabled !== undefined) {
if (this.props.isEnabled === true) { this.setRepetition() }
else { clearInterval(this.intervalId) }
}
}
onSuccess(data) {
......@@ -17,8 +30,22 @@ class PeriodicRefresher extends React.Component {
}
onFailure() {
console.log('Periodic callback failed')
}
}
setRepetition() {
this.intervalId = setInterval(() => { return this.props.periodicCallback(this.onSuccess, this.onFailure) }, this.props.intervalInMilliSeconds);
}
}
PeriodicRefresher.propTypes = {
/* Initial value returned in periodicData property to PeriodicRefresher's child. Can be anything. It must be a similar object to what periodic data will return in normal operation */
initialValue: PropTypes.any,
/* Timer interval between 2 calls to the callback periodicCallback */
intervalInMilliSeconds: PropTypes.number.isRequired,
/* whether the period call is enabled or disabled */
isEnabled: PropTypes.bool,
/* callback function which will be triggered periodically */
periodicCallback: PropTypes.func.isRequired
}
export default PeriodicRefresher;
\ No newline at end of file
import React from 'react';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import PeriodicRefresher from '../../src/containers/Logbook/PeriodicRefresher';
import { Iterable } from 'immutable';
// const resources = require('../resources/newlyAvailableEventsDialogue.resource.js')
beforeEach(() => {
Enzyme.configure({ adapter: new Adapter() })
})
describe("periodicRefresher unit tests", () => {
function getShallowedWrapper(initialValue, intervalInMilliSeconds, isEnabled, periodicCallback) {
return Enzyme.mount(<PeriodicRefresher
initialValue={initialValue}
intervalInMilliSeconds={intervalInMilliSeconds}
isEnabled={isEnabled}
periodicCallback={periodicCallback}>
<div id='child'> empty</div>
</PeriodicRefresher>
);
}
it('calls the callback periodically when enabled', (done) => {
let mockedPeriodicCallback = jest.fn();
// instanciate the componet. THis start the callback counts
let wrapper = getShallowedWrapper([], 1000, true, mockedPeriodicCallback);
// waitt 10s
setTimeout(() => {
expect(mockedPeriodicCallback.mock.calls.length).toBeGreaterThan(2);
done();
}, 4000);
})
it('does not call the callback when not enabled', (done) => {
let mockedPeriodicCallback = jest.fn();
// instanciate the componet. THis start the callback counts
let wrapper = getShallowedWrapper([], 1000, false, mockedPeriodicCallback);
// waitt 10s
setTimeout(() => {
expect(mockedPeriodicCallback.mock.calls.length).toBe(0);
done();
}, 4000);
})
it('transmits initialValue to its child in periodicdata property at initialization', () => {
let wrapper = getShallowedWrapper('initialValue', 1000, false, () => null);
expect(wrapper.find({ id: 'child' }).prop('periodicdata')).toEqual('initialValue');
})
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment