Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lib/hash-parser-hoc.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const HashParserHOC = function (WrappedComponent) {
const mapDispatchToProps = dispatch => ({
setProjectId: projectId => dispatch(setProjectId(projectId))
});
// Allow incoming props to override redux-provided props. Used to mock in tests.
const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(
{}, stateProps, dispatchProps, ownProps
);
Expand Down
1 change: 1 addition & 0 deletions src/lib/project-fetcher-hoc.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const ProjectFetcherHOC = function (WrappedComponent) {
dispatch(onFetchedProjectData(projectData, loadingState)),
setProjectId: projectId => dispatch(setProjectId(projectId))
});
// Allow incoming props to override redux-provided props. Used to mock in tests.
const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(
{}, stateProps, dispatchProps, ownProps
);
Expand Down
8 changes: 7 additions & 1 deletion src/lib/vm-manager-hoc.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,15 @@ const vmManagerHOC = function (WrappedComponent) {
onLoadedProject: loadingState => dispatch(onLoadedProject(loadingState))
});

// Allow incoming props to override redux-provided props. Used to mock in tests.
const mergeProps = (stateProps, dispatchProps, ownProps) => Object.assign(

This comment was marked as abuse.

{}, stateProps, dispatchProps, ownProps
);

return connect(
mapStateToProps,
mapDispatchToProps
mapDispatchToProps,
mergeProps
)(VMManager);
};

Expand Down
14 changes: 12 additions & 2 deletions test/unit/util/project-fetcher-hoc.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,30 @@ describe('ProjectFetcherHOC', () => {
expect(mockSetProjectIdFunc.mock.calls[0][0]).toBe('100');
});
test('when there is a reduxProjectId and isFetchingWithProjectId is true, it loads the project', () => {
const mockedOnFetchedProject = jest.fn();
const originalLoad = storage.load;
storage.load = jest.fn((type, id) => Promise.resolve({data: id}));
const Component = ({projectId}) => <div>{projectId}</div>;
const WrappedComponent = ProjectFetcherHOC(Component);
const mounted = mountWithIntl(<WrappedComponent store={store} />);
const mounted = mountWithIntl(
<WrappedComponent
store={store}
onFetchedProjectData={mockedOnFetchedProject}
/>
);
mounted.setProps({
reduxProjectId: '100',
isFetchingWithId: true,
loadingState: LoadingState.FETCHING_WITH_ID
});
mounted.update();
expect(storage.load).toHaveBeenLastCalledWith(
storage.AssetType.Project, '100', storage.DataFormat.JSON
);
storage.load = originalLoad;
// nextTick needed since storage.load is async, and onFetchedProject is called in its then()
process.nextTick(
() => expect(mockedOnFetchedProject)
.toHaveBeenLastCalledWith('100', LoadingState.FETCHING_WITH_ID)
);
});
});
101 changes: 101 additions & 0 deletions test/unit/util/vm-manager-hoc.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import 'web-audio-test-api';

import React from 'react';
import configureStore from 'redux-mock-store';
import {mount} from 'enzyme';
import VM from 'scratch-vm';
import {LoadingState} from '../../../src/reducers/project-state';

import vmManagerHOC from '../../../src/lib/vm-manager-hoc.jsx';

describe('VMManagerHOC', () => {
const mockStore = configureStore();
let store;
let vm;

beforeEach(() => {
store = mockStore({
scratchGui: {
projectState: {}
}
});
vm = new VM();
vm.attachAudioEngine = jest.fn();
vm.setCompatibilityMode = jest.fn();
vm.start = jest.fn();
});
test('when it mounts, the vm is initialized', () => {
const Component = () => (<div />);
const WrappedComponent = vmManagerHOC(Component);
mount(
<WrappedComponent
store={store}
vm={vm}
/>
);
expect(vm.attachAudioEngine.mock.calls.length).toBe(1);
expect(vm.setCompatibilityMode.mock.calls.length).toBe(1);
expect(vm.start.mock.calls.length).toBe(1);
expect(vm.initialized).toBe(true);
});
test('if it mounts with an initialized vm, it does not reinitialize the vm', () => {
const Component = () => <div />;
const WrappedComponent = vmManagerHOC(Component);
vm.initialized = true;
mount(
<WrappedComponent
store={store}
vm={vm}
/>
);
expect(vm.attachAudioEngine.mock.calls.length).toBe(0);
expect(vm.setCompatibilityMode.mock.calls.length).toBe(0);
expect(vm.start.mock.calls.length).toBe(0);
expect(vm.initialized).toBe(true);
});
test('if the isLoadingWithId prop becomes true, it loads project data into the vm', () => {
vm.loadProject = jest.fn(() => Promise.resolve());
const mockedOnLoadedProject = jest.fn();
const Component = () => <div />;
const WrappedComponent = vmManagerHOC(Component);
const mounted = mount(
<WrappedComponent
isLoadingWithId={false}
store={store}
vm={vm}
onLoadedProject={mockedOnLoadedProject}
/>
);
mounted.setProps({
isLoadingWithId: true,
loadingState: LoadingState.LOADING_VM_WITH_ID,
projectData: '100'
});
expect(vm.loadProject).toHaveBeenLastCalledWith('100');
// nextTick needed since vm.loadProject is async, and we have to wait for it :/
process.nextTick(() => expect(mockedOnLoadedProject).toHaveBeenLastCalledWith(LoadingState.LOADING_VM_WITH_ID));
});
test('if there is projectData, the child is rendered', () => {
const Component = () => <div />;
const WrappedComponent = vmManagerHOC(Component);
const mounted = mount(
<WrappedComponent
projectData="100"
store={store}
vm={vm}
/>
);
expect(mounted.find('div').length).toBe(1);
});
test('if there is no projectData, nothing is rendered', () => {
const Component = () => <div />;
const WrappedComponent = vmManagerHOC(Component);
const mounted = mount(
<WrappedComponent
store={store}
vm={vm}
/>
);
expect(mounted.find('div').length).toBe(0);
});
});