@qwickapps/react-framework 1.3.4 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1688 -2
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
- package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +7 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/Html.d.ts +28 -18
- package/dist/components/Html.d.ts.map +1 -1
- package/dist/components/Logo.d.ts +12 -35
- package/dist/components/Logo.d.ts.map +1 -1
- package/dist/components/Markdown.d.ts +18 -13
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/QwickApp.d.ts +16 -3
- package/dist/components/QwickApp.d.ts.map +1 -1
- package/dist/components/QwickIcon.d.ts +23 -0
- package/dist/components/QwickIcon.d.ts.map +1 -0
- package/dist/components/SafeSpan.d.ts +12 -5
- package/dist/components/SafeSpan.d.ts.map +1 -1
- package/dist/components/Scaffold.d.ts.map +1 -1
- package/dist/components/base/ModelView.d.ts +101 -0
- package/dist/components/base/ModelView.d.ts.map +1 -0
- package/dist/components/base/index.d.ts +11 -0
- package/dist/components/base/index.d.ts.map +1 -0
- package/dist/components/blocks/Article.d.ts +12 -2
- package/dist/components/blocks/Article.d.ts.map +1 -1
- package/dist/components/blocks/Code.d.ts +13 -2
- package/dist/components/blocks/Code.d.ts.map +1 -1
- package/dist/components/blocks/Content.d.ts.map +1 -1
- package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
- package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
- package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
- package/dist/components/blocks/Footer.d.ts.map +1 -1
- package/dist/components/blocks/HeroBlock.d.ts +27 -13
- package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
- package/dist/components/blocks/Image.d.ts +41 -0
- package/dist/components/blocks/Image.d.ts.map +1 -0
- package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
- package/dist/components/blocks/ProductCard.d.ts.map +1 -1
- package/dist/components/blocks/Section.d.ts +16 -2
- package/dist/components/blocks/Section.d.ts.map +1 -1
- package/dist/components/blocks/Text.d.ts +41 -0
- package/dist/components/blocks/Text.d.ts.map +1 -0
- package/dist/components/blocks/index.d.ts +4 -0
- package/dist/components/blocks/index.d.ts.map +1 -1
- package/dist/components/buttons/Button.d.ts +23 -7
- package/dist/components/buttons/Button.d.ts.map +1 -1
- package/dist/components/forms/FormBlock.d.ts +19 -13
- package/dist/components/forms/FormBlock.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/input/ChoiceInputField.d.ts +17 -11
- package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
- package/dist/components/input/HtmlInputField.d.ts +17 -11
- package/dist/components/input/HtmlInputField.d.ts.map +1 -1
- package/dist/components/input/SelectInputField.d.ts +16 -10
- package/dist/components/input/SelectInputField.d.ts.map +1 -1
- package/dist/components/input/SwitchInputField.d.ts +16 -10
- package/dist/components/input/SwitchInputField.d.ts.map +1 -1
- package/dist/components/input/TextField.d.ts.map +1 -1
- package/dist/components/input/TextInputField.d.ts +16 -11
- package/dist/components/input/TextInputField.d.ts.map +1 -1
- package/dist/components/layout/GridCell.d.ts +23 -6
- package/dist/components/layout/GridCell.d.ts.map +1 -1
- package/dist/components/layout/GridLayout.d.ts +24 -23
- package/dist/components/layout/GridLayout.d.ts.map +1 -1
- package/dist/components/pages/FormPage.d.ts.map +1 -1
- package/dist/components/pages/Page.d.ts +49 -87
- package/dist/components/pages/Page.d.ts.map +1 -1
- package/dist/components/pages/index.d.ts +2 -2
- package/dist/components/pages/index.d.ts.map +1 -1
- package/dist/config/AppConfig.d.ts +49 -0
- package/dist/config/AppConfig.d.ts.map +1 -0
- package/dist/config/AppConfigBuilder.d.ts +75 -0
- package/dist/config/AppConfigBuilder.d.ts.map +1 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/types.d.ts +130 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.esm.js +451 -0
- package/dist/config.js +455 -0
- package/dist/contexts/PrintModeContext.d.ts +27 -0
- package/dist/contexts/PrintModeContext.d.ts.map +1 -0
- package/dist/contexts/QwickAppContext.d.ts +2 -2
- package/dist/contexts/QwickAppContext.d.ts.map +1 -1
- package/dist/contexts/ThemeContext.d.ts.map +1 -1
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/usePrintMode.d.ts +39 -0
- package/dist/hooks/usePrintMode.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +20722 -16021
- package/dist/index.js +20725 -16010
- package/dist/schemas/CodeSchema.d.ts +2 -1
- package/dist/schemas/CodeSchema.d.ts.map +1 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
- package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
- package/dist/schemas/ContentSchema.d.ts +2 -1
- package/dist/schemas/ContentSchema.d.ts.map +1 -1
- package/dist/schemas/GridCellSchema.d.ts +25 -0
- package/dist/schemas/GridCellSchema.d.ts.map +1 -0
- package/dist/schemas/GridLayoutSchema.d.ts +23 -0
- package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
- package/dist/schemas/HtmlSchema.d.ts +14 -0
- package/dist/schemas/HtmlSchema.d.ts.map +1 -0
- package/dist/schemas/ImageSchema.d.ts +32 -0
- package/dist/schemas/ImageSchema.d.ts.map +1 -0
- package/dist/schemas/LogoSchema.d.ts +35 -0
- package/dist/schemas/LogoSchema.d.ts.map +1 -0
- package/dist/schemas/MarkdownSchema.d.ts +14 -0
- package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/schemas/PageTemplateSchema.d.ts +31 -0
- package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
- package/dist/schemas/PrintConfigSchema.d.ts +31 -0
- package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
- package/dist/schemas/SectionSchema.d.ts +2 -1
- package/dist/schemas/SectionSchema.d.ts.map +1 -1
- package/dist/schemas/TextSchema.d.ts +37 -0
- package/dist/schemas/TextSchema.d.ts.map +1 -0
- package/dist/schemas/ViewModelSchema.d.ts +23 -0
- package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
- package/dist/schemas/index.d.ts +15 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
- package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
- package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
- package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
- package/dist/schemas/transformers/registry.d.ts +15 -0
- package/dist/schemas/transformers/registry.d.ts.map +1 -0
- package/dist/schemas/types/Serializable.d.ts +46 -0
- package/dist/schemas/types/Serializable.d.ts.map +1 -0
- package/dist/utils/htmlTransform.d.ts.map +1 -1
- package/dist/utils/reactUtils.d.ts +12 -3
- package/dist/utils/reactUtils.d.ts.map +1 -1
- package/package.json +17 -3
- package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
- package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
- package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
- package/src/__tests__/components/Logo.test.js +3 -3
- package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
- package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
- package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
- package/src/__tests__/components/base/ModelView.test.tsx +220 -0
- package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
- package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
- package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
- package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
- package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
- package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
- package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
- package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
- package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
- package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
- package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
- package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
- package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
- package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
- package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
- package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
- package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
- package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
- package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
- package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
- package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
- package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
- package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
- package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
- package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
- package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
- package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
- package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
- package/src/components/ErrorBoundary.tsx +8 -8
- package/src/components/Html.tsx +147 -44
- package/src/components/Logo.tsx +198 -100
- package/src/components/Markdown.tsx +125 -16
- package/src/components/QwickApp.tsx +64 -31
- package/src/components/QwickIcon.tsx +59 -0
- package/src/components/SafeSpan.tsx +65 -10
- package/src/components/Scaffold.tsx +2 -8
- package/src/components/base/ModelView.tsx +199 -0
- package/src/components/base/index.ts +11 -0
- package/src/components/blocks/Article.tsx +57 -18
- package/src/components/blocks/Code.md +529 -0
- package/src/components/blocks/Code.tsx +102 -15
- package/src/components/blocks/Content.tsx +25 -77
- package/src/components/blocks/CoverImageHeader.tsx +9 -4
- package/src/components/blocks/FeatureCard.tsx +1 -2
- package/src/components/blocks/FeatureGrid.tsx +19 -1
- package/src/components/blocks/Footer.tsx +13 -1
- package/src/components/blocks/HeroBlock.tsx +87 -20
- package/src/components/blocks/Image.tsx +395 -0
- package/src/components/blocks/PageBannerHeader.tsx +14 -12
- package/src/components/blocks/ProductCard.tsx +51 -52
- package/src/components/blocks/Section.tsx +113 -8
- package/src/components/blocks/Text.tsx +285 -0
- package/src/components/blocks/index.ts +4 -0
- package/src/components/buttons/Button.tsx +184 -15
- package/src/components/forms/FormBlock.tsx +70 -17
- package/src/components/index.ts +5 -0
- package/src/components/input/ChoiceInputField.tsx +48 -18
- package/src/components/input/HtmlInputField.tsx +48 -18
- package/src/components/input/SelectInputField.tsx +48 -16
- package/src/components/input/SwitchInputField.tsx +48 -17
- package/src/components/input/TextField.tsx +41 -1
- package/src/components/input/TextInputField.tsx +52 -18
- package/src/components/layout/GridCell.tsx +118 -9
- package/src/components/layout/GridLayout.tsx +125 -24
- package/src/components/pages/FormPage.tsx +0 -1
- package/src/components/pages/Page.css +304 -332
- package/src/components/pages/Page.tsx +307 -255
- package/src/components/pages/index.ts +2 -2
- package/src/config/AppConfig.ts +133 -0
- package/src/config/AppConfigBuilder.ts +421 -0
- package/src/config/__tests__/AppConfig.test.ts +385 -0
- package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
- package/src/config/index.ts +24 -0
- package/src/config/types.ts +170 -0
- package/src/config.ts +25 -0
- package/src/contexts/PrintModeContext.tsx +332 -0
- package/src/contexts/QwickAppContext.tsx +2 -2
- package/src/contexts/ThemeContext.tsx +1 -2
- package/src/contexts/index.ts +2 -0
- package/src/hooks/index.ts +5 -1
- package/src/hooks/usePrintMode.ts +73 -0
- package/src/index.ts +3 -0
- package/src/schemas/CodeSchema.ts +3 -3
- package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
- package/src/schemas/ContentSchema.ts +2 -1
- package/src/schemas/GridCellSchema.ts +164 -0
- package/src/schemas/GridLayoutSchema.ts +133 -0
- package/src/schemas/HtmlSchema.ts +47 -0
- package/src/schemas/ImageSchema.ts +235 -0
- package/src/schemas/LogoSchema.ts +241 -0
- package/src/schemas/MarkdownSchema.ts +47 -0
- package/src/schemas/PageTemplateSchema.ts +186 -0
- package/src/schemas/PrintConfigSchema.ts +207 -0
- package/src/schemas/README.md +661 -0
- package/src/schemas/SectionSchema.ts +2 -1
- package/src/schemas/TextSchema.ts +329 -0
- package/src/schemas/ViewModelSchema.ts +115 -0
- package/src/schemas/index.ts +21 -2
- package/src/schemas/transformers/ComponentTransformer.ts +403 -0
- package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
- package/src/schemas/transformers/registry.ts +72 -0
- package/src/schemas/types/Serializable.ts +51 -0
- package/src/stories/AccessibilityProvider.stories.tsx +253 -253
- package/src/stories/Article.stories.tsx +433 -433
- package/src/stories/Button.stories.tsx +1 -1
- package/src/stories/CardListGrid.stories.tsx +451 -451
- package/src/stories/ChoiceInputField.stories.tsx +503 -503
- package/src/stories/Code.stories.tsx +1 -1
- package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
- package/src/stories/Content.stories.tsx +393 -393
- package/src/stories/CoverImageHeader.stories.tsx +701 -701
- package/src/stories/DataBinding.advanced.stories.tsx +432 -432
- package/src/stories/DataProvider.stories.tsx +1192 -1192
- package/src/stories/FeatureCard.stories.tsx +557 -557
- package/src/stories/FeatureGrid.stories.tsx +594 -594
- package/src/stories/Footer.stories.tsx +640 -640
- package/src/stories/FormBlock.stories.tsx +760 -760
- package/src/stories/FormComponents.stories.tsx +349 -541
- package/src/stories/GridCell.stories.tsx +417 -0
- package/src/stories/GridLayout.stories.tsx +353 -0
- package/src/stories/HeroBlock.stories.tsx +862 -373
- package/src/stories/HtmlInputField.stories.tsx +474 -474
- package/src/stories/Image.stories.tsx +819 -0
- package/src/stories/Introduction.stories.tsx +667 -667
- package/src/stories/LayoutBlocks.stories.tsx +324 -324
- package/src/stories/Logo.stories.tsx +165 -6
- package/src/stories/Markdown.stories.tsx +137 -137
- package/src/stories/ModelView.stories.tsx +477 -0
- package/src/stories/Page.stories.tsx +688 -688
- package/src/stories/PageBannerHeader.stories.tsx +864 -864
- package/src/stories/PaletteSwitcher.stories.tsx +119 -119
- package/src/stories/ProductCard.stories.tsx +424 -424
- package/src/stories/QwickApp.stories.tsx +368 -368
- package/src/stories/ResponsiveMenu.stories.tsx +249 -249
- package/src/stories/SafeSpan.stories.tsx +531 -531
- package/src/stories/Section.stories.tsx +90 -2
- package/src/stories/SelectInputField.stories.tsx +524 -524
- package/src/stories/Text.stories.tsx +560 -0
- package/src/stories/TextInputField.stories.tsx +443 -443
- package/src/stories/ThemeSwitcher.stories.tsx +123 -123
- package/src/utils/htmlTransform.tsx +74 -53
- package/src/utils/reactUtils.tsx +57 -6
- package/dist/index.bundled.css +0 -12
- /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
- /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
- /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GridLayout Component Serialization Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the GridLayout component's ModelView implementation and
|
|
5
|
+
* serialization capabilities using ComponentTransformer.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { render, screen } from '@testing-library/react';
|
|
12
|
+
import '@testing-library/jest-dom';
|
|
13
|
+
import { ComponentTransformer } from '../../../schemas/transformers/ComponentTransformer';
|
|
14
|
+
import { GridLayout } from '../../../components/layout/GridLayout';
|
|
15
|
+
import { GridCell } from '../../../components/layout/GridCell';
|
|
16
|
+
import { Text } from '../../../components/layout/../blocks/Text';
|
|
17
|
+
import { Button } from '../../../components/layout/../buttons/Button';
|
|
18
|
+
|
|
19
|
+
describe('GridLayout Serialization', () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
// Clear component registry for clean tests
|
|
22
|
+
ComponentTransformer.clearRegistry();
|
|
23
|
+
|
|
24
|
+
// Register all necessary components
|
|
25
|
+
ComponentTransformer.registerComponent(GridLayout as any);
|
|
26
|
+
ComponentTransformer.registerComponent(GridCell as any);
|
|
27
|
+
ComponentTransformer.registerComponent(Text as any);
|
|
28
|
+
ComponentTransformer.registerComponent(Button as any);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
ComponentTransformer.clearRegistry();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('Basic Serialization', () => {
|
|
36
|
+
it('should serialize and deserialize basic grid layout', () => {
|
|
37
|
+
// Create original component
|
|
38
|
+
const originalComponent = (
|
|
39
|
+
<GridLayout
|
|
40
|
+
columns={3}
|
|
41
|
+
spacing="medium"
|
|
42
|
+
equalHeight={true}
|
|
43
|
+
>
|
|
44
|
+
<div>Column 1</div>
|
|
45
|
+
<div>Column 2</div>
|
|
46
|
+
<div>Column 3</div>
|
|
47
|
+
</GridLayout>
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Serialize
|
|
51
|
+
const serialized = ComponentTransformer.serialize(originalComponent);
|
|
52
|
+
expect(serialized).toBeTruthy();
|
|
53
|
+
expect(typeof serialized).toBe('string');
|
|
54
|
+
|
|
55
|
+
// Parse to check structure
|
|
56
|
+
const parsed = JSON.parse(serialized);
|
|
57
|
+
expect(parsed.tag).toBe('GridLayout');
|
|
58
|
+
expect(parsed.version).toBe('1.0.0');
|
|
59
|
+
expect(parsed.data.columns).toBe(3);
|
|
60
|
+
expect(parsed.data.spacing).toBe('medium');
|
|
61
|
+
expect(parsed.data.equalHeight).toBe(true);
|
|
62
|
+
|
|
63
|
+
// Children should be serialized as JSON string
|
|
64
|
+
expect(typeof parsed.data.children).toBe('string');
|
|
65
|
+
const children = JSON.parse(parsed.data.children);
|
|
66
|
+
expect(Array.isArray(children)).toBe(true);
|
|
67
|
+
expect(children).toHaveLength(3);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should serialize empty grid layout', () => {
|
|
71
|
+
const originalComponent = (
|
|
72
|
+
<GridLayout columns={2} />
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const serialized = ComponentTransformer.serialize(originalComponent);
|
|
76
|
+
const parsed = JSON.parse(serialized);
|
|
77
|
+
|
|
78
|
+
expect(parsed.tag).toBe('GridLayout');
|
|
79
|
+
expect(parsed.data.columns).toBe(2);
|
|
80
|
+
expect(parsed.data.children).toBeUndefined();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should serialize grid layout with dimension props', () => {
|
|
84
|
+
const originalComponent = (
|
|
85
|
+
<GridLayout
|
|
86
|
+
columns={2}
|
|
87
|
+
height="400px"
|
|
88
|
+
width="100%"
|
|
89
|
+
maxWidth="800px"
|
|
90
|
+
className="custom-grid"
|
|
91
|
+
>
|
|
92
|
+
<div>Content</div>
|
|
93
|
+
</GridLayout>
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const serialized = ComponentTransformer.serialize(originalComponent);
|
|
97
|
+
const parsed = JSON.parse(serialized);
|
|
98
|
+
|
|
99
|
+
expect(parsed.data.height).toBe('400px');
|
|
100
|
+
expect(parsed.data.width).toBe('100%');
|
|
101
|
+
expect(parsed.data.maxWidth).toBe('800px');
|
|
102
|
+
expect(parsed.data.className).toBe('custom-grid');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('Nested Component Serialization', () => {
|
|
107
|
+
it('should serialize grid with nested GridCell components', () => {
|
|
108
|
+
const originalComponent = (
|
|
109
|
+
<GridLayout columns={2} spacing="large">
|
|
110
|
+
<GridCell span={6}>
|
|
111
|
+
<Text content="First Cell" variant="h3" />
|
|
112
|
+
</GridCell>
|
|
113
|
+
<GridCell span={6}>
|
|
114
|
+
<Text content="Second Cell" variant="body1" />
|
|
115
|
+
</GridCell>
|
|
116
|
+
</GridLayout>
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const serialized = ComponentTransformer.serialize(originalComponent);
|
|
120
|
+
const parsed = JSON.parse(serialized);
|
|
121
|
+
|
|
122
|
+
expect(parsed.tag).toBe('GridLayout');
|
|
123
|
+
|
|
124
|
+
// Children should be serialized as JSON string
|
|
125
|
+
expect(typeof parsed.data.children).toBe('string');
|
|
126
|
+
const children = JSON.parse(parsed.data.children);
|
|
127
|
+
expect(Array.isArray(children)).toBe(true);
|
|
128
|
+
expect(children).toHaveLength(2);
|
|
129
|
+
|
|
130
|
+
// Check that nested GridCell components are serialized
|
|
131
|
+
const firstChild = children[0];
|
|
132
|
+
expect(typeof firstChild).toBe('object');
|
|
133
|
+
expect(firstChild.tag).toBe('GridCell');
|
|
134
|
+
expect(firstChild.data.span).toBe(6);
|
|
135
|
+
|
|
136
|
+
// Check that Text components inside GridCell are serialized
|
|
137
|
+
expect(typeof firstChild.data.children).toBe('string');
|
|
138
|
+
const nestedText = JSON.parse(firstChild.data.children);
|
|
139
|
+
expect(nestedText.tag).toBe('Text');
|
|
140
|
+
expect(nestedText.data.content).toBe('First Cell');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should serialize grid with mixed nested components', () => {
|
|
144
|
+
const originalComponent = (
|
|
145
|
+
<GridLayout columns={3} spacing="medium">
|
|
146
|
+
<GridCell xs={12} sm={4}>
|
|
147
|
+
<Text content="Column 1" variant="h4" />
|
|
148
|
+
</GridCell>
|
|
149
|
+
<div>Regular div content</div>
|
|
150
|
+
<GridCell xs={12} sm={8}>
|
|
151
|
+
<Button label="Action Button" variant="primary" />
|
|
152
|
+
</GridCell>
|
|
153
|
+
</GridLayout>
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
const serialized = ComponentTransformer.serialize(originalComponent);
|
|
157
|
+
const parsed = JSON.parse(serialized);
|
|
158
|
+
|
|
159
|
+
// Children should be serialized as JSON string
|
|
160
|
+
expect(typeof parsed.data.children).toBe('string');
|
|
161
|
+
const children = JSON.parse(parsed.data.children);
|
|
162
|
+
expect(Array.isArray(children)).toBe(true);
|
|
163
|
+
expect(children).toHaveLength(3);
|
|
164
|
+
|
|
165
|
+
// First child is GridCell with Text
|
|
166
|
+
expect(children[0].tag).toBe('GridCell');
|
|
167
|
+
expect(children[0].data.xs).toBe(12);
|
|
168
|
+
expect(children[0].data.sm).toBe(4);
|
|
169
|
+
|
|
170
|
+
// Second child is regular div (serialized as react node)
|
|
171
|
+
expect(typeof children[1]).toBe('object');
|
|
172
|
+
expect(children[1].tag).toBe('__react_node__');
|
|
173
|
+
|
|
174
|
+
// Third child is GridCell with Button
|
|
175
|
+
expect(children[2].tag).toBe('GridCell');
|
|
176
|
+
const buttonChild = JSON.parse(children[2].data.children);
|
|
177
|
+
expect(buttonChild.tag).toBe('Button');
|
|
178
|
+
expect(buttonChild.data.label).toBe('Action Button');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe('Deserialization', () => {
|
|
183
|
+
it('should deserialize back to working component', () => {
|
|
184
|
+
const originalComponent = (
|
|
185
|
+
<GridLayout columns={2} spacing="small" equalHeight={true}>
|
|
186
|
+
<GridCell span={8}>
|
|
187
|
+
<Text content="Main Content" />
|
|
188
|
+
</GridCell>
|
|
189
|
+
<GridCell span={4}>
|
|
190
|
+
<Text content="Sidebar" />
|
|
191
|
+
</GridCell>
|
|
192
|
+
</GridLayout>
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
// Serialize and deserialize
|
|
196
|
+
const serialized = ComponentTransformer.serialize(originalComponent);
|
|
197
|
+
const deserialized = ComponentTransformer.deserialize(serialized);
|
|
198
|
+
|
|
199
|
+
// Render both to compare
|
|
200
|
+
const { container: originalContainer } = render(originalComponent);
|
|
201
|
+
const { container: deserializedContainer } = render(deserialized);
|
|
202
|
+
|
|
203
|
+
// Check that both render successfully
|
|
204
|
+
expect(originalContainer.firstChild).toBeTruthy();
|
|
205
|
+
expect(deserializedContainer.firstChild).toBeTruthy();
|
|
206
|
+
|
|
207
|
+
// Both should have grid container classes
|
|
208
|
+
const originalGrid = originalContainer.querySelector('.MuiGrid-container');
|
|
209
|
+
const deserializedGrid = deserializedContainer.querySelector('.MuiGrid-container');
|
|
210
|
+
expect(originalGrid).toBeTruthy();
|
|
211
|
+
expect(deserializedGrid).toBeTruthy();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should preserve all layout properties after round-trip serialization', () => {
|
|
215
|
+
const originalComponent = (
|
|
216
|
+
<GridLayout
|
|
217
|
+
columns={4}
|
|
218
|
+
spacing="huge"
|
|
219
|
+
equalHeight={false}
|
|
220
|
+
height="300px"
|
|
221
|
+
minHeight="200px"
|
|
222
|
+
maxWidth="1200px"
|
|
223
|
+
className="test-grid"
|
|
224
|
+
>
|
|
225
|
+
<div>Test content</div>
|
|
226
|
+
</GridLayout>
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
// Double serialization to test round-trip
|
|
230
|
+
const serialized1 = ComponentTransformer.serialize(originalComponent);
|
|
231
|
+
const deserialized1 = ComponentTransformer.deserialize(serialized1);
|
|
232
|
+
const serialized2 = ComponentTransformer.serialize(deserialized1);
|
|
233
|
+
const parsed2 = JSON.parse(serialized2);
|
|
234
|
+
|
|
235
|
+
// Properties should be preserved
|
|
236
|
+
expect(parsed2.data.columns).toBe(4);
|
|
237
|
+
expect(parsed2.data.spacing).toBe('huge');
|
|
238
|
+
expect(parsed2.data.equalHeight).toBe(false);
|
|
239
|
+
expect(parsed2.data.height).toBe('300px');
|
|
240
|
+
expect(parsed2.data.minHeight).toBe('200px');
|
|
241
|
+
expect(parsed2.data.maxWidth).toBe('1200px');
|
|
242
|
+
expect(parsed2.data.className).toBe('test-grid');
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('Performance', () => {
|
|
247
|
+
it('should serialize large grid efficiently', () => {
|
|
248
|
+
const gridItems = Array.from({ length: 50 }, (_, i) => (
|
|
249
|
+
<GridCell key={i} xs={12} sm={6} md={4} lg={3}>
|
|
250
|
+
<Text content={`Item ${i + 1}`} />
|
|
251
|
+
</GridCell>
|
|
252
|
+
));
|
|
253
|
+
|
|
254
|
+
const largeGrid = (
|
|
255
|
+
<GridLayout columns={4} spacing="medium">
|
|
256
|
+
{gridItems}
|
|
257
|
+
</GridLayout>
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const startTime = performance.now();
|
|
261
|
+
const serialized = ComponentTransformer.serialize(largeGrid);
|
|
262
|
+
const endTime = performance.now();
|
|
263
|
+
|
|
264
|
+
expect(serialized).toBeTruthy();
|
|
265
|
+
expect(endTime - startTime).toBeLessThan(100); // Should complete within 100ms
|
|
266
|
+
|
|
267
|
+
const parsed = JSON.parse(serialized);
|
|
268
|
+
const children = JSON.parse(parsed.data.children);
|
|
269
|
+
expect(children).toHaveLength(50);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
describe('Error Handling', () => {
|
|
274
|
+
it('should handle grid with invalid children gracefully', () => {
|
|
275
|
+
const gridWithNullChild = (
|
|
276
|
+
<GridLayout columns={2}>
|
|
277
|
+
<div>Valid content</div>
|
|
278
|
+
{null}
|
|
279
|
+
<div>More valid content</div>
|
|
280
|
+
</GridLayout>
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
expect(() => {
|
|
284
|
+
const serialized = ComponentTransformer.serialize(gridWithNullChild);
|
|
285
|
+
const parsed = JSON.parse(serialized);
|
|
286
|
+
const children = JSON.parse(parsed.data.children);
|
|
287
|
+
expect(children).toHaveLength(3); // null becomes a child
|
|
288
|
+
}).not.toThrow();
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('should handle grid with complex nested structures', () => {
|
|
292
|
+
const complexGrid = (
|
|
293
|
+
<GridLayout columns={1}>
|
|
294
|
+
<GridCell>
|
|
295
|
+
<div>
|
|
296
|
+
<span>Complex</span>
|
|
297
|
+
<strong>Nested</strong>
|
|
298
|
+
<em>Structure</em>
|
|
299
|
+
</div>
|
|
300
|
+
</GridCell>
|
|
301
|
+
</GridLayout>
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
expect(() => {
|
|
305
|
+
const serialized = ComponentTransformer.serialize(complexGrid);
|
|
306
|
+
const deserialized = ComponentTransformer.deserialize(serialized);
|
|
307
|
+
render(deserialized);
|
|
308
|
+
}).not.toThrow();
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePrintMode Hook Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for print mode detection and management
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PrintConfigSchema } from '../../schemas/PrintConfigSchema';
|
|
8
|
+
|
|
9
|
+
// Mock QwickApp context
|
|
10
|
+
const mockUpdateConfig = jest.fn();
|
|
11
|
+
jest.mock('../../contexts/QwickAppContext', () => ({
|
|
12
|
+
useQwickApp: () => ({
|
|
13
|
+
updateConfig: mockUpdateConfig,
|
|
14
|
+
}),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
describe('PrintConfig Integration', () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
jest.clearAllMocks();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should merge print configurations correctly', () => {
|
|
23
|
+
const baseConfig = PrintConfigSchema.createWithDefaults();
|
|
24
|
+
const overrideConfig = {
|
|
25
|
+
theme: 'dark' as const,
|
|
26
|
+
printTitle: 'Custom Title'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const merged = { ...baseConfig, ...overrideConfig };
|
|
30
|
+
|
|
31
|
+
expect(merged.theme).toBe('dark');
|
|
32
|
+
expect(merged.palette).toBe('default'); // Should retain base value
|
|
33
|
+
expect(merged.hideScaffolding).toBe(true); // Should retain base value
|
|
34
|
+
expect(merged.printTitle).toBe('Custom Title');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should validate print config properties', async () => {
|
|
38
|
+
const config = {
|
|
39
|
+
theme: 'light' as const,
|
|
40
|
+
palette: 'cosmic',
|
|
41
|
+
hideScaffolding: true,
|
|
42
|
+
optimizeForMonochrome: false,
|
|
43
|
+
printTitle: 'Test Document'
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const result = await PrintConfigSchema.validate(config);
|
|
47
|
+
expect(result.isValid).toBe(true);
|
|
48
|
+
expect(result.errors).toHaveLength(0);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should create proper default print configuration', () => {
|
|
52
|
+
const config = PrintConfigSchema.createWithDefaults();
|
|
53
|
+
|
|
54
|
+
expect(config.theme).toBe('light');
|
|
55
|
+
expect(config.palette).toBe('default');
|
|
56
|
+
expect(config.hideScaffolding).toBe(true);
|
|
57
|
+
expect(config.hideInteractiveElements).toBe(false);
|
|
58
|
+
expect(config.optimizeForMonochrome).toBe(false);
|
|
59
|
+
expect(config.showPrintDate).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should support custom print configuration values', () => {
|
|
63
|
+
const customConfig = {
|
|
64
|
+
theme: 'dark' as const,
|
|
65
|
+
palette: 'ocean',
|
|
66
|
+
hideScaffolding: false,
|
|
67
|
+
optimizeForMonochrome: true,
|
|
68
|
+
printTitle: 'Custom Print Title',
|
|
69
|
+
printHeader: 'Custom Header',
|
|
70
|
+
printFooter: 'Custom Footer'
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const config = PrintConfigSchema.createWithDefaults(customConfig);
|
|
74
|
+
|
|
75
|
+
expect(config.theme).toBe('dark');
|
|
76
|
+
expect(config.palette).toBe('ocean');
|
|
77
|
+
expect(config.hideScaffolding).toBe(false);
|
|
78
|
+
expect(config.optimizeForMonochrome).toBe(true);
|
|
79
|
+
expect(config.printTitle).toBe('Custom Print Title');
|
|
80
|
+
expect(config.printHeader).toBe('Custom Header');
|
|
81
|
+
expect(config.printFooter).toBe('Custom Footer');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should export PrintModeState interface from usePrintMode', () => {
|
|
85
|
+
// This test ensures the types are properly exported
|
|
86
|
+
const { usePrintMode } = require('../../hooks/usePrintMode');
|
|
87
|
+
expect(typeof usePrintMode).toBe('function');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageTemplate Schema Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for PageTemplateSchema functionality and validation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PageTemplateSchema } from '../../schemas/PageTemplateSchema';
|
|
8
|
+
import { PrintConfigSchema } from '../../schemas/PrintConfigSchema';
|
|
9
|
+
|
|
10
|
+
describe('PageTemplateSchema', () => {
|
|
11
|
+
it('should create a valid PageTemplateSchema instance', () => {
|
|
12
|
+
const pageTemplate = new PageTemplateSchema();
|
|
13
|
+
expect(pageTemplate).toBeInstanceOf(PageTemplateSchema);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should have correct schema metadata', () => {
|
|
17
|
+
const schema = PageTemplateSchema.getSchema();
|
|
18
|
+
expect(schema.name).toBe('PageTemplate');
|
|
19
|
+
expect(schema.version).toBe('1.0.0');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should inherit from ViewModel properties', async () => {
|
|
23
|
+
const data = {
|
|
24
|
+
className: 'page-template',
|
|
25
|
+
id: 'test-page',
|
|
26
|
+
'aria-label': 'Test Page Template'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const result = await PageTemplateSchema.validate(data);
|
|
30
|
+
expect(result.isValid).toBe(true);
|
|
31
|
+
|
|
32
|
+
const pageTemplate = PageTemplateSchema.createWithDefaults(data);
|
|
33
|
+
expect(pageTemplate.className).toBe('page-template');
|
|
34
|
+
expect(pageTemplate.id).toBe('test-page');
|
|
35
|
+
expect(pageTemplate['aria-label']).toBe('Test Page Template');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should validate page-specific properties correctly', async () => {
|
|
39
|
+
const data = {
|
|
40
|
+
slug: 'about-us',
|
|
41
|
+
name: 'About Us',
|
|
42
|
+
description: 'Learn more about our company',
|
|
43
|
+
title: 'About Us | Company Name',
|
|
44
|
+
metaKeywords: 'about, company, information',
|
|
45
|
+
metaAuthor: 'Web Team',
|
|
46
|
+
canonicalUrl: 'https://example.com/about-us',
|
|
47
|
+
children: '<div>Page content here</div>',
|
|
48
|
+
layout: 'default',
|
|
49
|
+
icon: 'info',
|
|
50
|
+
requiresAuth: false,
|
|
51
|
+
requiredRoles: 'user',
|
|
52
|
+
showInNavigation: true,
|
|
53
|
+
navigationPriority: 1,
|
|
54
|
+
indexable: true
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const result = await PageTemplateSchema.validate(data);
|
|
58
|
+
expect(result.isValid).toBe(true);
|
|
59
|
+
expect(result.errors).toHaveLength(0);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should create instance with page data correctly', () => {
|
|
63
|
+
const data = {
|
|
64
|
+
slug: 'contact',
|
|
65
|
+
name: 'Contact Us',
|
|
66
|
+
description: 'Get in touch with us',
|
|
67
|
+
title: 'Contact | Company',
|
|
68
|
+
layout: 'fullwidth',
|
|
69
|
+
showInNavigation: true,
|
|
70
|
+
navigationPriority: 5
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const pageTemplate = PageTemplateSchema.createWithDefaults(data);
|
|
74
|
+
expect(pageTemplate.slug).toBe('contact');
|
|
75
|
+
expect(pageTemplate.name).toBe('Contact Us');
|
|
76
|
+
expect(pageTemplate.description).toBe('Get in touch with us');
|
|
77
|
+
expect(pageTemplate.title).toBe('Contact | Company');
|
|
78
|
+
expect(pageTemplate.layout).toBe('fullwidth');
|
|
79
|
+
expect(pageTemplate.showInNavigation).toBe(true);
|
|
80
|
+
expect(pageTemplate.navigationPriority).toBe(5);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should handle print configuration integration', () => {
|
|
84
|
+
const printConfig = PrintConfigSchema.createWithDefaults({
|
|
85
|
+
theme: 'dark',
|
|
86
|
+
palette: 'ocean',
|
|
87
|
+
hideScaffolding: false,
|
|
88
|
+
printTitle: 'Page Print Title'
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const pageData = {
|
|
92
|
+
name: 'Test Page',
|
|
93
|
+
slug: 'test-page',
|
|
94
|
+
printConfig: printConfig
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const pageTemplate = PageTemplateSchema.createWithDefaults(pageData);
|
|
98
|
+
expect(pageTemplate.name).toBe('Test Page');
|
|
99
|
+
expect(pageTemplate.slug).toBe('test-page');
|
|
100
|
+
expect(pageTemplate.printConfig).toBeDefined();
|
|
101
|
+
expect(pageTemplate.printConfig?.theme).toBe('dark');
|
|
102
|
+
expect(pageTemplate.printConfig?.palette).toBe('ocean');
|
|
103
|
+
expect(pageTemplate.printConfig?.hideScaffolding).toBe(false);
|
|
104
|
+
expect(pageTemplate.printConfig?.printTitle).toBe('Page Print Title');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should handle boolean default values correctly', () => {
|
|
108
|
+
const pageTemplate = PageTemplateSchema.createWithDefaults();
|
|
109
|
+
|
|
110
|
+
// These are the default values as specified in the schema
|
|
111
|
+
expect(pageTemplate.requiresAuth).toBe(false); // @Field({ defaultValue: false })
|
|
112
|
+
expect(pageTemplate.showInNavigation).toBe(true); // @Field({ defaultValue: true })
|
|
113
|
+
expect(pageTemplate.navigationPriority).toBe(0); // @Field({ defaultValue: 0 })
|
|
114
|
+
expect(pageTemplate.indexable).toBe(true); // @Field({ defaultValue: true })
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should support comprehensive page metadata', async () => {
|
|
118
|
+
const comprehensiveData = {
|
|
119
|
+
slug: 'comprehensive-page',
|
|
120
|
+
name: 'Comprehensive Test Page',
|
|
121
|
+
description: 'A page with all possible metadata',
|
|
122
|
+
title: 'Complete Page | Site',
|
|
123
|
+
metaKeywords: 'test, comprehensive, page, metadata',
|
|
124
|
+
metaAuthor: 'Test Author',
|
|
125
|
+
canonicalUrl: 'https://example.com/comprehensive',
|
|
126
|
+
children: '<h1>Welcome</h1><p>This is a comprehensive test page.</p>',
|
|
127
|
+
layout: 'sidebar',
|
|
128
|
+
icon: 'star',
|
|
129
|
+
requiresAuth: true,
|
|
130
|
+
requiredRoles: 'admin,moderator',
|
|
131
|
+
showInNavigation: false,
|
|
132
|
+
navigationPriority: 10,
|
|
133
|
+
indexable: false,
|
|
134
|
+
className: 'comprehensive-page',
|
|
135
|
+
id: 'comp-page',
|
|
136
|
+
hidden: false
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const result = await PageTemplateSchema.validate(comprehensiveData);
|
|
140
|
+
expect(result.isValid).toBe(true);
|
|
141
|
+
|
|
142
|
+
const pageTemplate = PageTemplateSchema.createWithDefaults(comprehensiveData);
|
|
143
|
+
expect(pageTemplate.slug).toBe('comprehensive-page');
|
|
144
|
+
expect(pageTemplate.name).toBe('Comprehensive Test Page');
|
|
145
|
+
expect(pageTemplate.description).toBe('A page with all possible metadata');
|
|
146
|
+
expect(pageTemplate.title).toBe('Complete Page | Site');
|
|
147
|
+
expect(pageTemplate.metaKeywords).toBe('test, comprehensive, page, metadata');
|
|
148
|
+
expect(pageTemplate.metaAuthor).toBe('Test Author');
|
|
149
|
+
expect(pageTemplate.canonicalUrl).toBe('https://example.com/comprehensive');
|
|
150
|
+
expect(pageTemplate.layout).toBe('sidebar');
|
|
151
|
+
expect(pageTemplate.icon).toBe('star');
|
|
152
|
+
expect(pageTemplate.requiresAuth).toBe(true);
|
|
153
|
+
expect(pageTemplate.requiredRoles).toBe('admin,moderator');
|
|
154
|
+
expect(pageTemplate.showInNavigation).toBe(false);
|
|
155
|
+
expect(pageTemplate.navigationPriority).toBe(10);
|
|
156
|
+
expect(pageTemplate.indexable).toBe(false);
|
|
157
|
+
expect(pageTemplate.className).toBe('comprehensive-page');
|
|
158
|
+
expect(pageTemplate.id).toBe('comp-page');
|
|
159
|
+
expect(pageTemplate.hidden).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrintConfig Schema Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for PrintConfigSchema functionality and validation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PrintConfigSchema } from '../../schemas/PrintConfigSchema';
|
|
8
|
+
|
|
9
|
+
describe('PrintConfigSchema', () => {
|
|
10
|
+
it('should create a valid PrintConfigSchema instance', () => {
|
|
11
|
+
const printConfig = new PrintConfigSchema();
|
|
12
|
+
expect(printConfig).toBeInstanceOf(PrintConfigSchema);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should have correct schema metadata', () => {
|
|
16
|
+
const schema = PrintConfigSchema.getSchema();
|
|
17
|
+
expect(schema.name).toBe('PrintConfig');
|
|
18
|
+
expect(schema.version).toBe('1.0.0');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should have proper default values', () => {
|
|
22
|
+
const printConfig = PrintConfigSchema.createWithDefaults();
|
|
23
|
+
expect(printConfig.theme).toBe('light');
|
|
24
|
+
expect(printConfig.palette).toBe('default');
|
|
25
|
+
expect(printConfig.hideScaffolding).toBe(true);
|
|
26
|
+
expect(printConfig.hideInteractiveElements).toBe(false);
|
|
27
|
+
expect(printConfig.optimizeForMonochrome).toBe(false);
|
|
28
|
+
expect(printConfig.showPrintDate).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should validate theme values correctly', async () => {
|
|
32
|
+
const lightData = { theme: 'light' as const };
|
|
33
|
+
const darkData = { theme: 'dark' as const };
|
|
34
|
+
|
|
35
|
+
const lightResult = await PrintConfigSchema.validate(lightData);
|
|
36
|
+
const darkResult = await PrintConfigSchema.validate(darkData);
|
|
37
|
+
|
|
38
|
+
expect(lightResult.isValid).toBe(true);
|
|
39
|
+
expect(darkResult.isValid).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should validate boolean properties correctly', async () => {
|
|
43
|
+
const data = {
|
|
44
|
+
hideScaffolding: false,
|
|
45
|
+
hideInteractiveElements: true,
|
|
46
|
+
optimizeForMonochrome: true,
|
|
47
|
+
showPrintDate: false
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const result = await PrintConfigSchema.validate(data);
|
|
51
|
+
expect(result.isValid).toBe(true);
|
|
52
|
+
|
|
53
|
+
const printConfig = PrintConfigSchema.createWithDefaults(data);
|
|
54
|
+
expect(printConfig.hideScaffolding).toBe(false);
|
|
55
|
+
expect(printConfig.hideInteractiveElements).toBe(true);
|
|
56
|
+
expect(printConfig.optimizeForMonochrome).toBe(true);
|
|
57
|
+
expect(printConfig.showPrintDate).toBe(false);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should handle optional string properties', async () => {
|
|
61
|
+
const data = {
|
|
62
|
+
printTitle: 'Custom Print Title',
|
|
63
|
+
printHeader: 'Custom Header',
|
|
64
|
+
printFooter: 'Custom Footer',
|
|
65
|
+
palette: 'ocean'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const result = await PrintConfigSchema.validate(data);
|
|
69
|
+
expect(result.isValid).toBe(true);
|
|
70
|
+
|
|
71
|
+
const printConfig = PrintConfigSchema.createWithDefaults(data);
|
|
72
|
+
expect(printConfig.printTitle).toBe('Custom Print Title');
|
|
73
|
+
expect(printConfig.printHeader).toBe('Custom Header');
|
|
74
|
+
expect(printConfig.printFooter).toBe('Custom Footer');
|
|
75
|
+
expect(printConfig.palette).toBe('ocean');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should create instance with data correctly', () => {
|
|
79
|
+
const data = {
|
|
80
|
+
theme: 'dark' as const,
|
|
81
|
+
palette: 'cosmic',
|
|
82
|
+
printTitle: 'Test Document',
|
|
83
|
+
hideScaffolding: false
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const printConfig = PrintConfigSchema.createWithDefaults(data);
|
|
87
|
+
expect(printConfig.theme).toBe('dark');
|
|
88
|
+
expect(printConfig.palette).toBe('cosmic');
|
|
89
|
+
expect(printConfig.printTitle).toBe('Test Document');
|
|
90
|
+
expect(printConfig.hideScaffolding).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should restore from JSON correctly', () => {
|
|
94
|
+
const jsonData = {
|
|
95
|
+
theme: 'dark' as const,
|
|
96
|
+
palette: 'winter',
|
|
97
|
+
hideScaffolding: false,
|
|
98
|
+
optimizeForMonochrome: true,
|
|
99
|
+
printTitle: 'Restored Document',
|
|
100
|
+
printHeader: 'Restored Header'
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const printConfig = PrintConfigSchema.createWithDefaults(jsonData);
|
|
104
|
+
expect(printConfig.theme).toBe('dark');
|
|
105
|
+
expect(printConfig.palette).toBe('winter');
|
|
106
|
+
expect(printConfig.hideScaffolding).toBe(false);
|
|
107
|
+
expect(printConfig.optimizeForMonochrome).toBe(true);
|
|
108
|
+
expect(printConfig.printTitle).toBe('Restored Document');
|
|
109
|
+
expect(printConfig.printHeader).toBe('Restored Header');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should merge configurations correctly', () => {
|
|
113
|
+
const baseConfig = new PrintConfigSchema();
|
|
114
|
+
baseConfig.theme = 'light';
|
|
115
|
+
baseConfig.palette = 'default';
|
|
116
|
+
|
|
117
|
+
const overrideData = {
|
|
118
|
+
theme: 'dark',
|
|
119
|
+
printTitle: 'Override Title'
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const merged = { ...baseConfig, ...overrideData };
|
|
123
|
+
expect(merged.theme).toBe('dark');
|
|
124
|
+
expect(merged.palette).toBe('default'); // Should retain base value
|
|
125
|
+
expect(merged.printTitle).toBe('Override Title');
|
|
126
|
+
});
|
|
127
|
+
});
|