use-detach-layout.spec.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import '../../helpers/bootstrap-3'
  2. import useDetachLayout from '../../../../frontend/js/shared/hooks/use-detach-layout'
  3. import { detachChannel, testDetachChannel } from '../../helpers/detach-channel'
  4. import { EditorProviders } from '../../helpers/editor-providers'
  5. import { Button, Checkbox, ControlLabel, FormGroup } from 'react-bootstrap'
  6. const DetachLayoutTest = () => {
  7. const { role, reattach, detach, isLinked, isLinking, isRedundant } =
  8. useDetachLayout()
  9. return (
  10. <fieldset>
  11. <legend>
  12. role: <span id="role">{role || 'none'}</span>
  13. </legend>
  14. <FormGroup>
  15. <Checkbox id="isLinked" inline checked={isLinked} readOnly />
  16. <ControlLabel>linked</ControlLabel>
  17. </FormGroup>
  18. <FormGroup>
  19. <Checkbox id="isLinking" inline checked={isLinking} readOnly />
  20. <ControlLabel>linking</ControlLabel>
  21. </FormGroup>
  22. <FormGroup>
  23. <Checkbox id="isRedundant" inline checked={isRedundant} readOnly />
  24. <ControlLabel>redundant</ControlLabel>
  25. </FormGroup>
  26. <Button id="reattach" onClick={reattach}>
  27. reattach
  28. </Button>
  29. <Button id="detach" onClick={detach}>
  30. detach
  31. </Button>
  32. </fieldset>
  33. )
  34. }
  35. describe('useDetachLayout', function () {
  36. beforeEach(function () {
  37. window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
  38. cy.stub(window, 'open').as('openWindow')
  39. cy.stub(window, 'close').as('closeWindow')
  40. cy.interceptEvents()
  41. })
  42. it('detaching', function () {
  43. // 1. create hook in normal mode
  44. cy.mount(
  45. <EditorProviders>
  46. <DetachLayoutTest />
  47. </EditorProviders>
  48. )
  49. cy.get('#isLinked').should('not.be.checked')
  50. cy.get('#isLinking').should('not.be.checked')
  51. cy.get('#role').should('have.text', 'none')
  52. // 2. detach
  53. cy.get('#detach').click()
  54. cy.get('@openWindow').should(
  55. 'have.been.calledOnceWith',
  56. Cypress.sinon.match(/\/detached/),
  57. '_blank'
  58. )
  59. cy.get('#isLinked').should('not.be.checked')
  60. cy.get('#isLinking').should('be.checked')
  61. cy.get('#role').should('have.text', 'detacher')
  62. })
  63. it('detacher role', function () {
  64. // 1. create hook in detacher mode
  65. window.metaAttributesCache.set('ol-detachRole', 'detacher')
  66. cy.mount(
  67. <EditorProviders>
  68. <DetachLayoutTest />
  69. </EditorProviders>
  70. )
  71. cy.get('#isLinked').should('not.be.checked')
  72. cy.get('#isLinking').should('not.be.checked')
  73. cy.get('#role').should('have.text', 'detacher')
  74. cy.spy(detachChannel, 'postMessage').as('postDetachMessage')
  75. cy.wrap(null).then(() => {
  76. testDetachChannel.postMessage({
  77. role: 'detached',
  78. event: 'connected',
  79. })
  80. })
  81. // 2. simulate connected detached tab
  82. cy.get('@postDetachMessage').should('have.been.calledWith', {
  83. role: 'detacher',
  84. event: 'up',
  85. })
  86. cy.get('#isLinked').should('be.checked')
  87. cy.get('#isLinking').should('not.be.checked')
  88. cy.get('#role').should('have.text', 'detacher')
  89. // 3. simulate closed detached tab
  90. cy.wrap(null).then(() => {
  91. testDetachChannel.postMessage({
  92. role: 'detached',
  93. event: 'closed',
  94. })
  95. })
  96. cy.get('#isLinked').should('not.be.checked')
  97. cy.get('#isLinking').should('not.be.checked')
  98. cy.get('#role').should('have.text', 'detacher')
  99. // 4. simulate up detached tab
  100. cy.wrap(null).then(() => {
  101. testDetachChannel.postMessage({
  102. role: 'detached',
  103. event: 'up',
  104. })
  105. })
  106. cy.get('#isLinked').should('be.checked')
  107. cy.get('#isLinking').should('not.be.checked')
  108. cy.get('#role').should('have.text', 'detacher')
  109. // 5. reattach
  110. cy.get('@postDetachMessage').invoke('resetHistory')
  111. cy.get('#reattach').click()
  112. cy.get('#isLinked').should('not.be.checked')
  113. cy.get('#isLinking').should('not.be.checked')
  114. cy.get('#role').should('have.text', 'none')
  115. cy.get('@postDetachMessage').should('have.been.calledWith', {
  116. role: 'detacher',
  117. event: 'reattach',
  118. })
  119. })
  120. it('reset detacher role when other detacher tab connects', function () {
  121. // 1. create hook in detacher mode
  122. window.metaAttributesCache.set('ol-detachRole', 'detacher')
  123. cy.mount(
  124. <EditorProviders>
  125. <DetachLayoutTest />
  126. </EditorProviders>
  127. )
  128. cy.get('#isLinked').should('not.be.checked')
  129. cy.get('#isLinking').should('not.be.checked')
  130. cy.get('#role').should('have.text', 'detacher')
  131. // 2. simulate other detacher tab
  132. cy.wrap(null).then(() => {
  133. testDetachChannel.postMessage({
  134. role: 'detacher',
  135. event: 'up',
  136. })
  137. })
  138. cy.get('#isRedundant').should('be.checked')
  139. cy.get('#role').should('have.text', 'none')
  140. })
  141. it('detached role', function () {
  142. // 1. create hook in detached mode
  143. window.metaAttributesCache.set('ol-detachRole', 'detached')
  144. cy.mount(
  145. <EditorProviders>
  146. <DetachLayoutTest />
  147. </EditorProviders>
  148. )
  149. cy.get('#isLinked').should('not.be.checked')
  150. cy.get('#isLinking').should('not.be.checked')
  151. cy.get('#role').should('have.text', 'detached')
  152. // 2. simulate up detacher tab
  153. cy.wrap(null).then(() => {
  154. testDetachChannel.postMessage({
  155. role: 'detacher',
  156. event: 'up',
  157. })
  158. })
  159. cy.get('#isLinked').should('be.checked')
  160. cy.get('#isLinking').should('not.be.checked')
  161. cy.get('#role').should('have.text', 'detached')
  162. // 3. simulate closed detacher tab
  163. cy.wrap(null).then(() => {
  164. testDetachChannel.postMessage({
  165. role: 'detacher',
  166. event: 'closed',
  167. })
  168. })
  169. cy.get('#isLinked').should('not.be.checked')
  170. cy.get('#isLinking').should('not.be.checked')
  171. cy.get('#role').should('have.text', 'detached')
  172. // 4. simulate up detacher tab
  173. cy.wrap(null).then(() => {
  174. testDetachChannel.postMessage({
  175. role: 'detacher',
  176. event: 'up',
  177. })
  178. })
  179. cy.get('#isLinked').should('be.checked')
  180. cy.get('#isLinking').should('not.be.checked')
  181. cy.get('#role').should('have.text', 'detached')
  182. // 5. simulate closed detached tab
  183. cy.spy(detachChannel, 'postMessage').as('postDetachMessage')
  184. cy.wrap(null).then(() => {
  185. testDetachChannel.postMessage({
  186. role: 'detached',
  187. event: 'closed',
  188. })
  189. })
  190. cy.get('#isLinked').should('be.checked')
  191. cy.get('#isLinking').should('not.be.checked')
  192. cy.get('#role').should('have.text', 'detached')
  193. cy.get('@postDetachMessage').should('have.been.calledWith', {
  194. role: 'detached',
  195. event: 'up',
  196. })
  197. // 6. simulate reattach event
  198. cy.get('@postDetachMessage').invoke('resetHistory')
  199. cy.wrap(null).then(() => {
  200. testDetachChannel.postMessage({
  201. role: 'detacher',
  202. event: 'reattach',
  203. })
  204. })
  205. cy.get('#isLinked').should('not.be.checked')
  206. cy.get('#isLinking').should('not.be.checked')
  207. cy.get('#role').should('have.text', 'detached')
  208. cy.get('@closeWindow').should('have.been.called')
  209. })
  210. })