import { describe, expect, test, vi } from 'vitest' import { getDOM } from '@/tests/helpers/e2etest' import { allVersions } from '@/versions/lib/all-versions' import { getCategorizedAuditLogEvents } from '../lib' describe('audit log events docs', () => { vi.setConfig({ testTimeout: 60 * 1000 }) const auditLogEventPages = [ { path: '/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/audit-log-events-for-your-organization', type: 'organization', }, { path: '/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/audit-log-events-for-your-enterprise', type: 'enterprise', }, { path: '/authentication/keeping-your-account-and-data-secure/security-log-events', type: 'user', }, ] as const // This test ensures that the audit log event page components and Markdown // file are in sync. Additionally, it checks all event categories are // rendered and spot checks the events of one category are all rendered. test.each(auditLogEventPages)( 'loads audit log event data for all versions on page %o', async (page) => { for (const version of Object.keys(allVersions)) { // the enterprise events page has no FPT versioned audit log data if (page.type === 'enterprise' && version === 'free-pro-team@latest') continue const auditLogEvents = getCategorizedAuditLogEvents(page.type, version) if (Object.keys(auditLogEvents).length === 0) { console.warn(`There are no audit log events for ${page.path} with version '${version}'.`) continue } // check that we get and render all the audit log event categories // from the schema files const auditLogCategories = Object.keys(auditLogEvents).map((category) => category) const versionedAuditLogEventsPage = `/${version}${page.path}` const $ = await getDOM(versionedAuditLogEventsPage) const categoryH3Ids = $('h3') .map((_, h3) => $(h3).attr('id')) .get() const categoryNames = categoryH3Ids.map((category) => category) const everyAuditLogCategoryPresent = auditLogCategories.every((category) => categoryNames.includes(category), ) expect(categoryH3Ids.length).toBeGreaterThan(0) expect(everyAuditLogCategoryPresent).toBe(true) // Spot check audit log event data by checking all the event actions under // the workflows category which is available across all audit log event // pages. const workflowsEventActions = auditLogEvents.workflows.map((e) => e.action) // each definition list item corresponds to an audit log event, the format is: // //
event action
//
event description
// // we grab all the rendered workflow event action names and for our // comparison we check that all the action names from the audit log // schema data are included in the rendered action names. const workflowsEventDTs = $('#workflows + div > div > dl > dt').get() const renderedWorkflowsEventActions = workflowsEventDTs.map((dt) => { return $(dt).find('code').text() }) const everyWorkflowsEventActionPresent = workflowsEventActions.every((action) => renderedWorkflowsEventActions.includes(action), ) expect(renderedWorkflowsEventActions.length).toBeGreaterThan(0) expect(everyWorkflowsEventActionPresent).toBe(true) } }, ) test('audit log event pages have DOM markers needed for extracting search content', async () => { // We just need to test one of the 3 audit log event pages because they all use the same component // so we'll use the organization events page const $ = await getDOM( '/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/audit-log-events-for-your-organization', ) const rootSelector = '[data-search=article-body]' const $root = $(rootSelector) expect($root.length).toBe(1) // on the audit log event pages the lead is separate from the article body const leadSelector = '[data-search=lead] p' const $lead = $(leadSelector) expect($lead.length).toBe(1) }) test('category notes are rendered when present', async () => { // Test organization page which should have category notes const $ = await getDOM( '/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/audit-log-events-for-your-organization', ) // Look for category note elements - they should appear before tables const categoryNotes = $('.category-note') // If there are categories with notes configured, we should see them rendered if (categoryNotes.length > 0) { categoryNotes.each((_, note) => { const $note = $(note) expect($note.text().length).toBeGreaterThan(0) // Should be followed by a div (the category events) const $nextDiv = $note.next('div') expect($nextDiv.length).toBe(1) }) } }) test('git category note is rendered on appropriate pages', async () => { // Test enterprise page which should have git category note for GHES const $ = await getDOM( '/enterprise-server@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/audit-log-events-for-your-enterprise', ) // Look for git category heading const gitHeading = $('#git') if (gitHeading.length > 0) { // Should have a category note before the div const $noteOrTable = gitHeading.next() // Either the next element is a note (followed by div) or directly a div if ($noteOrTable.hasClass('category-note')) { expect($noteOrTable.text()).toContain('Git events') expect($noteOrTable.next('div').length).toBe(1) } else if ($noteOrTable.is('div')) { // Direct div is fine too - means no note for this category expect($noteOrTable.is('div')).toBe(true) } } }) })