Allow heading tags (h1-h6) in ContentSanitizer so news editor headings render

This commit is contained in:
2026-06-04 07:52:57 +02:00
parent 0b33a1b074
commit 15870ddb1f
191 changed files with 15453 additions and 1786 deletions

View File

@@ -1,11 +1,18 @@
import React from 'react'
import { cleanup, render, waitFor } from '@testing-library/react'
function prepareEnvironment() {
document.head.innerHTML = '<meta name="csrf-token" content="csrf-token" />'
vi.spyOn(Storage.prototype, 'getItem').mockReturnValue('visitor-123')
vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => {})
const storage = new Map([['academy.analytics.visitor-id', 'visitor-123']])
vi.spyOn(Storage.prototype, 'getItem').mockImplementation((key) => storage.get(String(key)) ?? null)
vi.spyOn(Storage.prototype, 'setItem').mockImplementation((key, value) => {
storage.set(String(key), String(value))
})
globalThis.fetch = vi.fn(() => Promise.resolve({ ok: true, headers: { get: () => 'application/json' }, json: () => Promise.resolve({ ok: true }) }))
}
function cleanupEnvironment() {
cleanup()
vi.restoreAllMocks()
document.head.innerHTML = ''
}
@@ -66,5 +73,73 @@ test('academy search click attribution falls back to keepalive fetch when sendBe
expect(globalThis.fetch).toHaveBeenCalledTimes(1)
expect(globalThis.fetch.mock.calls[0][1].keepalive).toBe(true)
cleanupEnvironment()
})
test('academy page analytics includes custom metadata and varies page-view once keys by tracking context', async () => {
prepareEnvironment()
const { useAcademyPageAnalytics } = await import('./academyAnalytics.js')
Object.defineProperty(navigator, 'sendBeacon', {
configurable: true,
value: undefined,
})
function TestPage({ analytics }) {
useAcademyPageAnalytics(analytics)
return React.createElement('div', null, 'Academy page')
}
const { rerender } = render(
React.createElement(TestPage, {
analytics: {
enabled: true,
eventUrl: '/academy/analytics/events',
pageName: 'academy_prompts_popular',
contentType: 'academy_prompt_popular',
contentId: null,
trackingKey: 'period:30d',
metadata: { period: '30d', period_days: 30 },
},
}),
)
await waitFor(() => {
expect(globalThis.fetch).toHaveBeenCalledTimes(2)
})
const firstPageView = globalThis.fetch.mock.calls
.map((call) => JSON.parse(call[1].body))
.find((payload) => payload.event_type === 'academy_page_view')
expect(firstPageView.metadata.period).toBe('30d')
expect(firstPageView.metadata.period_days).toBe(30)
rerender(
React.createElement(TestPage, {
analytics: {
enabled: true,
eventUrl: '/academy/analytics/events',
pageName: 'academy_prompts_popular',
contentType: 'academy_prompt_popular',
contentId: null,
trackingKey: 'period:7d',
metadata: { period: '7d', period_days: 7 },
},
}),
)
await waitFor(() => {
expect(globalThis.fetch).toHaveBeenCalledTimes(4)
})
const pageViews = globalThis.fetch.mock.calls
.map((call) => JSON.parse(call[1].body))
.filter((payload) => payload.event_type === 'academy_page_view')
expect(pageViews).toHaveLength(2)
expect(pageViews[1].metadata.period).toBe('7d')
cleanupEnvironment()
})