Skip to content

Commit 9416048

Browse files
committed
Refactor: standardize string quotes in tests and update README description
- Changed single quotes to double quotes for consistency in the test files. - Updated the README.md to clarify the component's purpose as a Convex Component for Cloudinary integration.
1 parent ddb080a commit 9416048

File tree

3 files changed

+66
-65
lines changed

3 files changed

+66
-65
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
- **[Example Repo (Studio App)](https://github.com/imaxisXD/cloudinary-convex-studio)**
77

8-
A comprehensive Cloudinary integration component for Convex that provides image upload, transformation, and management capabilities using direct Cloudinary REST APIs with full TypeScript support.
8+
A Convex Component for Cloudinary integration that provides image upload, transformation, and management capabilities using direct Cloudinary REST APIs with full TypeScript support.
99

1010
<!-- START: Include on https://convex.dev/components -->
1111

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,4 @@
9393
},
9494
"types": "./dist/client/index.d.ts",
9595
"module": "./dist/client/index.js"
96-
}
96+
}

src/component/lib.test.ts

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ import { api } from "./_generated/api.js";
77
import { modules } from "./setup.test.js";
88

99
// Mock Cloudinary credentials (these are fake for testing)
10-
process.env.CLOUDINARY_CLOUD_NAME = 'test-cloud';
11-
process.env.CLOUDINARY_API_KEY = '123456789012345';
12-
process.env.CLOUDINARY_API_SECRET = 'test-secret-key-123456789';
10+
process.env.CLOUDINARY_CLOUD_NAME = "test-cloud";
11+
process.env.CLOUDINARY_API_KEY = "123456789012345";
12+
process.env.CLOUDINARY_API_SECRET = "test-secret-key-123456789";
1313

1414
// Mock config object for API calls
1515
const mockConfig = {
16-
cloudName: 'test-cloud',
17-
apiKey: '123456789012345',
18-
apiSecret: 'test-secret-key-123456789',
16+
cloudName: "test-cloud",
17+
apiKey: "123456789012345",
18+
apiSecret: "test-secret-key-123456789",
1919
};
2020

2121
// Mock base64 image data (1x1 transparent PNG)
22-
const mockImageBase64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
22+
const mockImageBase64 =
23+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";
2324

