diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx index 911769762a8570aab8b68964a6238f90baa0407b..ee56b4b582c0453960aba4fe82db60b34490ba93 100644 --- a/src/lib/project-saver-hoc.jsx +++ b/src/lib/project-saver-hoc.jsx @@ -59,7 +59,12 @@ const ProjectSaverHOC = function (WrappedComponent) { // but then it'd be hard to turn this listening off in our tests window.onbeforeunload = e => this.leavePageConfirm(e); } + + // Allow the GUI consumer to pass in a function to receive a trigger + // for triggering thumbnail or whole project saves. + // These functions are called with null on unmount to prevent stale references. this.props.onSetProjectThumbnailer(this.getProjectThumbnail); + this.props.onSetProjectSaver(this.tryToAutoSave); } componentDidUpdate (prevProps) { if (!this.props.isAnyCreatingNewState && prevProps.isAnyCreatingNewState) { @@ -116,6 +121,7 @@ const ProjectSaverHOC = function (WrappedComponent) { // window.onbeforeunload = undefined; // eslint-disable-line no-undefined // Remove project thumbnailer function since the components are unmounting this.props.onSetProjectThumbnailer(null); + this.props.onSetProjectSaver(null); } leavePageConfirm (e) { if (this.props.projectChanged) { @@ -310,6 +316,7 @@ const ProjectSaverHOC = function (WrappedComponent) { onRemixing, onSetProjectUnchanged, onSetProjectThumbnailer, + onSetProjectSaver, onShowAlert, onShowCopySuccessAlert, onShowRemixSuccessAlert, @@ -376,6 +383,7 @@ const ProjectSaverHOC = function (WrappedComponent) { autoSaveIntervalSecs: 120, onRemixing: () => {}, onSetProjectThumbnailer: () => {}, + onSetProjectSaver: () => {}, onUpdateProjectData: saveProjectToServer }; const mapStateToProps = (state, ownProps) => { diff --git a/test/unit/util/project-saver-hoc.test.jsx b/test/unit/util/project-saver-hoc.test.jsx index 1336daef0b0a8f9bd0bbb13ebd4b1984d4dff52c..56ed39d44f9816dc7fd4015b2d242829bc2232c7 100644 --- a/test/unit/util/project-saver-hoc.test.jsx +++ b/test/unit/util/project-saver-hoc.test.jsx @@ -465,4 +465,27 @@ describe('projectSaverHOC', () => { expect(setThumb).toHaveBeenCalledTimes(2); expect(setThumb.mock.calls[1][0]).toBe(null); }); + + test('uses onSetProjectSaver on mount/unmount', () => { + const Component = () => <div />; + const WrappedComponent = projectSaverHOC(Component); + const setSaver = jest.fn(); + const mounted = mount( + <WrappedComponent + store={store} + vm={vm} + onSetProjectSaver={setSaver} + /> + ); + // Set project saver should be called on mount + expect(setSaver).toHaveBeenCalledTimes(1); + + // And it should not pass that function on to wrapped element + expect(mounted.find(Component).props().onSetProjectSaver).toBeUndefined(); + + // Unmounting should call it again with null + mounted.unmount(); + expect(setSaver).toHaveBeenCalledTimes(2); + expect(setSaver.mock.calls[1][0]).toBe(null); + }); });