Skip to content

Commit 2a7e562

Browse files
authored
Merge pull request #438 from contentstack/VE-6414-fix-contentstack-live-preview-sd-ks-config-type
fix: update LightLivePreviewHoC config to use IExportedConfig type
2 parents 166ddc5 + 45c8c99 commit 2a7e562

5 files changed

Lines changed: 251 additions & 67 deletions

File tree

.talismanrc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@ fileignoreconfig:
33
ignore_detectors:
44
- filecontent
55
- filename: README.md
6-
checksum: f9e1aee750713c9c4aea3c1027686a1aefcebd759de0ffd06dbea6fdf9f576e6
6+
checksum: 568289bbe7c088967493db246dbf29e465382648ac574c1b1236be57d5662a38
7+
- filename: CHANGELOG.md
8+
checksum: 677807c38f5135fac7ca0377e92953fb09097150ddd3c4f68667fe0368f916ee
9+
- filename: src/visualBuilder/components/__test__/fieldToolbar.test.tsx
10+
checksum: 3badd6a142456b6a361569e6fc546349a38ac6b366bef7fd5255d1e93220444e
711
version: "1.0"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ npm install @contentstack/live-preview-utils
1515
Alternatively, if you want to include the package directly in your website HTML code, use the following command:
1616

1717
```html
18-
<script type='module' integrity='sha384-SHUnMbbEHjE8k0KW44O7mqfIkMq3FXetFL0TBcsLnyje7aLZch0lhjcp2HxvHC8B' crossorigin="anonymous">
18+
<script type='module' integrity='sha384-b6G+ggU20rGxqCqsgaS6zludFgj5N11xsuXhMEIARMuQY2PtyDS04TU0H5goP+32' crossorigin="anonymous">
1919
import ContentstackLivePreview from 'https://esm.sh/@contentstack/live-preview-utils@3.2.2';
2020
2121
ContentstackLivePreview.init({
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import { vi } from 'vitest';
2+
import type { OnEntryChangeCallback, OnEntryChangeConfig } from '../livePreview/types/onEntryChangeCallback.type';
3+
import type { IStackSdk, IExportedConfig, IInitData } from '../types/types';
4+
5+
// Store original env and window
6+
const originalEnv = process.env;
7+
const originalWindow = global.window;
8+
9+
describe('ContentstackLivePreview HOC Class Integration Tests', () => {
10+
let ContentstackLivePreview: any;
11+
let ContentstackLivePreviewHOC: any;
12+
13+
beforeEach(() => {
14+
// Reset modules and env before each test
15+
vi.resetModules();
16+
process.env = { ...originalEnv };
17+
});
18+
19+
afterEach(() => {
20+
process.env = originalEnv;
21+
vi.clearAllMocks();
22+
23+
// Restore window to original state
24+
Object.defineProperty(global, 'window', {
25+
value: originalWindow,
26+
writable: true,
27+
configurable: true
28+
});
29+
});
30+
31+
describe('SDK Selection Tests', () => {
32+
test('should use LightLivePreviewHoC when PURGE_PREVIEW_SDK is true', async () => {
33+
process.env.PURGE_PREVIEW_SDK = 'true';
34+
35+
const { default: CSLivePreview } = await import('../index');
36+
const { default: CSLivePreviewHOC } = await import('../preview/contentstack-live-preview-HOC');
37+
38+
ContentstackLivePreview = CSLivePreview;
39+
ContentstackLivePreviewHOC = CSLivePreviewHOC;
40+
41+
expect(ContentstackLivePreview.name).toBe('LightLivePreviewHoC');
42+
});
43+
44+
test('should use LightLivePreviewHoC when REACT_APP_PURGE_PREVIEW_SDK is true', async () => {
45+
process.env.REACT_APP_PURGE_PREVIEW_SDK = 'true';
46+
47+
const { default: CSLivePreview } = await import('../index');
48+
ContentstackLivePreview = CSLivePreview;
49+
50+
expect(ContentstackLivePreview.name).toBe('LightLivePreviewHoC');
51+
});
52+
53+
test('should use ContentstackLivePreviewHOC by default', async () => {
54+
process.env.PURGE_PREVIEW_SDK = 'false';
55+
process.env.REACT_APP_PURGE_PREVIEW_SDK = 'false';
56+
57+
const { default: CSLivePreview } = await import('../index');
58+
const { default: CSLivePreviewHOC } = await import('../preview/contentstack-live-preview-HOC');
59+
60+
ContentstackLivePreview = CSLivePreview;
61+
ContentstackLivePreviewHOC = CSLivePreviewHOC;
62+
63+
expect(ContentstackLivePreview).toBe(ContentstackLivePreviewHOC);
64+
});
65+
});
66+
67+
describe('LightLivePreviewHoC Functionality Tests', () => {
68+
beforeEach(async () => {
69+
process.env.PURGE_PREVIEW_SDK = 'true';
70+
const { default: CSLivePreview } = await import('../index');
71+
ContentstackLivePreview = CSLivePreview;
72+
});
73+
74+
test('should initialize with empty constructors', async () => {
75+
const result = await ContentstackLivePreview.init();
76+
expect(result).toEqual({
77+
livePreview: {},
78+
visualBuilder: {},
79+
});
80+
});
81+
82+
test('should return empty hash', () => {
83+
expect(ContentstackLivePreview.hash).toBe('');
84+
});
85+
86+
test('should return empty config', () => {
87+
const config = ContentstackLivePreview.config as IExportedConfig;
88+
expect(config).toEqual({});
89+
});
90+
91+
test('should allow access to stackDetails from config without type error', () => {
92+
expect(ContentstackLivePreview.config.stackDetails).toEqual(undefined);
93+
});
94+
95+
test('should handle onEntryChange with immediate callback execution', () => {
96+
const mockCallback = vi.fn() as OnEntryChangeCallback;
97+
const config: OnEntryChangeConfig = { skipInitialRender: false };
98+
99+
const callbackId = ContentstackLivePreview.onEntryChange(mockCallback, config);
100+
101+
expect(callbackId).toBe('live-preview-id');
102+
expect(mockCallback).toHaveBeenCalledTimes(1);
103+
});
104+
105+
test('should handle onEntryChange with skipped initial render', () => {
106+
const mockCallback = vi.fn() as OnEntryChangeCallback;
107+
const config: OnEntryChangeConfig = { skipInitialRender: true };
108+
109+
const callbackId = ContentstackLivePreview.onEntryChange(mockCallback, config);
110+
111+
expect(callbackId).toBe('live-preview-id');
112+
expect(mockCallback).not.toHaveBeenCalled();
113+
});
114+
115+
test('should handle onLiveEdit', () => {
116+
const mockCallback = vi.fn() as OnEntryChangeCallback;
117+
const result = ContentstackLivePreview.onLiveEdit(mockCallback);
118+
expect(result).toBe('live-preview-id');
119+
});
120+
121+
test('should handle unsubscribeOnEntryChange without errors', () => {
122+
const mockCallback = vi.fn() as OnEntryChangeCallback;
123+
const callbackId = ContentstackLivePreview.onEntryChange(mockCallback);
124+
expect(() => {
125+
ContentstackLivePreview.unsubscribeOnEntryChange(callbackId);
126+
}).not.toThrow();
127+
});
128+
129+
test('should return package version from environment', () => {
130+
process.env.PACKAGE_VERSION = '1.0.0';
131+
expect(ContentstackLivePreview.getSdkVersion()).toBe('1.0.0');
132+
});
133+
});
134+
135+
describe('Browser Environment Tests', () => {
136+
beforeEach(async () => {
137+
process.env.PURGE_PREVIEW_SDK = 'true';
138+
vi.resetModules();
139+
const { default: CSLivePreview } = await import('../index');
140+
ContentstackLivePreview = CSLivePreview;
141+
});
142+
143+
test('should handle initialization in non-browser environment', async () => {
144+
// Mock window as undefined
145+
Object.defineProperty(global, 'window', {
146+
value: undefined,
147+
writable: true,
148+
configurable: true
149+
});
150+
151+
const result = await ContentstackLivePreview.init();
152+
153+
expect(result).toEqual({});
154+
});
155+
156+
test('should initialize properly in browser environment', async () => {
157+
// Mock window with minimum required properties
158+
Object.defineProperty(global, 'window', {
159+
value: {
160+
location: {
161+
search: '',
162+
hash: ''
163+
}
164+
},
165+
writable: true,
166+
configurable: true
167+
});
168+
169+
const result = await ContentstackLivePreview.init();
170+
171+
expect(result).toEqual({
172+
livePreview: {},
173+
visualBuilder: {},
174+
});
175+
});
176+
});
177+
});

src/index.ts

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,10 @@
11
import ContentstackLivePreviewHOC from "./preview/contentstack-live-preview-HOC";
22
import { IStackSdk as ExternalStackSdkType } from "./types/types";
33

4-
import {
5-
OnEntryChangeCallback,
6-
OnEntryChangeCallbackUID,
7-
OnEntryChangeConfig,
8-
} from "./livePreview/types/onEntryChangeCallback.type";
4+
import LightLivePreviewHoC from "./light-sdk";
95

106
export type IStackSdk = ExternalStackSdkType;
117

12-
class LightLivePreviewHoC {
13-
private static previewConstructors = {};
14-
private static onEntryChangeCallbacks = {};
15-
16-
static init() {
17-
if (typeof window === "undefined") {
18-
return Promise.resolve(LightLivePreviewHoC.previewConstructors);
19-
}
20-
21-
return LightLivePreviewHoC.initializePreview();
22-
}
23-
24-
private static initializePreview() {
25-
LightLivePreviewHoC.previewConstructors = {
26-
livePreview: {},
27-
visualBuilder: {},
28-
};
29-
30-
LightLivePreviewHoC.onEntryChangeCallbacks = {};
31-
32-
return Promise.resolve(LightLivePreviewHoC.previewConstructors);
33-
}
34-
35-
static get hash() {
36-
return "";
37-
}
38-
39-
static get config() {
40-
return {};
41-
}
42-
43-
static isInitialized() {
44-
return false;
45-
}
46-
47-
static onEntryChange(
48-
callback: OnEntryChangeCallback,
49-
config: OnEntryChangeConfig = {}
50-
): OnEntryChangeCallbackUID {
51-
const { skipInitialRender = false } = config;
52-
53-
if (!skipInitialRender) {
54-
callback();
55-
}
56-
57-
return "live-preview-id";
58-
}
59-
60-
static onLiveEdit(callback: OnEntryChangeCallback) {
61-
return "live-preview-id";
62-
}
63-
64-
static unsubscribeOnEntryChange() {
65-
// intentionally empty
66-
}
67-
68-
static getSdkVersion(): string {
69-
return process?.env?.PACKAGE_VERSION!;
70-
}
71-
}
728

739
const ContentstackLivePreview =
7410
typeof process !== "undefined" &&

src/light-sdk.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { OnEntryChangeCallbackUID, OnEntryChangeConfig } from "./livePreview/types/onEntryChangeCallback.type";
2+
3+
import { OnEntryChangeCallback } from "./livePreview/types/onEntryChangeCallback.type";
4+
import { IExportedConfig } from "./types/types";
5+
6+
class LightLivePreviewHoC {
7+
private static previewConstructors = {};
8+
private static onEntryChangeCallbacks = {};
9+
10+
static init() {
11+
if (typeof window === "undefined") {
12+
return Promise.resolve(LightLivePreviewHoC.previewConstructors);
13+
}
14+
15+
return LightLivePreviewHoC.initializePreview();
16+
}
17+
18+
private static initializePreview() {
19+
LightLivePreviewHoC.previewConstructors = {
20+
livePreview: {},
21+
visualBuilder: {},
22+
};
23+
24+
LightLivePreviewHoC.onEntryChangeCallbacks = {};
25+
26+
return Promise.resolve(LightLivePreviewHoC.previewConstructors);
27+
}
28+
29+
static get hash() {
30+
return "";
31+
}
32+
33+
static get config() {
34+
return {} as IExportedConfig;
35+
}
36+
37+
static isInitialized() {
38+
return false;
39+
}
40+
41+
static onEntryChange(
42+
callback: OnEntryChangeCallback,
43+
config: OnEntryChangeConfig = {}
44+
): OnEntryChangeCallbackUID {
45+
const { skipInitialRender = false } = config;
46+
47+
if (!skipInitialRender) {
48+
callback();
49+
}
50+
51+
return "live-preview-id";
52+
}
53+
54+
static onLiveEdit(callback: OnEntryChangeCallback) {
55+
return "live-preview-id";
56+
}
57+
58+
static unsubscribeOnEntryChange() {
59+
// intentionally empty
60+
}
61+
62+
static getSdkVersion(): string {
63+
return process?.env?.PACKAGE_VERSION!;
64+
}
65+
}
66+
67+
export default LightLivePreviewHoC;

0 commit comments

Comments
 (0)