@servicetitan/dte-unlayer 0.155.0 → 0.157.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/dist/editor-core-source.d.ts +1 -1
- package/dist/editor-core-source.d.ts.map +1 -1
- package/dist/editor-core-source.js +1 -1
- package/dist/editor-core-source.js.map +1 -1
- package/dist/image-upload-error.d.ts +5 -0
- package/dist/image-upload-error.d.ts.map +1 -0
- package/dist/image-upload-error.js +8 -0
- package/dist/image-upload-error.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/shared/fonts.js +1 -1
- package/dist/shared/fonts.js.map +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +6 -8
- package/dist/store.js.map +1 -1
- package/dist/tools.js +1 -1
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/store.image-upload.test.ts +132 -0
- package/src/editor-core-source.ts +1 -1
- package/src/image-upload-error.ts +7 -0
- package/src/index.ts +1 -0
- package/src/shared/fonts.ts +1 -1
- package/src/store.ts +8 -4
- package/src/tools.ts +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { ImageUploadError } from '../image-upload-error';
|
|
2
|
+
import { UnlayerStore } from '../store';
|
|
3
|
+
|
|
4
|
+
const editorMock = {
|
|
5
|
+
addEventListener: jest.fn(),
|
|
6
|
+
removeEventListener: jest.fn(),
|
|
7
|
+
registerCallback: jest.fn(),
|
|
8
|
+
unregisterCallback: jest.fn(),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
jest.mock('../loadScript', () => ({ loadScript: jest.fn().mockResolvedValue(undefined) }));
|
|
12
|
+
jest.mock('../unlayer', () => ({
|
|
13
|
+
...jest.requireActual('../unlayer'),
|
|
14
|
+
createUnlayerEditor: jest.fn(() => editorMock),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
class LoadedImageMock {
|
|
18
|
+
width = 100;
|
|
19
|
+
height = 100;
|
|
20
|
+
onload?: () => void;
|
|
21
|
+
onerror?: () => void;
|
|
22
|
+
|
|
23
|
+
set src(_: string) {
|
|
24
|
+
setTimeout(() => this.onload?.());
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const GENERIC_DESCRIPTION =
|
|
29
|
+
'Something went wrong while uploading the image. Please try again or select another image.';
|
|
30
|
+
|
|
31
|
+
describe('UnlayerStore image upload', () => {
|
|
32
|
+
const originalImage = window.Image;
|
|
33
|
+
const originalCreateObjectURL = URL.createObjectURL;
|
|
34
|
+
const originalRevokeObjectURL = URL.revokeObjectURL;
|
|
35
|
+
|
|
36
|
+
let store: UnlayerStore;
|
|
37
|
+
let onError: jest.Mock;
|
|
38
|
+
let done: jest.Mock;
|
|
39
|
+
|
|
40
|
+
const uploadImage = () => {
|
|
41
|
+
const [, handler] = editorMock.registerCallback.mock.calls.find(
|
|
42
|
+
([name]) => name === 'image',
|
|
43
|
+
);
|
|
44
|
+
const file = new File(['img'], 'logo.png', { type: 'image/png' });
|
|
45
|
+
|
|
46
|
+
return handler({ attachments: [file] }, done);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
beforeEach(async () => {
|
|
50
|
+
jest.clearAllMocks();
|
|
51
|
+
jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
52
|
+
window.Image = LoadedImageMock as unknown as typeof Image;
|
|
53
|
+
URL.createObjectURL = jest.fn(() => 'blob:logo');
|
|
54
|
+
URL.revokeObjectURL = jest.fn();
|
|
55
|
+
(window as any).unlayer = {};
|
|
56
|
+
|
|
57
|
+
onError = jest.fn();
|
|
58
|
+
done = jest.fn();
|
|
59
|
+
store = new UnlayerStore({ tools: [] });
|
|
60
|
+
store.setOnError(onError);
|
|
61
|
+
|
|
62
|
+
const container = document.createElement('div');
|
|
63
|
+
container.appendChild(document.createElement('iframe'));
|
|
64
|
+
await store.init(container);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
store.destroy();
|
|
69
|
+
window.Image = originalImage;
|
|
70
|
+
URL.createObjectURL = originalCreateObjectURL;
|
|
71
|
+
URL.revokeObjectURL = originalRevokeObjectURL;
|
|
72
|
+
jest.restoreAllMocks();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('when the host resolves with a url', () => {
|
|
76
|
+
beforeEach(async () => {
|
|
77
|
+
store.setOnImage(jest.fn().mockResolvedValue({ url: 'https://cdn/logo.png' }));
|
|
78
|
+
await uploadImage();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('completes the upload with the url only', () => {
|
|
82
|
+
expect(done.mock.calls).toEqual([[{ progress: 100, url: 'https://cdn/logo.png' }]]);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('does not report an error', () => {
|
|
86
|
+
expect(onError).not.toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('when the host rejects with an ImageUploadError', () => {
|
|
91
|
+
beforeEach(async () => {
|
|
92
|
+
store.setOnImage(
|
|
93
|
+
jest
|
|
94
|
+
.fn()
|
|
95
|
+
.mockRejectedValue(
|
|
96
|
+
new ImageUploadError(
|
|
97
|
+
'Image dimensions 4320x2144 exceed maximum allowed 4000px',
|
|
98
|
+
),
|
|
99
|
+
),
|
|
100
|
+
);
|
|
101
|
+
await uploadImage();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('reports the host message', () => {
|
|
105
|
+
expect(onError).toHaveBeenCalledWith(
|
|
106
|
+
'Image upload failed',
|
|
107
|
+
'Image dimensions 4320x2144 exceed maximum allowed 4000px',
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('does not report upload progress', () => {
|
|
112
|
+
expect(done).not.toHaveBeenCalled();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('when the host rejects with any other error', () => {
|
|
117
|
+
beforeEach(async () => {
|
|
118
|
+
store.setOnImage(
|
|
119
|
+
jest.fn().mockRejectedValue(new Error('Request failed with status code 500')),
|
|
120
|
+
);
|
|
121
|
+
await uploadImage();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('reports the generic message', () => {
|
|
125
|
+
expect(onError).toHaveBeenCalledWith('Image upload failed', GENERIC_DESCRIPTION);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('does not report upload progress', () => {
|
|
129
|
+
expect(done).not.toHaveBeenCalled();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|