vm-manager-hoc.test.jsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import 'web-audio-test-api';
  2. import React from 'react';
  3. import configureStore from 'redux-mock-store';
  4. import {mount} from 'enzyme';
  5. import VM from 'scratch-vm';
  6. import {LoadingState} from '../../../src/reducers/project-state';
  7. import vmManagerHOC from '../../../src/lib/vm-manager-hoc.jsx';
  8. describe('VMManagerHOC', () => {
  9. const mockStore = configureStore();
  10. let store;
  11. let vm;
  12. beforeEach(() => {
  13. store = mockStore({
  14. scratchGui: {
  15. projectState: {},
  16. mode: {},
  17. vmStatus: {}
  18. },
  19. locales: {
  20. locale: '',
  21. messages: {}
  22. }
  23. });
  24. vm = new VM();
  25. vm.attachAudioEngine = jest.fn();
  26. vm.setCompatibilityMode = jest.fn();
  27. vm.setLocale = jest.fn();
  28. vm.start = jest.fn();
  29. });
  30. test('when it mounts in player mode, the vm is initialized but not started', () => {
  31. const Component = () => (<div />);
  32. const WrappedComponent = vmManagerHOC(Component);
  33. mount(
  34. <WrappedComponent
  35. isPlayerOnly
  36. isStarted={false}
  37. store={store}
  38. vm={vm}
  39. />
  40. );
  41. expect(vm.attachAudioEngine.mock.calls.length).toBe(1);
  42. expect(vm.setCompatibilityMode.mock.calls.length).toBe(1);
  43. expect(vm.setLocale.mock.calls.length).toBe(1);
  44. expect(vm.initialized).toBe(true);
  45. // But vm should not be started automatically
  46. expect(vm.start).not.toHaveBeenCalled();
  47. });
  48. test('when it mounts in editor mode, the vm is initialized and started', () => {
  49. const Component = () => (<div />);
  50. const WrappedComponent = vmManagerHOC(Component);
  51. mount(
  52. <WrappedComponent
  53. isPlayerOnly={false}
  54. isStarted={false}
  55. store={store}
  56. vm={vm}
  57. />
  58. );
  59. expect(vm.attachAudioEngine.mock.calls.length).toBe(1);
  60. expect(vm.setCompatibilityMode.mock.calls.length).toBe(1);
  61. expect(vm.setLocale.mock.calls.length).toBe(1);
  62. expect(vm.initialized).toBe(true);
  63. expect(vm.start).toHaveBeenCalled();
  64. });
  65. test('if it mounts with an initialized vm, it does not reinitialize the vm but will start it', () => {
  66. const Component = () => <div />;
  67. const WrappedComponent = vmManagerHOC(Component);
  68. vm.initialized = true;
  69. mount(
  70. <WrappedComponent
  71. isPlayerOnly={false}
  72. isStarted={false}
  73. store={store}
  74. vm={vm}
  75. />
  76. );
  77. expect(vm.attachAudioEngine.mock.calls.length).toBe(0);
  78. expect(vm.setCompatibilityMode.mock.calls.length).toBe(0);
  79. expect(vm.setLocale.mock.calls.length).toBe(0);
  80. expect(vm.initialized).toBe(true);
  81. expect(vm.start).toHaveBeenCalled();
  82. });
  83. test('if it mounts without starting the VM, it can be started by switching to editor mode', () => {
  84. const Component = () => <div />;
  85. const WrappedComponent = vmManagerHOC(Component);
  86. vm.initialized = true;
  87. const mounted = mount(
  88. <WrappedComponent
  89. isPlayerOnly
  90. isStarted={false}
  91. store={store}
  92. vm={vm}
  93. />
  94. );
  95. expect(vm.start).not.toHaveBeenCalled();
  96. mounted.setProps({
  97. isPlayerOnly: false
  98. });
  99. expect(vm.start).toHaveBeenCalled();
  100. });
  101. test('if it mounts with an initialized and started VM, it does not start again', () => {
  102. const Component = () => <div />;
  103. const WrappedComponent = vmManagerHOC(Component);
  104. vm.initialized = true;
  105. const mounted = mount(
  106. <WrappedComponent
  107. isPlayerOnly
  108. isStarted
  109. store={store}
  110. vm={vm}
  111. />
  112. );
  113. expect(vm.start).not.toHaveBeenCalled();
  114. mounted.setProps({
  115. isPlayerOnly: false
  116. });
  117. expect(vm.start).not.toHaveBeenCalled();
  118. });
  119. test('if the isLoadingWithId prop becomes true, it loads project data into the vm', () => {
  120. vm.loadProject = jest.fn(() => Promise.resolve());
  121. const mockedOnLoadedProject = jest.fn();
  122. const Component = () => <div />;
  123. const WrappedComponent = vmManagerHOC(Component);
  124. const mounted = mount(
  125. <WrappedComponent
  126. fontsLoaded
  127. isLoadingWithId={false}
  128. store={store}
  129. vm={vm}
  130. onLoadedProject={mockedOnLoadedProject}
  131. />
  132. );
  133. mounted.setProps({
  134. canSave: true,
  135. isLoadingWithId: true,
  136. loadingState: LoadingState.LOADING_VM_WITH_ID,
  137. projectData: '100'
  138. });
  139. expect(vm.loadProject).toHaveBeenLastCalledWith('100');
  140. // nextTick needed since vm.loadProject is async, and we have to wait for it :/
  141. process.nextTick(() => (
  142. expect(mockedOnLoadedProject).toHaveBeenLastCalledWith(LoadingState.LOADING_VM_WITH_ID, true)
  143. ));
  144. });
  145. test('if the fontsLoaded prop becomes true, it loads project data into the vm', () => {
  146. vm.loadProject = jest.fn(() => Promise.resolve());
  147. const mockedOnLoadedProject = jest.fn();
  148. const Component = () => <div />;
  149. const WrappedComponent = vmManagerHOC(Component);
  150. const mounted = mount(
  151. <WrappedComponent
  152. isLoadingWithId
  153. store={store}
  154. vm={vm}
  155. onLoadedProject={mockedOnLoadedProject}
  156. />
  157. );
  158. mounted.setProps({
  159. canSave: false,
  160. fontsLoaded: true,
  161. loadingState: LoadingState.LOADING_VM_WITH_ID,
  162. projectData: '100'
  163. });
  164. expect(vm.loadProject).toHaveBeenLastCalledWith('100');
  165. // nextTick needed since vm.loadProject is async, and we have to wait for it :/
  166. process.nextTick(() => (
  167. expect(mockedOnLoadedProject).toHaveBeenLastCalledWith(LoadingState.LOADING_VM_WITH_ID, false)
  168. ));
  169. });
  170. test('if the fontsLoaded prop is false, project data is never loaded', () => {
  171. vm.loadProject = jest.fn(() => Promise.resolve());
  172. const mockedOnLoadedProject = jest.fn();
  173. const Component = () => <div />;
  174. const WrappedComponent = vmManagerHOC(Component);
  175. const mounted = mount(
  176. <WrappedComponent
  177. isLoadingWithId
  178. store={store}
  179. vm={vm}
  180. onLoadedProject={mockedOnLoadedProject}
  181. />
  182. );
  183. mounted.setProps({
  184. loadingState: LoadingState.LOADING_VM_WITH_ID,
  185. projectData: '100'
  186. });
  187. expect(vm.loadProject).toHaveBeenCalledTimes(0);
  188. process.nextTick(() => expect(mockedOnLoadedProject).toHaveBeenCalledTimes(0));
  189. });
  190. });