Merge pull request #6053 from overleaf/ta-pdf-detach-tests

PDF Detach Misc Tests

GitOrigin-RevId: 9615c8fdfd8964a9c63d7c91e4596d397a1d35dc
This commit is contained in:
Timothée Alby
2021-12-15 09:04:46 +00:00
committed by Copybot
parent 1201a733d9
commit 44eca312ff
16 changed files with 817 additions and 28 deletions
@@ -0,0 +1,34 @@
import sinon from 'sinon'
import { renderHook } from '@testing-library/react-hooks'
import useCallbackHandlers from '../../../../frontend/js/shared/hooks/use-callback-handlers'
describe('useCallbackHandlers', function () {
it('adds, removes and calls all handlers without duplicate', async function () {
const handler1 = sinon.stub()
const handler2 = sinon.stub()
const handler3 = sinon.stub()
const { result } = renderHook(() => useCallbackHandlers())
result.current.addHandler(handler1)
result.current.deleteHandler(handler1)
result.current.addHandler(handler1)
result.current.addHandler(handler2)
result.current.deleteHandler(handler2)
result.current.addHandler(handler3)
result.current.addHandler(handler3)
result.current.callHandlers('foo')
result.current.callHandlers(1337)
sinon.assert.calledTwice(handler1)
sinon.assert.calledWith(handler1, 'foo')
sinon.assert.calledWith(handler1, 1337)
sinon.assert.notCalled(handler2)
sinon.assert.calledTwice(handler3)
})
})
@@ -0,0 +1,82 @@
import sinon from 'sinon'
import { expect } from 'chai'
import { renderHookWithEditorContext } from '../../helpers/render-with-context'
import sysendTestHelper from '../../helpers/sysend'
import useDetachAction from '../../../../frontend/js/shared/hooks/use-detach-action'
const actionName = 'some-action'
const actionFunction = sinon.stub()
describe('useDetachAction', function () {
beforeEach(function () {
window.metaAttributesCache = new Map()
})
afterEach(function () {
window.metaAttributesCache = new Map()
actionFunction.reset()
})
it('broadcast message as sender', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detacher')
const { result } = renderHookWithEditorContext(() =>
useDetachAction(actionName, actionFunction, 'detacher', 'detached')
)
const triggerFn = result.current
sysendTestHelper.resetHistory()
triggerFn('param')
expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
role: 'detacher',
event: `action-${actionName}`,
data: { args: ['param'] },
})
sinon.assert.notCalled(actionFunction)
})
it('call function as non-sender', async function () {
const { result } = renderHookWithEditorContext(() =>
useDetachAction(actionName, actionFunction, 'detacher', 'detached')
)
const triggerFn = result.current
sysendTestHelper.resetHistory()
triggerFn('param')
expect(sysendTestHelper.getDetachCalls('broadcast').length).to.equal(0)
sinon.assert.calledWith(actionFunction, 'param')
})
it('receive message and call function as target', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detached')
renderHookWithEditorContext(() =>
useDetachAction(actionName, actionFunction, 'detacher', 'detached')
)
sysendTestHelper.receiveMessage({
role: 'detached',
event: `action-${actionName}`,
data: { args: ['param'] },
})
sinon.assert.calledWith(actionFunction, 'param')
})
it('receive message and does not call function as non-target', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detacher')
renderHookWithEditorContext(() =>
useDetachAction(actionName, actionFunction, 'detacher', 'detached')
)
sysendTestHelper.receiveMessage({
role: 'detached',
event: `action-${actionName}`,
data: { args: [] },
})
sinon.assert.notCalled(actionFunction)
})
})
@@ -0,0 +1,187 @@
import { act } from '@testing-library/react-hooks'
import { expect } from 'chai'
import sinon from 'sinon'
import { renderHookWithEditorContext } from '../../helpers/render-with-context'
import sysendTestHelper from '../../helpers/sysend'
import useDetachLayout from '../../../../frontend/js/shared/hooks/use-detach-layout'
describe('useDetachLayout', function () {
let openStub
let closeStub
beforeEach(function () {
window.metaAttributesCache = new Map()
openStub = sinon.stub(window, 'open')
closeStub = sinon.stub(window, 'close')
})
afterEach(function () {
window.metaAttributesCache = new Map()
openStub.restore()
closeStub.restore()
})
it('detaching', async function () {
// 1. create hook in normal mode
const { result } = renderHookWithEditorContext(() => useDetachLayout())
expect(result.current.reattach).to.be.a('function')
expect(result.current.detach).to.be.a('function')
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.be.null
// 2. detach
act(() => {
result.current.detach()
})
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.true
expect(result.current.role).to.equal('detacher')
sinon.assert.calledOnce(openStub)
sinon.assert.calledWith(
openStub,
'https://www.test-overleaf.com/detached',
'_blank'
)
})
it('detacher role', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detacher')
// 1. create hook in detacher mode
const { result } = renderHookWithEditorContext(() => useDetachLayout())
expect(result.current.reattach).to.be.a('function')
expect(result.current.detach).to.be.a('function')
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detacher')
// 2. simulate connected detached tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detached',
event: 'connected',
})
expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
role: 'detacher',
event: 'up',
})
expect(result.current.isLinked).to.be.true
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detacher')
// 3. simulate closed detached tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detached',
event: 'closed',
})
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detacher')
// 4. simulate up detached tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detached',
event: 'up',
})
expect(result.current.isLinked).to.be.true
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detacher')
// 5. simulate closed detacher tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detacher',
event: 'closed',
})
expect(result.current.isLinked).to.be.true
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detacher')
expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
role: 'detacher',
event: 'up',
})
// 6. reattach
sysendTestHelper.spy.broadcast.resetHistory()
act(() => {
result.current.reattach()
})
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.be.null
expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
role: 'detacher',
event: 'reattach',
})
})
it('detached role', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detached')
// 1. create hook in detached mode
const { result } = renderHookWithEditorContext(() => useDetachLayout())
expect(result.current.reattach).to.be.a('function')
expect(result.current.detach).to.be.a('function')
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detached')
// 2. simulate up detacher tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detacher',
event: 'up',
})
expect(result.current.isLinked).to.be.true
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detached')
// 3. simulate closed detacher tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detacher',
event: 'closed',
})
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detached')
// 4. simulate up detacher tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detacher',
event: 'up',
})
expect(result.current.isLinked).to.be.true
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detached')
// 5. simulate closed detached tab
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detached',
event: 'closed',
})
expect(result.current.isLinked).to.be.true
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detached')
expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
role: 'detached',
event: 'up',
})
// 6. simulate reattach event
sysendTestHelper.spy.broadcast.resetHistory()
sysendTestHelper.receiveMessage({
role: 'detacher',
event: 'reattach',
})
expect(result.current.isLinked).to.be.false
expect(result.current.isLinking).to.be.false
expect(result.current.role).to.equal('detached')
sinon.assert.called(closeStub)
})
})
@@ -0,0 +1,68 @@
import { act } from '@testing-library/react-hooks'
import { expect } from 'chai'
import { renderHookWithEditorContext } from '../../helpers/render-with-context'
import sysendTestHelper from '../../helpers/sysend'
import useDetachState from '../../../../frontend/js/shared/hooks/use-detach-state'
const stateKey = 'some-key'
describe('useDetachState', function () {
beforeEach(function () {
window.metaAttributesCache = new Map()
})
afterEach(function () {
window.metaAttributesCache = new Map()
})
it('create and update state', async function () {
const defaultValue = 'foobar'
const { result } = renderHookWithEditorContext(() =>
useDetachState(stateKey, defaultValue)
)
const [value, setValue] = result.current
expect(value).to.equal(defaultValue)
expect(setValue).to.be.a('function')
const newValue = 'barbaz'
act(() => {
setValue(newValue)
})
expect(result.current[0]).to.equal(newValue)
})
it('broadcast message as sender', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detacher')
const { result } = renderHookWithEditorContext(() =>
useDetachState(stateKey, null, 'detacher', 'detached')
)
const [, setValue] = result.current
sysendTestHelper.resetHistory()
const newValue = 'barbaz'
act(() => {
setValue(newValue)
})
expect(sysendTestHelper.getLastBroacastMessage()).to.deep.equal({
role: 'detacher',
event: `state-${stateKey}`,
data: { value: newValue },
})
})
it('receive message as target', async function () {
window.metaAttributesCache.set('ol-detachRole', 'detached')
const { result } = renderHookWithEditorContext(() =>
useDetachState(stateKey, null, 'detacher', 'detached')
)
const newValue = 'barbaz'
sysendTestHelper.receiveMessage({
role: 'detached',
event: `state-${stateKey}`,
data: { value: newValue },
})
expect(result.current[0]).to.equal(newValue)
})
})
@@ -0,0 +1,53 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { buildUrlWithDetachRole } from '../../../../frontend/js/shared/utils/url-helper'
describe('url-helper', function () {
let locationStub
describe('buildUrlWithDetachRole', function () {
beforeEach(function () {
locationStub = sinon.stub(window, 'location')
})
afterEach(function () {
locationStub.restore()
})
describe('without mode', function () {
it('removes trailing slash', function () {
locationStub.value('https://www.ovelreaf.com/project/1abc/')
expect(buildUrlWithDetachRole().href).to.equal(
'https://www.ovelreaf.com/project/1abc'
)
})
it('clears the mode from the current URL', function () {
locationStub.value('https://www.ovelreaf.com/project/2abc/detached')
expect(buildUrlWithDetachRole().href).to.equal(
'https://www.ovelreaf.com/project/2abc'
)
locationStub.value('https://www.ovelreaf.com/project/2abc/detacher/')
expect(buildUrlWithDetachRole().href).to.equal(
'https://www.ovelreaf.com/project/2abc'
)
})
})
describe('with mode', function () {
it('handles with trailing slash', function () {
locationStub.value('https://www.ovelreaf.com/project/3abc/')
expect(buildUrlWithDetachRole('detacher').href).to.equal(
'https://www.ovelreaf.com/project/3abc/detacher'
)
})
it('handles without trailing slash', function () {
locationStub.value('https://www.ovelreaf.com/project/4abc')
expect(buildUrlWithDetachRole('detached').href).to.equal(
'https://www.ovelreaf.com/project/4abc/detached'
)
})
})
})
})