Skip to content

Commit 632f528

Browse files
committed
test: added cloud-image-editor
1 parent 7a53fc1 commit 632f528

File tree

10 files changed

+1051
-241
lines changed

10 files changed

+1051
-241
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2+
import { defineComponents } from '../defineComponents';
3+
import { loadFileUploaderFrom, UC_WINDOW_KEY } from '../loadFileUploaderFrom';
4+
5+
vi.mock('../defineComponents', () => ({
6+
defineComponents: vi.fn(),
7+
}));
8+
9+
beforeEach(() => {
10+
vi.clearAllMocks();
11+
12+
delete (window as any)[UC_WINDOW_KEY];
13+
});
14+
15+
afterEach(() => {
16+
const scripts = document.querySelectorAll('script[src]');
17+
for (const script of scripts) {
18+
script.remove();
19+
}
20+
21+
delete (window as any)[UC_WINDOW_KEY];
22+
});
23+
24+
describe('loadFileUploaderFrom', async () => {
25+
const { default: testUrl } = await import('~/web/file-uploader.iife.min.js?url');
26+
27+
describe('UC_WINDOW_KEY', () => {
28+
it('should export UC_WINDOW_KEY as "UC"', () => {
29+
expect(UC_WINDOW_KEY).toBe('UC');
30+
});
31+
});
32+
33+
describe('when window.UC already exists', () => {
34+
it('should resolve with existing window.UC immediately', async () => {
35+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
36+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
37+
38+
const result = await loadFileUploaderFrom(testUrl);
39+
40+
expect(result).toBe(mockBlocks);
41+
});
42+
43+
it('should not create a new script element', async () => {
44+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
45+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
46+
const initialScriptCount = document.querySelectorAll('script').length;
47+
48+
await loadFileUploaderFrom(testUrl);
49+
50+
expect(document.querySelectorAll('script').length).toBe(initialScriptCount);
51+
});
52+
53+
it('should not call defineComponents even if register is true', async () => {
54+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
55+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
56+
57+
await loadFileUploaderFrom(testUrl, true);
58+
59+
expect(defineComponents).not.toHaveBeenCalled();
60+
});
61+
});
62+
63+
describe('when loading script', () => {
64+
it('should append script to document head', async () => {
65+
const loadPromise = loadFileUploaderFrom(testUrl);
66+
67+
const script = document.head.querySelector(`script[src="${testUrl}"]`);
68+
expect(script).not.toBeNull();
69+
70+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
71+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
72+
(script as HTMLScriptElement).onload?.(new Event('load'));
73+
74+
await loadPromise;
75+
});
76+
77+
it('should resolve with window.UC on successful load', async () => {
78+
const loadPromise = loadFileUploaderFrom(testUrl);
79+
const mockBlocks = { TestBlock: { reg: vi.fn() }, AnotherBlock: { reg: vi.fn() } };
80+
81+
const script = document.querySelector(`script[src="${testUrl}"]`) as HTMLScriptElement;
82+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
83+
script.onload?.(new Event('load'));
84+
85+
const result = await loadPromise;
86+
expect(result).toBe(mockBlocks);
87+
});
88+
89+
it('should call defineComponents when register is true', async () => {
90+
const loadPromise = loadFileUploaderFrom(testUrl, true);
91+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
92+
93+
const script = document.querySelector(`script[src="${testUrl}"]`) as HTMLScriptElement;
94+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
95+
script.onload?.(new Event('load'));
96+
97+
await loadPromise;
98+
expect(defineComponents).toHaveBeenCalledWith(mockBlocks);
99+
});
100+
101+
it('should not call defineComponents when register is false', async () => {
102+
const loadPromise = loadFileUploaderFrom(testUrl, false);
103+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
104+
105+
const script = document.querySelector(`script[src="${testUrl}"]`) as HTMLScriptElement;
106+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
107+
script.onload?.(new Event('load'));
108+
109+
await loadPromise;
110+
expect(defineComponents).not.toHaveBeenCalled();
111+
});
112+
113+
it('should not call defineComponents by default', async () => {
114+
const loadPromise = loadFileUploaderFrom(testUrl);
115+
const mockBlocks = { TestBlock: { reg: vi.fn() } };
116+
117+
const script = document.querySelector(`script[src="${testUrl}"]`) as HTMLScriptElement;
118+
(window as any)[UC_WINDOW_KEY] = mockBlocks;
119+
script.onload?.(new Event('load'));
120+
121+
await loadPromise;
122+
expect(defineComponents).not.toHaveBeenCalled();
123+
});
124+
125+
it('should reject on script error', async () => {
126+
const loadPromise = loadFileUploaderFrom(testUrl);
127+
128+
const script = document.querySelector(`script[src="${testUrl}"]`) as HTMLScriptElement;
129+
script.onerror?.(new Event('error'));
130+
131+
await expect(loadPromise).rejects.toBeUndefined();
132+
});
133+
});
134+
135+
describe('non-browser environment', () => {
136+
it('should resolve with null when document is not an object', async () => {
137+
const originalDocument = global.document;
138+
139+
// @ts-expect-error - intentionally setting to non-object for test
140+
global.document = undefined;
141+
142+
const result = await loadFileUploaderFrom(testUrl);
143+
144+
expect(result).toBeNull();
145+
146+
global.document = originalDocument;
147+
});
148+
});
149+
});

