diff --git a/apps-rendering/package.json b/apps-rendering/package.json index 86437de3e85..961cdebfee6 100644 --- a/apps-rendering/package.json +++ b/apps-rendering/package.json @@ -41,11 +41,11 @@ "@emotion/jest": "11.13.0", "@emotion/react": "11.14.0", "@emotion/server": "11.11.0", - "@guardian/apps-rendering-api-models": "11.0.0", + "@guardian/apps-rendering-api-models": "13.0.1", "@guardian/bridget": "7.0.0", "@guardian/cdk": "61.4.0", - "@guardian/content-api-models": "26.0.0", - "@guardian/content-atom-model": "4.0.1", + "@guardian/content-api-models": "31.0.0", + "@guardian/content-atom-model": "6.1.0", "@guardian/eslint-config": "7.0.1", "@guardian/eslint-config-typescript": "9.0.1", "@guardian/libs": "22.0.0", diff --git a/apps-rendering/src/atoms.test.ts b/apps-rendering/src/atoms.test.ts index 95aecf86dcd..aa3fb6e9331 100644 --- a/apps-rendering/src/atoms.test.ts +++ b/apps-rendering/src/atoms.test.ts @@ -653,6 +653,7 @@ describe('parseAtom', () => { let atoms: Atoms; let media: Atom; let mediaAtom: MediaAtom; + const assetVersion = new Int64(1); beforeEach(() => { blockElement.contentAtomTypeData = { @@ -662,10 +663,16 @@ describe('parseAtom', () => { mediaAtom = { title: '', assets: [ + { + assetType: AssetType.SUBTITLES, + id: 'subtitles-asset-id', + version: assetVersion, + platform: Platform.YOUTUBE, + }, { assetType: AssetType.VIDEO, - id: 'asset-id', - version: new Int64(1), + id: 'video-asset-id', + version: assetVersion, platform: Platform.YOUTUBE, }, ], @@ -726,7 +733,7 @@ describe('parseAtom', () => { posterUrl: 'poster-url', caption: some(frag), duration: some(1000), - videoId: 'asset-id', + videoId: 'video-asset-id', id: atomId, title: '', }), diff --git a/apps-rendering/src/atoms.ts b/apps-rendering/src/atoms.ts index 09e306a6bb3..0eaa6d4c43c 100644 --- a/apps-rendering/src/atoms.ts +++ b/apps-rendering/src/atoms.ts @@ -8,6 +8,8 @@ import { isValidDate } from 'date'; import type { Int64 } from 'thrift'; import type { DocParser } from 'parserContext'; import { Result } from 'result'; +import type { MediaAtom } from '@guardian/content-atom-model/media/mediaAtom'; +import { AssetType } from '@guardian/content-atom-model/media/assetType'; interface TimelineEvent { title: string; @@ -248,10 +250,12 @@ function parseAtom( return Result.err(`No atom matched this id: ${id}`); } + const mediaAtom: MediaAtom = atom.data.media; const { posterUrl, duration, assets, activeVersion, title } = - atom.data.media; + mediaAtom; const videoId = assets.find( (asset) => + asset.assetType === AssetType.VIDEO && asset.version.toNumber() === activeVersion?.toNumber(), )?.id; const caption = docParser(title); diff --git a/apps-rendering/src/video.test.ts b/apps-rendering/src/video.test.ts index 7e92e661a23..d33dad0ed1a 100644 --- a/apps-rendering/src/video.test.ts +++ b/apps-rendering/src/video.test.ts @@ -22,7 +22,8 @@ describe('parseVideo', () => { let mediaAtom: MediaAtom; const atomId = 'atomId2'; const posterUrl = 'poster-url'; - const assetId = 'asset-id'; + const videoAssetId = 'video-asset-id'; + const subtitlesAssetId = 'subtitles-asset-id'; const mediaAtomTitle = 'mediaTitle'; const assetVersion = new Int64(2); @@ -43,9 +44,15 @@ describe('parseVideo', () => { mediaAtom = { assets: [ + { + assetType: AssetType.SUBTITLES, + id: subtitlesAssetId, + version: assetVersion, + platform: Platform.YOUTUBE, + }, { assetType: AssetType.VIDEO, - id: assetId, + id: videoAssetId, version: assetVersion, platform: Platform.YOUTUBE, }, @@ -79,7 +86,7 @@ describe('parseVideo', () => { test('returns video', () => { const expected = Optional.some({ posterUrl: posterUrl, - videoId: assetId, + videoId: videoAssetId, duration: undefined, atomId: atomId, title: mediaAtomTitle, diff --git a/apps-rendering/src/video.ts b/apps-rendering/src/video.ts index 2fe565d9877..1becb34dcd7 100644 --- a/apps-rendering/src/video.ts +++ b/apps-rendering/src/video.ts @@ -1,6 +1,8 @@ import type { Atoms } from '@guardian/content-api-models/v1/atoms'; import type { BlockElement } from '@guardian/content-api-models/v1/blockElement'; import { Optional } from 'optional'; +import type { MediaAtom } from '@guardian/content-atom-model/media/mediaAtom'; +import { AssetType } from '@guardian/content-atom-model/media/assetType'; interface Video { posterUrl: string; @@ -23,10 +25,12 @@ const parseVideo = if (atom?.data.kind !== 'media') { return Optional.none(); } - - const { posterUrl, duration, assets, activeVersion, title } = - atom.data.media; - const videoId = assets.find( + const mediaAtom: MediaAtom = atom.data.media; + const { posterUrl, duration, assets, activeVersion, title } = mediaAtom; + const videoAssets = assets.filter( + (asset) => asset.assetType === AssetType.VIDEO, + ); + const videoId = videoAssets.find( (asset) => asset.version.toNumber() === activeVersion?.toNumber(), )?.id; diff --git a/dotcom-rendering/src/frontend/feFront.ts b/dotcom-rendering/src/frontend/feFront.ts index 4d6b5a71e8d..3c1cbd6f41e 100644 --- a/dotcom-rendering/src/frontend/feFront.ts +++ b/dotcom-rendering/src/frontend/feFront.ts @@ -111,6 +111,7 @@ export interface FEMediaAsset { version: number; platform: string; mimeType?: string; + assetType: string; } /** @see https://github.com/guardian/frontend/blob/0bf69f55a/common/app/model/content/Atom.scala#L158-L169 */ diff --git a/dotcom-rendering/src/frontend/schemas/feFront.json b/dotcom-rendering/src/frontend/schemas/feFront.json index 9855488ff7b..82488205db5 100644 --- a/dotcom-rendering/src/frontend/schemas/feFront.json +++ b/dotcom-rendering/src/frontend/schemas/feFront.json @@ -3261,9 +3261,13 @@ }, "mimeType": { "type": "string" + }, + "assetType": { + "type": "string" } }, "required": [ + "assetType", "id", "platform", "version" diff --git a/dotcom-rendering/src/frontend/schemas/feTagPage.json b/dotcom-rendering/src/frontend/schemas/feTagPage.json index ea3f0a9af7a..c0c51ee4993 100644 --- a/dotcom-rendering/src/frontend/schemas/feTagPage.json +++ b/dotcom-rendering/src/frontend/schemas/feTagPage.json @@ -1434,9 +1434,13 @@ }, "mimeType": { "type": "string" + }, + "assetType": { + "type": "string" } }, "required": [ + "assetType", "id", "platform", "version" diff --git a/dotcom-rendering/src/model/enhanceCards.test.ts b/dotcom-rendering/src/model/enhanceCards.test.ts index fbc0c20a4ed..07ff42cee39 100644 --- a/dotcom-rendering/src/model/enhanceCards.test.ts +++ b/dotcom-rendering/src/model/enhanceCards.test.ts @@ -10,12 +10,74 @@ describe('Enhance Cards', () => { version: 1, platform: 'Url', mimeType: 'video/mp4', + assetType: 'Video', }, { id: 'https://guim-example.co.uk/atomID-1.m3u8', version: 1, platform: 'Url', mimeType: 'application/x-mpegURL', + assetType: 'Video', + }, + ]; + const mediaAtom: FEMediaAtom = { + id: 'atomID', + assets, + title: 'Example video', + duration: 15, + source: '', + posterImage: { allImages: [] }, + trailImage: { allImages: [] }, + expired: false, + activeVersion: 1, + }; + const cardTrailImage = ''; + + expect( + getActiveMediaAtom(videoReplace, mediaAtom, cardTrailImage), + ).toEqual({ + atomId: 'atomID', + duration: 15, + height: 400, + image: '', + type: 'LoopVideo', + sources: [ + { + mimeType: 'application/x-mpegURL', + src: 'https://guim-example.co.uk/atomID-1.m3u8', + }, + { + mimeType: 'video/mp4', + src: 'https://guim-example.co.uk/atomID-1.mp4', + }, + ], + width: 500, + }); + }); + + it('filters out non-video assets', () => { + const videoReplace = true; + const assets: FEMediaAsset[] = [ + { + id: 'https://guim-example.co.uk/atomID-1.vtt', + version: 1, + platform: 'Url', + mimeType: 'text/vtt', + assetType: 'Subtitles', + }, + { + id: 'https://guim-example.co.uk/atomID-1.m3u8', + version: 1, + platform: 'Url', + mimeType: 'application/x-mpegURL', + assetType: 'Video', + }, + { + id: 'https://guim-example.co.uk/atomID-1.mp4', + version: 1, + platform: 'Url', + mimeType: 'video/mp4', + assetType: 'Video', }, ]; const mediaAtom: FEMediaAtom = { diff --git a/dotcom-rendering/src/model/enhanceCards.ts b/dotcom-rendering/src/model/enhanceCards.ts index f5a1dc72878..635a6db70fa 100644 --- a/dotcom-rendering/src/model/enhanceCards.ts +++ b/dotcom-rendering/src/model/enhanceCards.ts @@ -200,9 +200,9 @@ export const getActiveMediaAtom = ( cardTrailImage?: string, ): MainMedia | undefined => { if (mediaAtom) { - const assets = mediaAtom.assets.filter( - ({ version }) => version === mediaAtom.activeVersion, - ); + const assets = mediaAtom.assets + .filter((_) => _.assetType === 'Video') + .filter(({ version }) => version === mediaAtom.activeVersion); if (!assets.length) return undefined; const image = decideMediaAtomImage( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a368149d4bb..c30fb69194e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -64,8 +64,8 @@ importers: specifier: 11.11.0 version: 11.11.0 '@guardian/apps-rendering-api-models': - specifier: 11.0.0 - version: 11.0.0 + specifier: 13.0.1 + version: 13.0.1 '@guardian/bridget': specifier: 7.0.0 version: 7.0.0 @@ -73,11 +73,11 @@ importers: specifier: 61.4.0 version: 61.4.0(aws-cdk-lib@2.189.0)(aws-cdk@2.1007.0)(constructs@10.4.2) '@guardian/content-api-models': - specifier: 26.0.0 - version: 26.0.0 + specifier: 31.0.0 + version: 31.0.0 '@guardian/content-atom-model': - specifier: 4.0.1 - version: 4.0.1 + specifier: 6.1.0 + version: 6.1.0 '@guardian/eslint-config': specifier: 7.0.1 version: 7.0.1(@typescript-eslint/parser@6.18.0)(eslint@8.56.0)(tslib@2.6.2) @@ -4743,11 +4743,11 @@ packages: typescript: 5.5.3 dev: false - /@guardian/apps-rendering-api-models@11.0.0: - resolution: {integrity: sha512-cmyMiQK4jSiCX4nN3wHnSqB6StKZ4Gek2q6p3l8g4ZJRq46nl0OcTvNm5/SsrjHPsOArImN9XKiaNP4BVZvRoQ==} + /@guardian/apps-rendering-api-models@13.0.1: + resolution: {integrity: sha512-w2+jArODTq/dWD/Gx44LBkaiy8cA8+aJ1S6ZMx2huFdN69QL1Ex3QhEmzzjqDbSymA9cxJEySb92y8+QZIxycw==} dependencies: - '@guardian/content-api-models': 26.0.0 - '@guardian/content-atom-model': 4.0.4 + '@guardian/content-api-models': 31.0.0 + '@guardian/content-atom-model': 6.1.0 '@guardian/content-entity-model': 3.0.3 '@guardian/story-packages-model': 2.2.0 '@types/node-int64': 0.4.32 @@ -4827,10 +4827,10 @@ packages: '@types/googletag': 3.3.0 dev: false - /@guardian/content-api-models@26.0.0: - resolution: {integrity: sha512-41kW0r/aq8LDgrs4sBnBIGeNTzYbqUM+9qYL3y5nR+8pKZJ3lF1NPIcsdcoG1nRhrkhLnqsehfJ/oWgwPPBg/w==} + /@guardian/content-api-models@31.0.0: + resolution: {integrity: sha512-DlamPrKkfCncpais8gyUdF6oXLLWB1xIXb/J5GUUkeCsNYfffYKU0snae5kPUIKycLZ0AiS5dV6ZOxTPCcM8pw==} dependencies: - '@guardian/content-atom-model': 4.0.4 + '@guardian/content-atom-model': 6.1.0 '@guardian/content-entity-model': 3.0.3 '@guardian/story-packages-model': 2.2.0 '@types/node-int64': 0.4.32 @@ -4842,23 +4842,10 @@ packages: - utf-8-validate dev: false - /@guardian/content-atom-model@4.0.1: - resolution: {integrity: sha512-c2biKd9SPbXiCmN9ZOyYdaiPlwLCJNEzRGqWW0hISq3ELOzqndhTG6/vYrQMp0+7CmDEeQ+4pSzZxPfvIN10Tw==} - dependencies: - '@guardian/content-entity-model': 2.2.1 - '@types/node-int64': 0.4.32 - '@types/thrift': 0.10.17 - node-int64: 0.4.0 - thrift: 0.15.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /@guardian/content-atom-model@4.0.4: - resolution: {integrity: sha512-B/2oe4h6wYoygKEdcvycgRw4keKglvRu/ma81Ad+Gb5OnBcRTqIoeRmgO2V8BEbrHxPLSjBMI3SimcgbUccBzg==} + /@guardian/content-atom-model@6.1.0: + resolution: {integrity: sha512-crRWfm7DhfBopMUK3m7/Vj0TBSPDf1Ui/a/4tn9+xtpediQUuQBJLKXE37BHAzBi2nKkLXCZQdH1m2AnSaeprQ==} dependencies: - '@guardian/content-entity-model': 3.0.3 + '@guardian/content-entity-model': 4.0.0 '@types/node-int64': 0.4.32 '@types/thrift': 0.10.17 node-int64: 0.4.0 @@ -4868,8 +4855,8 @@ packages: - utf-8-validate dev: false - /@guardian/content-entity-model@2.2.1: - resolution: {integrity: sha512-ywFYEmwvM8LcLxKbP321KqRGzd4lD40MNUCxS7V38eLbo6emgIJDmPl4rpNMgznR79BL5S1Q0FOhhRqChSVv/g==} + /@guardian/content-entity-model@3.0.3: + resolution: {integrity: sha512-Eu45IhbJk2/JfWrJjwmEQDcQjYm+EgTPIbaSGVVy6TAipD8t2i08VStnOYgXXRHgRvQU4QyiZSmaW6Rpjrao7w==} dependencies: '@types/node-int64': 0.4.32 '@types/thrift': 0.10.17 @@ -4880,8 +4867,8 @@ packages: - utf-8-validate dev: false - /@guardian/content-entity-model@3.0.3: - resolution: {integrity: sha512-Eu45IhbJk2/JfWrJjwmEQDcQjYm+EgTPIbaSGVVy6TAipD8t2i08VStnOYgXXRHgRvQU4QyiZSmaW6Rpjrao7w==} + /@guardian/content-entity-model@4.0.0: + resolution: {integrity: sha512-dtjmkXifML+rhQL0TY4zyTsiyukPwexntVKod5/h36/0zpjTO700YIVnx03vh6NnvNLM97g309Qcg1cE0h45hA==} dependencies: '@types/node-int64': 0.4.32 '@types/thrift': 0.10.17