fix(frontend): fix motd e2e test

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-10-24 08:57:42 +02:00 committed by Erik Michelson
parent dd4e50103f
commit dfbd45301c
6 changed files with 31 additions and 9 deletions

View file

@ -4,19 +4,20 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
const MOTD_LOCAL_STORAGE_KEY = 'motd.lastModified' import { MOTD_LOCAL_STORAGE_KEY } from '../../src/components/global-dialogs/motd-modal/local-storage-keys'
const motdMockHtml = 'This is the test motd text' const motdMockHtml = 'This is the test motd text'
describe('Motd', () => { describe('Motd', () => {
it("shows, dismisses and won't show again a motd modal", () => { it("shows, dismisses and won't show again a motd modal", () => {
localStorage.removeItem(MOTD_LOCAL_STORAGE_KEY) window.localStorage.removeItem(MOTD_LOCAL_STORAGE_KEY)
cy.visitHistory() cy.visitHistory()
cy.getSimpleRendererBody().should('contain.text', motdMockHtml) cy.getSimpleRendererBody().should('contain.text', motdMockHtml)
cy.getByCypressId('motd-dismiss') cy.getByCypressId('motd-dismiss')
.click() .click()
.then(() => { .then(() => {
expect(localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).not.to.be.eq(null) expect(window.localStorage.getItem(MOTD_LOCAL_STORAGE_KEY)).not.to.be.eq(null)
}) })
cy.getByCypressId('motd-modal').should('not.exist') cy.getByCypressId('motd-modal').should('not.exist')
cy.reload() cy.reload()

View file

@ -5,6 +5,7 @@
*/ */
import { AuthProviderType } from '../../src/api/config/types' import { AuthProviderType } from '../../src/api/config/types'
import { HttpMethod } from '../../src/handler-utils/respond-to-matching-request' import { HttpMethod } from '../../src/handler-utils/respond-to-matching-request'
import { IGNORE_MOTD, MOTD_LOCAL_STORAGE_KEY } from '../../src/components/global-dialogs/motd-modal/local-storage-keys'
declare namespace Cypress { declare namespace Cypress {
interface Chainable { interface Chainable {
@ -87,6 +88,7 @@ Cypress.Commands.add('logOut', () => {
beforeEach(() => { beforeEach(() => {
cy.loadConfig() cy.loadConfig()
window.localStorage.setItem(MOTD_LOCAL_STORAGE_KEY, IGNORE_MOTD)
cy.logIn() cy.logIn()
cy.intercept('GET', '/public/motd.md', { cy.intercept('GET', '/public/motd.md', {

View file

@ -8,9 +8,10 @@
import React, { useCallback, useMemo, useState } from 'react' import React, { useCallback, useMemo, useState } from 'react'
import { useMotdContextValue } from '../../motd/motd-context' import { useMotdContextValue } from '../../motd/motd-context'
import { useLocalStorage } from 'react-use' import { useLocalStorage } from 'react-use'
import { MOTD_LOCAL_STORAGE_KEY } from './fetch-motd'
import { MotdModal } from './motd-modal' import { MotdModal } from './motd-modal'
import { testId } from '../../../utils/test-id' import { testId } from '../../../utils/test-id'
import { isTestMode } from '../../../utils/test-modes'
import { IGNORE_MOTD, MOTD_LOCAL_STORAGE_KEY } from './local-storage-keys'
/** /**
* Reads the motd from the context and shows it in a modal. * Reads the motd from the context and shows it in a modal.
@ -19,13 +20,22 @@ import { testId } from '../../../utils/test-id'
*/ */
export const CachedMotdModal: React.FC = () => { export const CachedMotdModal: React.FC = () => {
const contextValue = useMotdContextValue() const contextValue = useMotdContextValue()
const [cachedLastModified, saveLocalStorage] = useLocalStorage<string>(MOTD_LOCAL_STORAGE_KEY, undefined) const [cachedLastModified, saveLocalStorage] = useLocalStorage<string>(MOTD_LOCAL_STORAGE_KEY, undefined, {
raw: true
})
const [dismissed, setDismissed] = useState(false) const [dismissed, setDismissed] = useState(false)
const show = useMemo(() => { const show = useMemo(() => {
const lastModified = contextValue?.lastModified const lastModified = contextValue?.lastModified
return cachedLastModified !== lastModified && lastModified !== undefined && !dismissed
if (cachedLastModified === IGNORE_MOTD && isTestMode) {
return false
}
if (cachedLastModified === lastModified || lastModified === undefined) {
return false
}
return !dismissed
}, [cachedLastModified, contextValue?.lastModified, dismissed]) }, [cachedLastModified, contextValue?.lastModified, dismissed])
const doDismiss = useCallback(() => { const doDismiss = useCallback(() => {

View file

@ -5,8 +5,6 @@
*/ */
import { defaultConfig } from '../../../api/common/default-config' import { defaultConfig } from '../../../api/common/default-config'
export const MOTD_LOCAL_STORAGE_KEY = 'motd.lastModified'
export interface MotdApiResponse { export interface MotdApiResponse {
motdText: string motdText: string
lastModified: string lastModified: string

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
export const MOTD_LOCAL_STORAGE_KEY: string = 'motd.lastModified'
export const IGNORE_MOTD: string = 'IGNORE_MOTD'

View file

@ -62,7 +62,10 @@ export const respondToTestRequest = <T>(req: NextApiRequest, res: NextApiRespons
res.status(405).send('Method not allowed') res.status(405).send('Method not allowed')
} else if (!isTestMode) { } else if (!isTestMode) {
res.status(404).send('Route only available in test mode') res.status(404).send('Route only available in test mode')
} else if (!['127.0.0.1', '::1', '::ffff:127.0.0.1'].includes(req.socket.remoteAddress)) { } else if (
req.socket.remoteAddress === undefined ||
!['127.0.0.1', '::1', '::ffff:127.0.0.1'].includes(req.socket.remoteAddress)
) {
res.status(403).send(`Request must come from localhost but was ${req.socket.remoteAddress}`) res.status(403).send(`Request must come from localhost but was ${req.socket.remoteAddress}`)
} else { } else {
res.status(200).json(response()) res.status(200).json(response())