src/blocks/CameraSource/CameraSource.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,7 @@ CameraSource.template = /* HTML */ `
10281028
type="button"
10291029
class="uc-switch uc-mini-btn"
10301030
set="onclick: onClickTab; @hidden: tabCameraHidden"
1031+
data-testid="tab-photo"
10311032
>
10321033
<uc-icon name="camera"></uc-icon>
10331034
</button>
@@ -1036,6 +1037,7 @@ CameraSource.template = /* HTML */ `
10361037
type="button"
10371038
class="uc-switch uc-mini-btn"
10381039
set="onclick: onClickTab; @hidden: tabVideoHidden"
1040+
data-testid="tab-video"
10391041
>
10401042
<uc-icon name="video-camera"></uc-icon>
10411043
</button>
@@ -1044,6 +1046,7 @@ CameraSource.template = /* HTML */ `
10441046
<button
10451047
class="uc-secondary-btn uc-recording-timer"
10461048
set="@hidden:timerHidden; onclick: onToggleRecording"
1049+
data-testid="recording-timer"
10471050
>
10481051
<uc-icon set="@name: currentTimelineIcon"></uc-icon>
10491052
<span ref="timer"> 00:00 </span>
@@ -1054,7 +1057,7 @@ CameraSource.template = /* HTML */ `
10541057
class="uc-camera-actions uc-camera-action"
10551058
set="@hidden: cameraActionsHidden"
10561059
>
1057-
<button type="button" class="uc-secondary-btn" set="onclick: onRetake">
1060+
<button type="button" class="uc-secondary-btn" set="onclick: onRetake" data-testid="retake">
10581061
Retake
10591062
</button>
10601063
<button
@@ -1080,13 +1083,15 @@ CameraSource.template = /* HTML */ `
10801083
<button
10811084
class="uc-mini-btn uc-btn-microphone"
10821085
set="onclick: onToggleAudio; @hidden: audioToggleMicrophoneHidden;"
1086+
data-testid="toggle-microphone"
10831087
>
10841088
<uc-icon set="@name:toggleMicrophoneIcon"></uc-icon>
10851089
</button>
10861090
10871091
<uc-select
10881092
class="uc-audio-select"
10891093
set="$.options: audioSelectOptions; onchange: onAudioSelectChange; @hidden: audioSelectHidden; @disabled: audioSelectDisabled"
1094+
data-testid="audio-select"
10901095
>
10911096
</uc-select>
10921097
</div>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { describe, expect, it } from 'vitest';
2+
import type { ConfigType } from '../../../types/index';
3+
import { initialConfig } from '../../Config/initialConfig';
4+
import { calcCameraModes } from '../calcCameraModes';
5+
6+
describe('calcCameraModes', () => {
7+
it('should return both modes enabled when cameraModes includes video and photo', () => {
8+
const cfg = { ...initialConfig } as ConfigType;
9+
const result = calcCameraModes(cfg);
10+
expect(result).toEqual({
11+
isVideoRecordingEnabled: true,
12+
isPhotoEnabled: true,
13+
});
14+
});
15+
16+
it('should return only video enabled when cameraModes includes only video', () => {
17+
const cfg = { ...initialConfig, cameraModes: 'video' } as ConfigType;
18+
const result = calcCameraModes(cfg);
19+
expect(result).toEqual({
20+
isVideoRecordingEnabled: true,
21+
isPhotoEnabled: false,
22+
});
23+
});
24+
25+
it('should return only photo enabled when cameraModes includes only photo', () => {
26+
const cfg = { ...initialConfig, cameraModes: 'photo' } as ConfigType;
27+
const result = calcCameraModes(cfg);
28+
expect(result).toEqual({
29+
isVideoRecordingEnabled: false,
30+
isPhotoEnabled: true,
31+
});
32+
});
33+
34+
it('should return both modes disabled when cameraModes is empty', () => {
35+
const cfg = { ...initialConfig, cameraModes: '' } as ConfigType;
36+
const result = calcCameraModes(cfg);
37+
expect(result).toEqual({
38+
isVideoRecordingEnabled: false,
39+
isPhotoEnabled: false,
40+
});
41+
});
42+
43+
it('should handle mixed valid and invalid values', () => {
44+
const cfg = { cameraModes: 'video,unknown,photo' } as ConfigType;
45+
const result = calcCameraModes(cfg);
46+
expect(result).toEqual({
47+
isVideoRecordingEnabled: true,
48+
isPhotoEnabled: true,
49+
});
50+
});
51+
});

src/blocks/CloudImageEditor/src/EditorToolbar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,8 @@ EditorToolbar.template = /* HTML */ `
501501
<div class="uc-list-aspect-ratio" ref="list-el"></div>
502502
</div>
503503
<div class="uc-controls-row">
504-
<uc-btn-ui theme="secondary" set="onclick: on.cancelSlider" l10n="@text:cancel"> </uc-btn-ui>
505-
<uc-btn-ui theme="primary" set="onclick: on.applySlider" l10n="@text:apply"> </uc-btn-ui>
504+
<uc-btn-ui theme="secondary" set="onclick: on.cancelSlider; title-prop:cancel" l10n="@text:cancel"> </uc-btn-ui>
505+
<uc-btn-ui theme="primary" set="onclick: on.applySlider; title-prop:apply" l10n="@text:apply"> </uc-btn-ui>
506506
</div>
507507
</uc-presence-toggle>
508508
</div>

0 commit comments

Comments
 (0)