use-detach-layout.spec.tsx 6.9 KB

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