mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-02-06 19:53:27 +00:00
feat(realtime): disconnect user on user login status change
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
9b9eafc948
commit
972ec8c9c5
3 changed files with 104 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
@ -19,6 +19,7 @@ import { useOnImageUploadFromRenderer } from './hooks/image-upload-from-renderer
|
|||
import { useCodeMirrorTablePasteExtension } from './hooks/table-paste/use-code-mirror-table-paste-extension'
|
||||
import { useApplyScrollState } from './hooks/use-apply-scroll-state'
|
||||
import { useCursorActivityCallback } from './hooks/use-cursor-activity-callback'
|
||||
import { useDisconnectOnUserLoginStatusChange } from './hooks/use-disconnect-on-user-login-status-change'
|
||||
import { useUpdateCodeMirrorReference } from './hooks/use-update-code-mirror-reference'
|
||||
import { useBindYTextToRedux } from './hooks/yjs/use-bind-y-text-to-redux'
|
||||
import { useCodeMirrorYjsExtension } from './hooks/yjs/use-code-mirror-yjs-extension'
|
||||
|
@ -56,6 +57,9 @@ export const EditorPane: React.FC<EditorPaneProps> = ({ scrollState, onScroll, o
|
|||
useApplyScrollState(scrollState)
|
||||
|
||||
const messageTransporter = useRealtimeConnection()
|
||||
|
||||
useDisconnectOnUserLoginStatusChange(messageTransporter)
|
||||
|
||||
const realtimeDoc = useRealtimeDoc()
|
||||
const editorScrollExtension = useCodeMirrorScrollWatchExtension(onScroll)
|
||||
const tablePasteExtensions = useCodeMirrorTablePasteExtension()
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import type { LoginUserInfo } from '../../../../api/me/types'
|
||||
import * as UseApplicationStateModule from '../../../../hooks/common/use-application-state'
|
||||
import type { ApplicationState } from '../../../../redux/application-state'
|
||||
import { useDisconnectOnUserLoginStatusChange } from './use-disconnect-on-user-login-status-change'
|
||||
import type { MessageTransporter } from '@hedgedoc/commons'
|
||||
import { render } from '@testing-library/react'
|
||||
import React, { Fragment } from 'react'
|
||||
import { Mock } from 'ts-mockery'
|
||||
|
||||
jest.mock('../../../../hooks/common/use-application-state')
|
||||
|
||||
describe('use logout on user change', () => {
|
||||
const TestComponent: React.FC<{ messageTransporter: MessageTransporter }> = ({ messageTransporter }) => {
|
||||
useDisconnectOnUserLoginStatusChange(messageTransporter)
|
||||
return <Fragment />
|
||||
}
|
||||
|
||||
const mockUseApplicationState = (userLoggedIn: boolean) => {
|
||||
jest
|
||||
.spyOn(UseApplicationStateModule, 'useApplicationState')
|
||||
.mockImplementation((fn) =>
|
||||
fn(Mock.of<ApplicationState>({ user: userLoggedIn ? Mock.of<LoginUserInfo>({}) : null }))
|
||||
)
|
||||
}
|
||||
|
||||
let disconnectCallback: jest.Mock
|
||||
let messageTransporter: MessageTransporter
|
||||
|
||||
beforeEach(() => {
|
||||
disconnectCallback = jest.fn()
|
||||
messageTransporter = Mock.of<MessageTransporter>({ disconnect: disconnectCallback })
|
||||
})
|
||||
|
||||
it("doesn't disconnect if user is logged in before", () => {
|
||||
mockUseApplicationState(true)
|
||||
render(<TestComponent messageTransporter={messageTransporter} />)
|
||||
expect(disconnectCallback).not.toBeCalled()
|
||||
})
|
||||
|
||||
it("doesn't disconnect if user is not logged in before", () => {
|
||||
mockUseApplicationState(false)
|
||||
render(<TestComponent messageTransporter={messageTransporter} />)
|
||||
expect(disconnectCallback).not.toBeCalled()
|
||||
})
|
||||
|
||||
it('disconnects if user switches from logged in to logged out', () => {
|
||||
mockUseApplicationState(true)
|
||||
const view = render(<TestComponent messageTransporter={messageTransporter} />)
|
||||
expect(disconnectCallback).not.toBeCalled()
|
||||
|
||||
mockUseApplicationState(false)
|
||||
view.rerender(<TestComponent messageTransporter={messageTransporter} />)
|
||||
expect(disconnectCallback).toBeCalled()
|
||||
})
|
||||
|
||||
it('disconnects if user switches from logged out to logged in', () => {
|
||||
mockUseApplicationState(false)
|
||||
const view = render(<TestComponent messageTransporter={messageTransporter} />)
|
||||
expect(disconnectCallback).not.toBeCalled()
|
||||
|
||||
mockUseApplicationState(true)
|
||||
view.rerender(<TestComponent messageTransporter={messageTransporter} />)
|
||||
expect(disconnectCallback).toBeCalled()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||
import type { MessageTransporter } from '@hedgedoc/commons'
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
/**
|
||||
* Disconnects the given {@link MessageTransporter message transporter} if the user status changes through log-in or log-out.
|
||||
*
|
||||
* @param messageTransporter the message transporter to disconnect
|
||||
*/
|
||||
export const useDisconnectOnUserLoginStatusChange = (messageTransporter: MessageTransporter): void => {
|
||||
const previousIsLoggedIn = useRef<boolean | undefined>()
|
||||
const isLoggedIn = useApplicationState((state) => state.user !== null)
|
||||
useEffect(() => {
|
||||
if (previousIsLoggedIn.current === undefined) {
|
||||
previousIsLoggedIn.current = isLoggedIn
|
||||
return
|
||||
}
|
||||
if (previousIsLoggedIn.current === isLoggedIn) {
|
||||
return
|
||||
}
|
||||
previousIsLoggedIn.current = isLoggedIn
|
||||
messageTransporter.disconnect()
|
||||
}, [isLoggedIn, messageTransporter])
|
||||
}
|
Loading…
Reference in a new issue