Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ yarn-error.log*
/ingest/__pycache__/
/myenv/
venv
.python-version
.python-version

# Test coverage reports
/coverage/
4 changes: 3 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ module.exports = {
url: 'https://learn.netdata.cloud',
baseUrl: '/',
onBrokenLinks: 'warn',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon-32x32.png',
organizationName: 'netdata',
projectName: 'netdata',
markdown: {
mermaid: true,
hooks: {
onBrokenMarkdownLinks: 'warn',
},
},
themes: ['@docusaurus/theme-mermaid'],
themeConfig: {
Expand Down
77 changes: 45 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,59 @@
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
"write-heading-ids": "docusaurus write-heading-ids",
"test": "vitest",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage",
"test:ui": "vitest --ui"
},
"dependencies": {
"@babel/core": "^7.26.10",
"@docusaurus/core": "^3.7.0",
"@docusaurus/mdx-loader": "^3.7.0",
"@docusaurus/plugin-google-gtag": "^3.7.0",
"@docusaurus/plugin-google-tag-manager": "^3.7.0",
"@docusaurus/preset-classic": "^3.7.0",
"@docusaurus/theme-common": "^3.7.0",
"@docusaurus/theme-mermaid": "^3.7.0",
"@mdx-js/react": "^3.0.0",
"@tailwindcss/typography": "^0.4.0",
"@types/react": "^18.0.21",
"@babel/core": "^7.29.0",
"@docusaurus/core": "^3.9.2",
"@docusaurus/mdx-loader": "^3.9.2",
"@docusaurus/plugin-google-gtag": "^3.9.2",
"@docusaurus/plugin-google-tag-manager": "^3.9.2",
"@docusaurus/preset-classic": "^3.9.2",
"@docusaurus/theme-common": "^3.9.2",
"@docusaurus/theme-mermaid": "^3.9.2",
"@mdx-js/react": "^3.1.1",
"@tailwindcss/typography": "^0.5.19",
"@types/react": "^19.2.10",
"acorn": "^8.14.1",
"axios": "^1.12.0",
"babel": "^6.23.0",
"clsx": "^1.1.1",
"dotenv": "^8.2.0",
"postcss": "^8.4.31",
"postcss-import": "^15.1.0",
"postcss-nesting": "^13.0.1",
"posthog-docusaurus": "^2.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-icons": "^4.2.0",
"react-inlinesvg": "^2.2.2",
"axios": "^1.13.4",
"clsx": "^2.1.1",
"dotenv": "^17.2.3",
"postcss": "^8.5.6",
"postcss-import": "^16.1.1",
"postcss-nesting": "^14.0.0",
"posthog-docusaurus": "^2.0.5",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-icons": "^5.5.0",
"react-inlinesvg": "^4.2.0",
"react-loadable": "^5.5.0",
"react-markdown": "^10.1.0",
"react-player": "^2.10.0",
"react-player": "^3.4.0",
"remark-gfm": "^4.0.1",
"swagger-ui": "^4.18.1",
"typescript": "^4.8.2",
"webpack": "^5.94.0"
"swagger-ui": "^5.31.0",
"typescript": "^5.9.3",
"webpack": "^5.104.1"
},
"devDependencies": {
"autoprefixer": "^10.2.5",
"postcss-loader": "^5.2.0",
"postcss-preset-env": "^7.8.0",
"tailwindcss": "^2.1.2"
"@tailwindcss/postcss": "^4.1.18",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@vitejs/plugin-react": "^5.1.2",
"@vitest/coverage-v8": "^4.0.18",
"autoprefixer": "^10.4.24",
"happy-dom": "^20.4.0",
"jsdom": "^27.4.0",
"postcss-loader": "^8.2.0",
"postcss-preset-env": "^11.1.2",
"tailwindcss": "^4.1.18",
"vitest": "^4.0.18"
},
"browserslist": {
"production": [
Expand Down
5 changes: 5 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
plugins: {
'@tailwindcss/postcss': {},
},
};
15 changes: 15 additions & 0 deletions src/__mocks__/@docusaurus/Link.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

// Mock Docusaurus Link component
const Link = React.forwardRef(function Link({ to, href, children, ...props }, ref) {
const destination = to || href || '#';
return (
<a ref={ref} href={destination} data-testid="docusaurus-link" {...props}>
{children}
</a>
);
});

Link.displayName = 'MockLink';

export default Link;
21 changes: 21 additions & 0 deletions src/__mocks__/@docusaurus/Translate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { vi } from 'vitest';

// Mock Translate component
const Translate = ({ children, id, description }) => {
return React.createElement('span', { 'data-testid': 'translate', 'data-id': id }, children);
};

// Mock translate function
export const translate = vi.fn((config, values) => {
if (typeof config === 'string') return config;
let message = config.message || '';
if (values) {
Object.entries(values).forEach(([key, value]) => {
message = message.replace(`{${key}}`, value);
});
}
return message;
});

export default Translate;
49 changes: 49 additions & 0 deletions src/__mocks__/@docusaurus/plugin-content-docs/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { vi } from 'vitest';

// Default mock doc data
const mockDocData = {
metadata: {
title: 'Test Doc Title',
description: 'Test doc description',
editUrl: 'https://github.com/netdata/learn/edit/master/docs/test.md',
lastUpdatedAt: 1640000000000,
lastUpdatedBy: 'test-user',
formattedLastUpdatedAt: 'Dec 20, 2021',
tags: [],
permalink: '/docs/test',
slug: '/test',
},
frontMatter: {
id: 'test-doc',
title: 'Test Doc',
hide_title: false,
},
contentTitle: undefined, // undefined triggers synthetic title
toc: [],
};

// Clone to allow modification
let currentMockDoc = { ...mockDocData };

export const useDoc = vi.fn(() => currentMockDoc);

// Export for test manipulation
export const __setMockDoc = (docOverrides) => {
currentMockDoc = {
...mockDocData,
...docOverrides,
metadata: { ...mockDocData.metadata, ...(docOverrides?.metadata || {}) },
frontMatter: { ...mockDocData.frontMatter, ...(docOverrides?.frontMatter || {}) },
};
};

export const __resetMockDoc = () => {
currentMockDoc = { ...mockDocData };
};

export const useDocById = vi.fn(() => mockDocData);

export const useActiveDocContext = vi.fn(() => ({
activeVersion: { name: 'current', path: '/docs' },
activeDoc: mockDocData,
}));
72 changes: 72 additions & 0 deletions src/__mocks__/@docusaurus/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import { vi } from 'vitest';

// Mock history object
const mockHistory = {
push: vi.fn(),
replace: vi.fn(),
go: vi.fn(),
goBack: vi.fn(),
goForward: vi.fn(),
listen: vi.fn(() => vi.fn()),
location: {
pathname: '/docs/test',
search: '',
hash: '',
state: null,
},
};

// Mock location object
const mockLocation = {
pathname: '/docs/test',
search: '',
hash: '',
state: null,
key: 'test-key',
};

export const useHistory = vi.fn(() => mockHistory);
export const useLocation = vi.fn(() => mockLocation);
export const useParams = vi.fn(() => ({}));

export const Redirect = ({ to }) => {
return React.createElement('div', { 'data-testid': 'redirect', 'data-to': to }, `Redirect to ${to}`);
};

export const withRouter = (Component) => {
return function WrappedComponent(props) {
return React.createElement(Component, {
...props,
history: mockHistory,
location: mockLocation,
});
};
};

// Default location state
const defaultLocation = {
pathname: '/docs/test',
search: '',
hash: '',
state: null,
key: 'test-key',
};

// Export mocks for test manipulation
export const __mockHistory = mockHistory;
export const __mockLocation = mockLocation;
export const __setMockPathname = (pathname) => {
mockLocation.pathname = pathname;
mockHistory.location.pathname = pathname;
};

export const __setMockLocation = (locationOverrides) => {
Object.assign(mockLocation, locationOverrides);
Object.assign(mockHistory.location, locationOverrides);
};

export const __resetMockLocation = () => {
Object.assign(mockLocation, defaultLocation);
Object.assign(mockHistory.location, defaultLocation);
};
56 changes: 56 additions & 0 deletions src/__mocks__/@docusaurus/theme-common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { vi } from 'vitest';

// Mock color mode context
let mockColorMode = 'light';

export const useColorMode = vi.fn(() => ({
colorMode: mockColorMode,
setColorMode: vi.fn((mode) => {
mockColorMode = mode;
}),
isDarkTheme: mockColorMode === 'dark',
}));

// Export for test manipulation
export const __setMockColorMode = (mode) => {
mockColorMode = mode;
};

// Mock ThemeClassNames
export const ThemeClassNames = {
docs: {
docMarkdown: 'theme-doc-markdown',
docFooterEditMetaRow: 'theme-doc-footer-edit-meta-row',
},
common: {
editThisPage: 'theme-edit-this-page',
},
};

// Mock Details component
export const Details = React.forwardRef(function Details({ children, summary, ...props }, ref) {
return React.createElement(
'details',
{ ref, 'data-testid': 'docusaurus-details', ...props },
React.createElement('summary', null, summary),
children
);
});

// Mock usePrismTheme
export const usePrismTheme = vi.fn(() => ({
plain: { color: '#000', backgroundColor: '#fff' },
styles: [],
}));

// Mock useDocsSidebar
export const useDocsSidebar = vi.fn(() => ({
items: [],
}));

// Mock useWindowSize
export const useWindowSize = vi.fn(() => ({
width: 1024,
height: 768,
}));
13 changes: 13 additions & 0 deletions src/__mocks__/@docusaurus/theme-common/Details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

// Mock Details component from theme-common/Details
export const Details = React.forwardRef(function Details({ children, summary, className, ...props }, ref) {
return React.createElement(
'details',
{ ref, className, 'data-testid': 'docusaurus-details-generic', ...props },
summary && React.createElement('summary', null, summary),
children
);
});

export default { Details };
12 changes: 12 additions & 0 deletions src/__mocks__/@docusaurus/useIsBrowser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { vi } from 'vitest';

let isBrowser = true;

const useIsBrowser = vi.fn(() => isBrowser);

// Export for test manipulation
export const __setIsBrowser = (value) => {
isBrowser = value;
};

export default useIsBrowser;
12 changes: 12 additions & 0 deletions src/__mocks__/@theme-original/DocItem/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';

// Mock original DocItem/Footer
const Footer = (props) => {
return React.createElement(
'footer',
{ 'data-testid': 'original-doc-footer', ...props },
'Original Footer'
);
};

export default Footer;
12 changes: 12 additions & 0 deletions src/__mocks__/@theme-original/NavbarItem/ComponentTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Mock original NavbarItem ComponentTypes
export default {
default: () => null,
localeDropdown: () => null,
search: () => null,
dropdown: () => null,
html: () => null,
doc: () => null,
docSidebar: () => null,
docsVersion: () => null,
docsVersionDropdown: () => null,
};
Loading