@ever-works/urlbox-plugin 1.0.0 → 1.0.2

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.
@@ -1,353 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import { UrlboxPlugin } from '../urlbox.plugin.js';
3
- import type { PluginContext, ScreenshotOptions } from '@ever-works/plugin';
4
-
5
- // Mock the urlbox module
6
- // urlbox exports a factory function: Urlbox(apiKey, apiSecret) => { generateRenderLink(options) }
7
- vi.mock('urlbox', () => {
8
- const mockGenerateRenderLink = vi
9
- .fn()
10
- .mockReturnValue('https://api.urlbox.com/v1/render?url=https%3A%2F%2Fexample.com&width=1280');
11
-
12
- const mockUrlboxFactory = vi.fn().mockReturnValue({
13
- generateRenderLink: mockGenerateRenderLink
14
- });
15
-
16
- return {
17
- default: mockUrlboxFactory
18
- };
19
- });
20
-
21
- // Mock global fetch
22
- const mockFetchResponse = {
23
- ok: true,
24
- status: 200,
25
- arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(100))
26
- };
27
-
28
- vi.stubGlobal('fetch', vi.fn().mockResolvedValue(mockFetchResponse));
29
-
30
- describe('UrlboxPlugin', () => {
31
- let plugin: UrlboxPlugin;
32
- let mockContext: PluginContext;
33
-
34
- beforeEach(() => {
35
- plugin = new UrlboxPlugin();
36
- mockContext = {
37
- pluginId: 'urlbox',
38
- logger: {
39
- log: vi.fn(),
40
- error: vi.fn(),
41
- warn: vi.fn(),
42
- debug: vi.fn()
43
- },
44
- cache: {} as any,
45
- http: {} as any,
46
- env: {} as any,
47
- envVars: {} as any,
48
- services: {} as any,
49
- getSettings: vi.fn().mockResolvedValue({}),
50
- getResolvedSettings: vi.fn().mockResolvedValue({}),
51
- onEvent: vi.fn(),
52
- emitEvent: vi.fn(),
53
- registerCustomCapability: vi.fn(),
54
- getCustomCapability: vi.fn(),
55
- hasCustomCapability: vi.fn(),
56
- listCustomCapabilities: vi.fn()
57
- };
58
- });
59
-
60
- afterEach(() => {
61
- vi.clearAllMocks();
62
- });
63
-
64
- describe('Plugin Metadata', () => {
65
- it('should have correct plugin metadata', () => {
66
- expect(plugin.id).toBe('urlbox');
67
- expect(plugin.name).toBe('Urlbox');
68
- expect(plugin.version).toBe('1.0.0');
69
- expect(plugin.category).toBe('screenshot');
70
- });
71
-
72
- it('should have screenshot capability', () => {
73
- expect(plugin.capabilities).toContain('screenshot');
74
- });
75
-
76
- it('should have provider name', () => {
77
- expect(plugin.providerName).toBe('Urlbox');
78
- });
79
-
80
- it('should have hybrid configuration mode', () => {
81
- expect(plugin.configurationMode).toBe('hybrid');
82
- });
83
- });
84
-
85
- describe('Settings Schema', () => {
86
- it('should define apiKey as required', () => {
87
- expect(plugin.settingsSchema.required).toContain('apiKey');
88
- });
89
-
90
- it('should mark apiKey as secret', () => {
91
- const properties = plugin.settingsSchema.properties as Record<string, any>;
92
- expect(properties.apiKey['x-secret']).toBe(true);
93
- });
94
-
95
- it('should mark apiSecret as secret', () => {
96
- const properties = plugin.settingsSchema.properties as Record<string, any>;
97
- expect(properties.apiSecret['x-secret']).toBe(true);
98
- });
99
-
100
- it('should have environment variable fallbacks', () => {
101
- const properties = plugin.settingsSchema.properties as Record<string, any>;
102
- expect(properties.apiKey['x-envVar']).toBe('PLUGIN_URLBOX_API_KEY');
103
- expect(properties.apiSecret['x-envVar']).toBe('PLUGIN_URLBOX_API_SECRET');
104
- expect(properties.viewportWidth['x-envVar']).toBe('PLUGIN_URLBOX_VIEWPORT_WIDTH');
105
- expect(properties.viewportHeight['x-envVar']).toBe('PLUGIN_URLBOX_VIEWPORT_HEIGHT');
106
- expect(properties.format['x-envVar']).toBe('PLUGIN_URLBOX_FORMAT');
107
- });
108
-
109
- it('should have default values for viewport settings', () => {
110
- const properties = plugin.settingsSchema.properties as Record<string, any>;
111
- expect(properties.viewportWidth.default).toBe(1280);
112
- expect(properties.viewportHeight.default).toBe(1024);
113
- });
114
-
115
- it('should have default values for format and blocking options', () => {
116
- const properties = plugin.settingsSchema.properties as Record<string, any>;
117
- expect(properties.format.default).toBe('png');
118
- expect(properties.fullPage.default).toBe(false);
119
- expect(properties.blockAds.default).toBe(true);
120
- expect(properties.hideCookieBanners.default).toBe(true);
121
- });
122
-
123
- it('should have quality setting with correct bounds', () => {
124
- const properties = plugin.settingsSchema.properties as Record<string, any>;
125
- expect(properties.quality.default).toBe(80);
126
- expect(properties.quality.minimum).toBe(1);
127
- expect(properties.quality.maximum).toBe(100);
128
- });
129
-
130
- it('should have retina setting defaulting to false', () => {
131
- const properties = plugin.settingsSchema.properties as Record<string, any>;
132
- expect(properties.retina.default).toBe(false);
133
- });
134
-
135
- it('should have format enum with supported formats', () => {
136
- const properties = plugin.settingsSchema.properties as Record<string, any>;
137
- expect(properties.format.enum).toEqual(['png', 'jpg', 'jpeg', 'webp']);
138
- });
139
- });
140
-
141
- describe('IScreenshotPlugin - capture', () => {
142
- it('should capture screenshot successfully with settings', async () => {
143
- await plugin.onLoad(mockContext);
144
-
145
- const options: ScreenshotOptions = {
146
- url: 'https://example.com',
147
- settings: {
148
- apiKey: 'test-api-key',
149
- apiSecret: 'test-api-secret'
150
- }
151
- };
152
-
153
- const result = await plugin.capture(options);
154
-
155
- expect(result.success).toBe(true);
156
- expect(result.imageBuffer).toBeDefined();
157
- expect(result.imageBase64).toBeDefined();
158
- expect(result.imageUrl).toBeDefined();
159
- });
160
-
161
- it('should fail when API key is not configured', async () => {
162
- await plugin.onLoad(mockContext);
163
-
164
- const options: ScreenshotOptions = {
165
- url: 'https://example.com',
166
- settings: {}
167
- };
168
-
169
- const result = await plugin.capture(options);
170
-
171
- expect(result.success).toBe(false);
172
- expect(result.error).toContain('API key not configured');
173
- });
174
-
175
- it('should use provided viewport dimensions', async () => {
176
- await plugin.onLoad(mockContext);
177
-
178
- const options: ScreenshotOptions = {
179
- url: 'https://example.com',
180
- viewportWidth: 1920,
181
- viewportHeight: 1080,
182
- settings: {
183
- apiKey: 'test-key'
184
- }
185
- };
186
-
187
- const result = await plugin.capture(options);
188
-
189
- expect(result.success).toBe(true);
190
- expect(result.width).toBe(1920);
191
- expect(result.height).toBe(1080);
192
- });
193
- });
194
-
195
- describe('IScreenshotPlugin - getScreenshotUrl', () => {
196
- it('should generate URL with settings', async () => {
197
- await plugin.onLoad(mockContext);
198
-
199
- const options: ScreenshotOptions = {
200
- url: 'https://example.com',
201
- settings: {
202
- apiKey: 'test-key'
203
- }
204
- };
205
-
206
- const url = await plugin.getScreenshotUrl(options);
207
-
208
- expect(url).toBeDefined();
209
- expect(url).toContain('api.urlbox.com');
210
- });
211
-
212
- it('should generate render link with API secret', async () => {
213
- await plugin.onLoad(mockContext);
214
-
215
- const options: ScreenshotOptions = {
216
- url: 'https://example.com',
217
- settings: {
218
- apiKey: 'test-key',
219
- apiSecret: 'test-secret'
220
- }
221
- };
222
-
223
- const url = await plugin.getScreenshotUrl(options);
224
-
225
- expect(url).toBeDefined();
226
- expect(url).toContain('api.urlbox.com');
227
- });
228
-
229
- it('should return null when API key is missing', async () => {
230
- await plugin.onLoad(mockContext);
231
-
232
- const options: ScreenshotOptions = {
233
- url: 'https://example.com',
234
- settings: {}
235
- };
236
-
237
- const url = await plugin.getScreenshotUrl(options);
238
-
239
- expect(url).toBeNull();
240
- });
241
- });
242
-
243
- describe('IScreenshotPlugin - isAvailable', () => {
244
- it('should return true when API key is configured', async () => {
245
- (mockContext.getSettings as ReturnType<typeof vi.fn>).mockResolvedValue({ apiKey: 'test-key' });
246
- await plugin.onLoad(mockContext);
247
- const available = await plugin.isAvailable();
248
- expect(available).toBe(true);
249
- });
250
-
251
- it('should return false when not loaded', async () => {
252
- const available = await plugin.isAvailable();
253
- expect(available).toBe(false);
254
- });
255
- });
256
-
257
- describe('IScreenshotPlugin - validateCredentials', () => {
258
- it('should return invalid when plugin not initialized', async () => {
259
- const result = await plugin.validateCredentials();
260
-
261
- expect(result.valid).toBe(false);
262
- expect(result.message).toContain('not initialized');
263
- });
264
-
265
- it('should return invalid when API key not configured', async () => {
266
- vi.mocked(mockContext.getSettings).mockResolvedValue({});
267
- await plugin.onLoad(mockContext);
268
-
269
- const result = await plugin.validateCredentials();
270
-
271
- expect(result.valid).toBe(false);
272
- expect(result.message).toContain('API key is not configured');
273
- });
274
-
275
- it('should return valid when credentials are configured', async () => {
276
- vi.mocked(mockContext.getSettings).mockResolvedValue({
277
- apiKey: 'test-key'
278
- });
279
- await plugin.onLoad(mockContext);
280
-
281
- const result = await plugin.validateCredentials();
282
-
283
- expect(result.valid).toBe(true);
284
- });
285
- });
286
-
287
- describe('IScreenshotPlugin - getSupportedFormats', () => {
288
- it('should return supported formats', () => {
289
- const formats = plugin.getSupportedFormats();
290
-
291
- expect(formats).toContain('png');
292
- expect(formats).toContain('jpg');
293
- expect(formats).toContain('jpeg');
294
- expect(formats).toContain('webp');
295
- });
296
- });
297
-
298
- describe('IScreenshotPlugin - getMaxDimensions', () => {
299
- it('should return maximum viewport dimensions', () => {
300
- const dimensions = plugin.getMaxDimensions();
301
-
302
- expect(dimensions.width).toBe(3840);
303
- expect(dimensions.height).toBe(2160);
304
- });
305
- });
306
-
307
- describe('Lifecycle', () => {
308
- it('should log on load', async () => {
309
- await plugin.onLoad(mockContext);
310
- expect(mockContext.logger.log).toHaveBeenCalledWith('Urlbox Plugin loaded');
311
- });
312
-
313
- it('should clear context on unload', async () => {
314
- await plugin.onLoad(mockContext);
315
- await plugin.onUnload();
316
- // Context should be cleared - validateCredentials should fail
317
- const result = await plugin.validateCredentials();
318
- expect(result.valid).toBe(false);
319
- expect(result.message).toContain('not initialized');
320
- });
321
- });
322
-
323
- describe('healthCheck', () => {
324
- it('should return healthy status', async () => {
325
- const health = await plugin.healthCheck();
326
-
327
- expect(health.status).toBe('healthy');
328
- expect(health.checkedAt).toBeDefined();
329
- });
330
- });
331
-
332
- describe('getManifest', () => {
333
- it('should return correct manifest', () => {
334
- const manifest = plugin.getManifest();
335
-
336
- expect(manifest.id).toBe('urlbox');
337
- expect(manifest.name).toBe('Urlbox');
338
- expect(manifest.version).toBe('1.0.0');
339
- expect(manifest.category).toBe('screenshot');
340
- expect(manifest.capabilities).toContain('screenshot');
341
- expect(manifest.builtIn).toBe(false);
342
- expect(manifest.systemPlugin).toBe(false);
343
- });
344
-
345
- it('should have icon configuration', () => {
346
- const manifest = plugin.getManifest();
347
-
348
- expect(manifest.icon).toBeDefined();
349
- expect(manifest.icon?.type).toBe('url');
350
- expect(manifest.icon?.value).toBe('https://urlbox.com/apple-touch-icon.png');
351
- });
352
- });
353
- });
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { UrlboxPlugin } from './urlbox.plugin.js';
2
- export { UrlboxPlugin as default } from './urlbox.plugin.js';