fix(media-manager): resolve video preview issues and stabilize tests

- Backend (MediaService):
    - Implemented robust contentUrl generation for Drive files using drive.google.com/uc pattern.
    - Added mimeType exposure to unified media state.

- Frontend (MediaManager):
    - Replaced video tag with iframe embedding the Google Drive Preview player (/preview) for reliable playback.
    - Fixed syntax error in console logging causing UI freeze.
    - Updated gallery card logic to prioritize video content URLs.

- Tests (Integration):
    - Refactored mediaManager.integration.test.ts to align with new logic.
    - Mocked DriveApp completely to support orphan adoption flows.
    - Updated file renaming expectations to support timestamped filenames.

- Documentation:
    - Updated MEMORY.md with video preview strategy.
This commit is contained in:
Ben Miller
2025-12-28 15:51:56 -07:00
parent dadcccb7f9
commit 243f7057b7
7 changed files with 74 additions and 21 deletions

View File

@ -11,6 +11,7 @@ const mockDrive = {
renameFile: jest.fn(),
trashFile: jest.fn(),
updateFileProperties: jest.fn(),
getFileProperties: jest.fn(),
getFileById: jest.fn()
}
const mockShopify = {
@ -39,6 +40,10 @@ global.Drive = {
}
} as any
global.DriveApp = {
getRootFolder: jest.fn().mockReturnValue({ removeFile: jest.fn() })
} as any
describe("MediaService V2 Integration Logic", () => {
let service: MediaService
const dummyPid = "gid://shopify/Product/123"
@ -55,7 +60,8 @@ describe("MediaService V2 Integration Logic", () => {
getBlob: jest.fn().mockReturnValue({
getDataAsString: () => "fake_blob_data",
getContentType: () => "image/jpeg",
getBytes: () => []
getBytes: () => [],
setName: jest.fn()
})
})
@ -65,12 +71,14 @@ describe("MediaService V2 Integration Logic", () => {
getName: () => "file_name.jpg",
moveTo: jest.fn(),
getMimeType: () => "image/jpeg",
getBlob: () => ({})
getBlob: () => ({}),
getId: () => id
}))
mockDrive.createFile.mockReturnValue({
getId: () => "new_created_file_id"
})
mockDrive.getFileProperties.mockReturnValue({})
})
describe("getUnifiedMediaState (Phase A)", () => {
@ -80,12 +88,14 @@ describe("MediaService V2 Integration Logic", () => {
getId: () => "drive_1",
getName: () => "IMG_001.jpg",
getAppProperty: (k: string) => k === 'shopify_media_id' ? "gid://shopify/Media/100" : null,
getThumbnail: () => ({ getBytes: () => [] })
getThumbnail: () => ({ getBytes: () => [] }),
getMimeType: () => "image/jpeg"
}
mockDrive.getOrCreateFolder.mockReturnValue({ getId: () => "folder_1" })
mockDrive.getFiles.mockReturnValue([driveFile])
// Setup Shopify
mockDrive.getFileProperties.mockReturnValue({ 'shopify_media_id': 'gid://shopify/Media/100' })
const shopMedia = {
id: "gid://shopify/Media/100",
mediaContentType: "IMAGE",
@ -108,7 +118,8 @@ describe("MediaService V2 Integration Logic", () => {
getId: () => "drive_new",
getName: () => "new.jpg",
getAppProperty: () => null,
getThumbnail: () => ({ getBytes: () => [] })
getThumbnail: () => ({ getBytes: () => [] }),
getMimeType: () => "image/jpeg"
}
mockDrive.getOrCreateFolder.mockReturnValue({ getId: () => "folder_1" })
mockDrive.getFiles.mockReturnValue([driveFile])
@ -121,7 +132,7 @@ describe("MediaService V2 Integration Logic", () => {
})
test("should identify Shopify-Only items", () => {
mockDrive.getOrCreateFolder.mockReturnValue({ getId: () => "folder_1" })
mockDrive.getOrCreateFolder.mockReturnValue({ getId: () => "folder_1", addFile: jest.fn() })
mockDrive.getFiles.mockReturnValue([])
const shopMedia = {
@ -153,14 +164,14 @@ describe("MediaService V2 Integration Logic", () => {
service.processMediaChanges("SKU-123", finalState, dummyPid)
// Assert
expect(mockDrive.renameFile).toHaveBeenCalledWith("d1", "SKU-123_0001.jpg")
expect(mockDrive.renameFile).toHaveBeenCalledWith("d2", "SKU-123_0002.jpg")
expect(mockDrive.renameFile).toHaveBeenCalledWith("d1", expect.stringMatching(/SKU-123_\d+\.jpg/))
expect(mockDrive.renameFile).toHaveBeenCalledWith("d2", expect.stringMatching(/SKU-123_\d+\.jpg/))
})
test("should call Shopify Reorder Mutation", () => {
const finalState = [
{ id: "1", shopifyId: "s10", sortOrder: 0 },
{ id: "2", shopifyId: "s20", sortOrder: 1 }
{ id: "1", shopifyId: "s10", sortOrder: 0, driveId: "d1" },
{ id: "2", shopifyId: "s20", sortOrder: 1, driveId: "d2" }
]
jest.spyOn(service, "getUnifiedMediaState").mockReturnValue([])
@ -179,6 +190,7 @@ describe("MediaService V2 Integration Logic", () => {
jest.spyOn(service, "getUnifiedMediaState").mockReturnValue([])
// Mock file creation
mockDrive.getOrCreateFolder.mockReturnValue({ getId: () => "folder_1", addFile: jest.fn() })
// We set default mockDrive.createFile above but we can specialize if needed
// Default returns "new_created_file_id"