diff --git a/src/mediaManager.integration.test.ts b/src/mediaManager.integration.test.ts index 86d3dae..34ec2a0 100644 --- a/src/mediaManager.integration.test.ts +++ b/src/mediaManager.integration.test.ts @@ -72,6 +72,7 @@ describe("MediaService V2 Integration Logic", () => { moveTo: jest.fn(), getMimeType: () => "image/jpeg", getBlob: () => ({}), + getSize: () => 1024, getId: () => id })) diff --git a/src/services/MediaService.test.ts b/src/services/MediaService.test.ts index 62601c7..c3c179c 100644 --- a/src/services/MediaService.test.ts +++ b/src/services/MediaService.test.ts @@ -163,4 +163,46 @@ describe("MediaService Robust Sync", () => { expect(spyRename).toHaveBeenCalledWith(f1.getId(), expect.stringMatching(/^SKU123_\d+\.jpg$/)) expect(spyRename).not.toHaveBeenCalledWith(f2.getId(), expect.anything()) }) + test("Upload: Handles Video Uploads with correct resource type", () => { + const folder = driveService.getOrCreateFolder("SKU_VIDEO", "root") + + // Mock Video Blob + const videoBlob = { + getName: () => "video.mp4", + getBytes: () => [], + getContentType: () => "video/mp4", + getThumbnail: () => ({ getBytes: () => [] }) + } as any + + const vidFile = driveService.saveFile(videoBlob, folder.getId()) + + const finalState = [{ + id: vidFile.getId(), + driveId: vidFile.getId(), + filename: "video.mp4", + source: "drive_only" + }] + + const spyStaged = jest.spyOn(shopifyService, 'stagedUploadsCreate') + const spyCreate = jest.spyOn(shopifyService, 'productCreateMedia') + + mediaService.processMediaChanges("SKU_VIDEO", finalState, "pid") + + // 1. Verify stagedUploadsCreate called with resource="VIDEO" and fileSize + expect(spyStaged).toHaveBeenCalledWith(expect.arrayContaining([ + expect.objectContaining({ + resource: "VIDEO", + mimeType: "video/mp4", + filename: "video.mp4", + fileSize: "0" // 0 because mock bytes are empty + }) + ])) + + // 2. Verify productCreateMedia called with mediaContentType="VIDEO" + expect(spyCreate).toHaveBeenCalledWith("pid", expect.arrayContaining([ + expect.objectContaining({ + mediaContentType: "VIDEO" + }) + ])) + }) }) diff --git a/src/services/MediaService.ts b/src/services/MediaService.ts index 5f19c16..4a5f7c7 100644 --- a/src/services/MediaService.ts +++ b/src/services/MediaService.ts @@ -277,7 +277,8 @@ export class MediaService { return { filename: f.getName(), mimeType: f.getMimeType(), - resource: "IMAGE", + resource: f.getMimeType().startsWith('video/') ? "VIDEO" : "IMAGE", + fileSize: f.getSize().toString(), httpMethod: "POST", file: f, originalItem: item @@ -290,14 +291,26 @@ export class MediaService { filename: u.filename, mimeType: u.mimeType, resource: u.resource, + fileSize: u.fileSize, httpMethod: u.httpMethod })) const stagedResp = shopifySvc.stagedUploadsCreate(stagedInput) + + if (stagedResp.userErrors && stagedResp.userErrors.length > 0) { + console.error("[MediaService] stagedUploadsCreate Errors:", JSON.stringify(stagedResp.userErrors)) + logs.push(`- Upload preparation failed: ${stagedResp.userErrors.map(e => e.message).join(', ')}`) + } + const targets = stagedResp.stagedTargets const mediaToCreate = [] uploads.forEach((u, i) => { const target = targets[i] + if (!target || !target.url) { + logs.push(`- Failed to get upload target for ${u.filename}: Invalid target`) + console.warn(`[MediaService] Missing target URL for ${u.filename}. Target:`, JSON.stringify(target)) + return + } const payload = {} target.parameters.forEach((p: any) => payload[p.name] = p.value) payload['file'] = u.file.getBlob() @@ -305,7 +318,7 @@ export class MediaService { mediaToCreate.push({ originalSource: target.resourceUrl, alt: u.filename, - mediaContentType: "IMAGE" + mediaContentType: u.resource }) }) diff --git a/src/services/MockDriveService.ts b/src/services/MockDriveService.ts index 3d41701..e10df29 100644 --- a/src/services/MockDriveService.ts +++ b/src/services/MockDriveService.ts @@ -52,6 +52,7 @@ export class MockDriveService implements IDriveService { getThumbnail: () => ({ getBytes: () => [] }), getMimeType: () => (blob as any).getContentType ? (blob as any).getContentType() : "image/jpeg", getDownloadUrl: () => `https://drive.google.com/uc?export=download&id=${id}`, + getSize: () => blob.getBytes ? blob.getBytes().length : 0, getAppProperty: (key) => { return (newFile as any)._properties?.[key] }