2425
describe("Cloudinary component lib", () => {
2526
beforeEach(async () => {
@@ -32,175 +33,175 @@ describe("Cloudinary component lib", () => {
3233
// Test transformation URL generation (doesn't require API calls)
3334
test("should generate transformed URLs", async () => {
3435
const t = convexTest(schema, modules);
35-
36+
3637
const result = await t.query(api.lib.transform, {
37-
publicId: 'sample-image',
38+
publicId: "sample-image",
3839
transformation: {
3940
width: 300,
4041
height: 300,
41-
crop: 'fill'
42+
crop: "fill",
4243
},
4344
config: mockConfig,
4445
});
45-
46-
expect(result.transformedUrl).toContain('test-cloud');
47-
expect(result.transformedUrl).toContain('w_300,h_300,c_fill');
48-
expect(result.transformedUrl).toContain('sample-image');
46+
47+
expect(result.transformedUrl).toContain("test-cloud");
48+
expect(result.transformedUrl).toContain("w_300,h_300,c_fill");
49+
expect(result.transformedUrl).toContain("sample-image");
4950
});
5051

5152
// Test file validation (doesn't require API calls)
5253
test("should validate file data format", async () => {
5354
const t = convexTest(schema, modules);
54-
55+
5556
// Test with invalid base64 data
5657
const result = await t.action(api.lib.upload, {
57-
base64Data: 'invalid-data',
58-
filename: 'test.png',
58+
base64Data: "invalid-data",
59+
filename: "test.png",
5960
config: mockConfig,
6061
});
61-
62+
6263
expect(result.success).toBe(false);
63-
expect(result.error).toContain('Invalid file data format');
64+
expect(result.error).toContain("Invalid file data format");
6465
});
6566

6667
// Test transformation parameter validation
6768
test("should validate transformation parameters", async () => {
6869
const t = convexTest(schema, modules);
69-
70+
7071
try {
7172
await t.query(api.lib.transform, {
72-
publicId: 'test-image',
73+
publicId: "test-image",
7374
transformation: {
74-
width: -1, // Invalid width
75+
width: -1, // Invalid width
7576
height: 300,
76-
crop: 'fill'
77+
crop: "fill",
7778
},
7879
config: mockConfig,
7980
});
80-
expect.fail('Should have thrown validation error');
81+
expect.fail("Should have thrown validation error");
8182
} catch (error) {
82-
expect((error as Error).message).toContain('Width must be between');
83+
expect((error as Error).message).toContain("Width must be between");
8384
}
8485
});
8586

8687
// Test that transformation URL contains correct parameters
8788
test("should include all transformation parameters in URL", async () => {
8889
const t = convexTest(schema, modules);
89-
90+
9091
const result = await t.query(api.lib.transform, {
91-
publicId: 'my-image',
92+
publicId: "my-image",
9293
transformation: {
9394
width: 500,
9495
height: 400,
95-
crop: 'thumb',
96-
quality: 'auto',
97-
format: 'webp',
98-
gravity: 'face',
96+
crop: "thumb",
97+
quality: "auto",
98+
format: "webp",
99+
gravity: "face",
99100
},
100101
config: mockConfig,
101102
});
102-
103-
expect(result.transformedUrl).toContain('w_500');
104-
expect(result.transformedUrl).toContain('h_400');
105-
expect(result.transformedUrl).toContain('c_thumb');
106-
expect(result.transformedUrl).toContain('q_auto');
107-
expect(result.transformedUrl).toContain('f_webp');
108-
expect(result.transformedUrl).toContain('g_face');
103+
104+
expect(result.transformedUrl).toContain("w_500");
105+
expect(result.transformedUrl).toContain("h_400");
106+
expect(result.transformedUrl).toContain("c_thumb");
107+
expect(result.transformedUrl).toContain("q_auto");
108+
expect(result.transformedUrl).toContain("f_webp");
109+
expect(result.transformedUrl).toContain("g_face");
109110
});
110111

111112
// Test transformation with effects
112113
test("should handle effect transformations", async () => {
113114
const t = convexTest(schema, modules);
114-
115+
115116
const result = await t.query(api.lib.transform, {
116-
publicId: 'test-image',
117+
publicId: "test-image",
117118
transformation: {
118-
effect: 'sepia',
119+
effect: "sepia",
119120
},
120121
config: mockConfig,
121122
});
122-
123-
expect(result.transformedUrl).toContain('e_sepia');
123+
124+
expect(result.transformedUrl).toContain("e_sepia");
124125
});
125126

126127
// Test transformation with radius
127128
test("should handle radius transformation", async () => {
128129
const t = convexTest(schema, modules);
129-
130+
130131
const result = await t.query(api.lib.transform, {
131-
publicId: 'test-image',
132+
publicId: "test-image",
132133
transformation: {
133134
width: 200,
134135
height: 200,
135-
crop: 'fill',
136+
crop: "fill",
136137
radius: 20,
137138
},
138139
config: mockConfig,
139140
});
140-
141-
expect(result.transformedUrl).toContain('r_20');
141+
142+
expect(result.transformedUrl).toContain("r_20");
142143
});
143144

144145
// Test width validation boundary
145146
test("should reject width above maximum", async () => {
146147
const t = convexTest(schema, modules);
147-
148+
148149
try {
149150
await t.query(api.lib.transform, {
150-
publicId: 'test-image',
151+
publicId: "test-image",
151152
transformation: {
152-
width: 5000, // Above max of 4000
153+
width: 5000, // Above max of 4000
153154
height: 300,
154155
},
155156
config: mockConfig,
156157
});
157-
expect.fail('Should have thrown validation error');
158+
expect.fail("Should have thrown validation error");
158159
} catch (error) {
159-
expect((error as Error).message).toContain('Width must be between');
160+
expect((error as Error).message).toContain("Width must be between");
160161
}
161162
});
162163

163164
// Test height validation boundary
164165
test("should reject height above maximum", async () => {
165166
const t = convexTest(schema, modules);
166-
167+
167168
try {
168169
await t.query(api.lib.transform, {
169-
publicId: 'test-image',
170+
publicId: "test-image",
170171
transformation: {
171172
width: 300,
172-
height: 5000, // Above max of 4000
173+
height: 5000, // Above max of 4000
173174
},
174175
config: mockConfig,
175176
});
176-
expect.fail('Should have thrown validation error');
177+
expect.fail("Should have thrown validation error");
177178
} catch (error) {
178-
expect((error as Error).message).toContain('Height must be between');
179+
expect((error as Error).message).toContain("Height must be between");
179180
}
180181
});
181182

182183
// Test valid base64 format is accepted (will fail at API but pass validation)
183184
test("should accept valid base64 format", async () => {
184185
const t = convexTest(schema, modules);
185-
186+
186187
// Valid base64 format should pass validation
187188
// It will fail at the Cloudinary API stage (mock credentials), but not at validation
188189
const result = await t.action(api.lib.upload, {
189190
base64Data: mockImageBase64,
190-
filename: 'test.png',
191+
filename: "test.png",
191192
config: mockConfig,
192193
});
193-
194+
194195
// The upload will fail due to mock credentials, but the error should NOT be about format
195196
if (!result.success && result.error) {
196-
expect(result.error).not.toContain('Invalid file data format');
197+
expect(result.error).not.toContain("Invalid file data format");
197198
}
198199
});
199200

200201
// Note: Integration tests that require real Cloudinary credentials are skipped.
201202
// These tests would need real credentials to run:
202203
// - should upload and store asset
203-
// - should list assets with filtering
204+
// - should list assets with filtering
204205
// - should get single asset
205206
// - should update asset metadata
206207
// - should delete asset

0 commit comments

Comments
 (0)