@financial-times/cp-content-pipeline-schema 3.12.2 → 3.14.0
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.
- package/CHANGELOG.md +32 -0
- package/lib/datasources/origami-image.js +3 -3
- package/lib/datasources/origami-image.js.map +1 -1
- package/lib/datasources/url-management.js +45 -7
- package/lib/datasources/url-management.js.map +1 -1
- package/lib/datasources/url-management.test.js +97 -0
- package/lib/datasources/url-management.test.js.map +1 -1
- package/lib/generated/index.d.ts +11 -11
- package/lib/helpers/imageService.js +1 -1
- package/lib/helpers/imageService.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/model/Clip.d.ts +3 -1
- package/lib/model/Clip.js +4 -2
- package/lib/model/Clip.js.map +1 -1
- package/lib/model/Clip.test.js +26 -37
- package/lib/model/Clip.test.js.map +1 -1
- package/lib/model/Concept.js +8 -2
- package/lib/model/Concept.js.map +1 -1
- package/lib/model/Content.js +6 -1
- package/lib/model/Content.js.map +1 -1
- package/lib/model/FlourishSource.js +2 -2
- package/lib/model/FlourishSource.js.map +1 -1
- package/lib/model/Image.js +1 -1
- package/lib/model/Image.js.map +1 -1
- package/lib/model/Image.test.js +8 -8
- package/lib/model/Image.test.js.map +1 -1
- package/lib/model/LeadFlourish.js +1 -1
- package/lib/model/LeadFlourish.js.map +1 -1
- package/lib/model/Person.js +1 -1
- package/lib/model/Person.js.map +1 -1
- package/lib/model/Person.test.js +2 -2
- package/lib/model/Person.test.js.map +1 -1
- package/lib/model/Picture.test.js +4 -2
- package/lib/model/Picture.test.js.map +1 -1
- package/lib/model/RichText.test.js +9 -9
- package/lib/model/Topper.js +1 -1
- package/lib/model/Topper.js.map +1 -1
- package/lib/model/Topper.test.js +3 -2
- package/lib/model/Topper.test.js.map +1 -1
- package/lib/resolvers/content-tree/bodyXMLToTree.test.js +176 -176
- package/lib/resolvers/content-tree/references/ClipSet.d.ts +2 -1
- package/lib/resolvers/content-tree/references/ClipSet.js +2 -2
- package/lib/resolvers/content-tree/references/ClipSet.js.map +1 -1
- package/lib/resolvers/content-tree/references/RawImage.js +1 -1
- package/lib/resolvers/content-tree/references/RawImage.js.map +1 -1
- package/package.json +1 -1
- package/src/datasources/origami-image.ts +3 -3
- package/src/datasources/url-management.test.ts +126 -0
- package/src/datasources/url-management.ts +48 -8
- package/src/generated/index.ts +11 -11
- package/src/helpers/imageService.ts +1 -1
- package/src/index.ts +1 -1
- package/src/model/Clip.test.ts +164 -145
- package/src/model/Clip.ts +7 -3
- package/src/model/Concept.ts +8 -2
- package/src/model/Content.ts +6 -1
- package/src/model/FlourishSource.ts +3 -6
- package/src/model/Image.test.ts +8 -10
- package/src/model/Image.ts +1 -1
- package/src/model/LeadFlourish.ts +1 -1
- package/src/model/Person.test.ts +2 -2
- package/src/model/Person.ts +1 -1
- package/src/model/Picture.test.ts +4 -2
- package/src/model/RichText.test.ts +9 -9
- package/src/model/Topper.test.ts +4 -2
- package/src/model/Topper.ts +1 -1
- package/src/model/__snapshots__/Byline.test.ts.snap +99 -99
- package/src/model/__snapshots__/RichText.test.ts.snap +305 -305
- package/src/resolvers/content-tree/bodyXMLToTree.test.ts +176 -176
- package/src/resolvers/content-tree/references/ClipSet.ts +3 -2
- package/src/resolvers/content-tree/references/RawImage.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/typedefs/image.graphql +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.14.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-schema-v3.13.0...cp-content-pipeline-schema-v3.14.0) (2025-09-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* log specific operational errors for url management call sites ([ee36423](https://github.com/Financial-Times/cp-content-pipeline/commit/ee364235fa59dab9a229fea79da72881c3913494))
|
|
9
|
+
* migrate image service to v3, remove v2 instances and update tests ([979b397](https://github.com/Financial-Times/cp-content-pipeline/commit/979b3974731a7774ea98df48a576b5a799db2695))
|
|
10
|
+
* remove invalid bizop system codes fallback ([854a4a2](https://github.com/Financial-Times/cp-content-pipeline/commit/854a4a28375fd58f5baf736671ee7e7f8ed5868c))
|
|
11
|
+
* remove system code fallback and update tests ([f03151f](https://github.com/Financial-Times/cp-content-pipeline/commit/f03151fc22c3e627f1e2f57021555261131976c6))
|
|
12
|
+
* update base URL and system code in the origami-image-datasource ([4100191](https://github.com/Financial-Times/cp-content-pipeline/commit/4100191e11894ee73ed4020e64be4eb55b2b3a50))
|
|
13
|
+
* update source to cp-content-pipeline-api ([d62f3ca](https://github.com/Financial-Times/cp-content-pipeline/commit/d62f3ca55f84690f2b1bb0939078c4209cf083b6))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* don't memoize or cache url management error responses ([1aec5a3](https://github.com/Financial-Times/cp-content-pipeline/commit/1aec5a3e4cf0a1bb0d06926faccb7d4735b27d32))
|
|
19
|
+
* revert "migrate image service to v3, remove v2 instances and update tests" ([e08a16e](https://github.com/Financial-Times/cp-content-pipeline/commit/e08a16e4da7a1ee77daa0b45e4136e9a5c4a547e))
|
|
20
|
+
* revert "remove invalid bizop system codes fallback" ([3d3ed55](https://github.com/Financial-Times/cp-content-pipeline/commit/3d3ed557e5d0614a55b496463c02ea8932038fb0))
|
|
21
|
+
* revert "remove system code fallback and update tests" ([7646db5](https://github.com/Financial-Times/cp-content-pipeline/commit/7646db5d50e859aa28c49981b303b122a42b59aa))
|
|
22
|
+
* revert "update source to cp-content-pipeline-api" ([fa2e665](https://github.com/Financial-Times/cp-content-pipeline/commit/fa2e665f91192d2bf3885e588844178bdeaf7a3d))
|
|
23
|
+
* wrap errors from n-url-management-read-client in operational errors ([4773dd6](https://github.com/Financial-Times/cp-content-pipeline/commit/4773dd64c40a79278fda044ec107b32c4477d776))
|
|
24
|
+
|
|
25
|
+
## [3.13.0](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-schema-v3.12.2...cp-content-pipeline-schema-v3.13.0) (2025-09-18)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* migrate image service to v3, remove v2 instances and update tests ([c815bbd](https://github.com/Financial-Times/cp-content-pipeline/commit/c815bbd65d6367f5c2055d0bde4781ca3bb49d9b))
|
|
31
|
+
* remove invalid bizop system codes fallback ([5aa1130](https://github.com/Financial-Times/cp-content-pipeline/commit/5aa113011f71c5ec49669dea3ef2b1810b16c5e5))
|
|
32
|
+
* remove system code fallback and update tests ([e3cea7f](https://github.com/Financial-Times/cp-content-pipeline/commit/e3cea7f191c60c3187e255fec5335723b7c1f2df))
|
|
33
|
+
* update source to cp-content-pipeline-api ([70dbe1f](https://github.com/Financial-Times/cp-content-pipeline/commit/70dbe1f71430148bab1223f51e6c911475503f52))
|
|
34
|
+
|
|
3
35
|
## [3.12.2](https://github.com/Financial-Times/cp-content-pipeline/compare/cp-content-pipeline-schema-v3.12.1...cp-content-pipeline-schema-v3.12.2) (2025-09-16)
|
|
4
36
|
|
|
5
37
|
|
|
@@ -6,9 +6,9 @@ const REQUEST_TIMEOUT = process.env.ORIGAMI_DATASOURCE_REQUEST_TIMEOUT
|
|
|
6
6
|
? parseInt(process.env.ORIGAMI_DATASOURCE_REQUEST_TIMEOUT)
|
|
7
7
|
: 200;
|
|
8
8
|
class OrigamiImageDataSource extends instrumented_1.InstrumentedRESTDataSource {
|
|
9
|
-
baseURL = 'https://
|
|
9
|
+
baseURL = 'https://images.ft.com/v3/image/';
|
|
10
10
|
get backendSystemCode() {
|
|
11
|
-
return '
|
|
11
|
+
return 'image-service';
|
|
12
12
|
}
|
|
13
13
|
imageMetadataCacheTTL = process.env.IMAGE_METADATA_CACHE_TTL
|
|
14
14
|
? parseInt(process.env.IMAGE_METADATA_CACHE_TTL)
|
|
@@ -21,7 +21,7 @@ class OrigamiImageDataSource extends instrumented_1.InstrumentedRESTDataSource {
|
|
|
21
21
|
return { ttl: this.imageMetadataCacheTTL };
|
|
22
22
|
}
|
|
23
23
|
async getImageMetadata(url) {
|
|
24
|
-
const imageMetadata = await this.get(`
|
|
24
|
+
const imageMetadata = await this.get(`metadata/${encodeURIComponent(url)}?source=cp-content-pipeline-api`);
|
|
25
25
|
this.calls.push(url);
|
|
26
26
|
return imageMetadata;
|
|
27
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"origami-image.js","sourceRoot":"","sources":["../../src/datasources/origami-image.ts"],"names":[],"mappings":";;;AAAA,iDAA2D;AAG3D,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,kCAAkC;IACpE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC;IAC1D,CAAC,CAAC,GAAG,CAAA;AAEP,MAAa,sBAAuB,SAAQ,yCAA0B;IACpE,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"origami-image.js","sourceRoot":"","sources":["../../src/datasources/origami-image.ts"],"names":[],"mappings":";;;AAAA,iDAA2D;AAG3D,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,kCAAkC;IACpE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC;IAC1D,CAAC,CAAC,GAAG,CAAA;AAEP,MAAa,sBAAuB,SAAQ,yCAA0B;IACpE,OAAO,GAAG,iCAAiC,CAAA;IAC3C,IAAI,iBAAiB;QACnB,OAAO,eAAe,CAAA;IACxB,CAAC;IAED,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB;QAC1D,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;QAChD,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA,CAAC,SAAS;IAErB,eAAe,CAAC,IAAY,EAAE,OAAyB;QAC9D,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAEpC,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACvD,CAAC;IAES,eAAe;QACvB,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,GAAW;QAEX,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAClC,YAAY,kBAAkB,CAAC,GAAG,CAAC,iCAAiC,CACrE,CAAA;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEpB,OAAO,aAAa,CAAA;IACtB,CAAC;CACF;AA/BD,wDA+BC"}
|
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.URLManagementDataSource = void 0;
|
|
7
7
|
const utils_keyvaluecache_1 = require("@apollo/utils.keyvaluecache");
|
|
8
8
|
const n_url_management_api_read_client_1 = __importDefault(require("@financial-times/n-url-management-api-read-client"));
|
|
9
|
+
const errors_1 = require("@dotcom-reliability-kit/errors");
|
|
10
|
+
const isError_1 = __importDefault(require("../helpers/isError"));
|
|
9
11
|
const CACHE_PREFIX = 'nurlmgmtapi:';
|
|
10
12
|
const DEFAULT_TTL_IN_SECONDS = 60 * 60; // one hour
|
|
11
13
|
class URLManagementDataSource {
|
|
@@ -40,14 +42,50 @@ class URLManagementDataSource {
|
|
|
40
42
|
await this.cache.set(fromURL, fromDynamoDB.toURL, { ttl });
|
|
41
43
|
return fromDynamoDB.toURL;
|
|
42
44
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
try {
|
|
46
|
+
let promise = this.memoizedResults.get(fromURL);
|
|
47
|
+
if (promise) {
|
|
48
|
+
return await promise;
|
|
49
|
+
}
|
|
50
|
+
promise = getVanity();
|
|
51
|
+
this.memoizedResults.set(fromURL, promise);
|
|
52
|
+
this.calls.push(fromURL);
|
|
53
|
+
return await promise;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.memoizedResults.delete(fromURL);
|
|
57
|
+
await this.cache.delete(fromURL);
|
|
58
|
+
if ((0, isError_1.default)(error) &&
|
|
59
|
+
'statusCode' in error &&
|
|
60
|
+
typeof error.statusCode === 'number') {
|
|
61
|
+
const baseErrorOptions = {
|
|
62
|
+
cause: error,
|
|
63
|
+
relatesToSystems: ['next-url-management-db'],
|
|
64
|
+
upstreamStatusCode: error.statusCode,
|
|
65
|
+
};
|
|
66
|
+
if (error.statusCode >= 400 && error.statusCode < 500) {
|
|
67
|
+
throw new errors_1.HttpError({
|
|
68
|
+
code: 'URL_MANAGEMENT_CLIENT_ERROR',
|
|
69
|
+
statusCode: 500,
|
|
70
|
+
...baseErrorOptions,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else if (error.statusCode >= 500 && error.statusCode < 600) {
|
|
74
|
+
throw new errors_1.UpstreamServiceError({
|
|
75
|
+
code: 'URL_MANAGEMENT_SERVER_ERROR',
|
|
76
|
+
...baseErrorOptions,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
throw new errors_1.HttpError({
|
|
80
|
+
code: 'URL_MANAGEMENT_UNKNOWN_ERROR',
|
|
81
|
+
statusCode: 500,
|
|
82
|
+
...baseErrorOptions,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
46
88
|
}
|
|
47
|
-
promise = getVanity();
|
|
48
|
-
this.memoizedResults.set(fromURL, promise);
|
|
49
|
-
this.calls.push(fromURL);
|
|
50
|
-
return promise;
|
|
51
89
|
}
|
|
52
90
|
}
|
|
53
91
|
exports.URLManagementDataSource = URLManagementDataSource;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url-management.js","sourceRoot":"","sources":["../../src/datasources/url-management.ts"],"names":[],"mappings":";;;;;;AAAA,qEAGoC;AAEpC,yHAA2F;
|
|
1
|
+
{"version":3,"file":"url-management.js","sourceRoot":"","sources":["../../src/datasources/url-management.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ const url_management_1 = require("./url-management");
|
|
|
11
11
|
const n_url_management_api_read_client_1 = __importDefault(require("@financial-times/n-url-management-api-read-client"));
|
|
12
12
|
const utils_keyvaluecache_1 = require("@apollo/utils.keyvaluecache");
|
|
13
13
|
const globals_1 = require("@jest/globals");
|
|
14
|
+
const errors_1 = require("@dotcom-reliability-kit/errors");
|
|
14
15
|
const getMock = n_url_management_api_read_client_1.default.get;
|
|
15
16
|
const context = {};
|
|
16
17
|
describe('URL management data source', () => {
|
|
@@ -76,5 +77,101 @@ describe('URL management data source', () => {
|
|
|
76
77
|
expect(different).toEqual('different.url.vanity');
|
|
77
78
|
expect(n_url_management_api_read_client_1.default.get).toHaveBeenCalledTimes(2);
|
|
78
79
|
});
|
|
80
|
+
describe('error handling', () => {
|
|
81
|
+
it('wraps 4xx errors in HttpError', async () => {
|
|
82
|
+
getMock.mockRejectedValueOnce(new errors_1.HttpError({
|
|
83
|
+
statusCode: 400,
|
|
84
|
+
code: 'UnrecognisedClientException',
|
|
85
|
+
}));
|
|
86
|
+
const datasource = new url_management_1.URLManagementDataSource({
|
|
87
|
+
context,
|
|
88
|
+
cache: new utils_keyvaluecache_1.InMemoryLRUCache(),
|
|
89
|
+
});
|
|
90
|
+
await expect(datasource.get('original.url')).rejects
|
|
91
|
+
.toMatchInlineSnapshot(`
|
|
92
|
+
HttpError: "Internal Server Error" {
|
|
93
|
+
"cause": "HttpError: "Bad Request" {
|
|
94
|
+
"cause": null,
|
|
95
|
+
"code": "UNRECOGNISEDCLIENTEXCEPTION",
|
|
96
|
+
"data": {},
|
|
97
|
+
}",
|
|
98
|
+
"code": "URL_MANAGEMENT_CLIENT_ERROR",
|
|
99
|
+
"data": {
|
|
100
|
+
"upstreamStatusCode": 400,
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
`);
|
|
104
|
+
});
|
|
105
|
+
it('wraps 5xx errors in UpstreamError', async () => {
|
|
106
|
+
getMock.mockRejectedValueOnce(new errors_1.HttpError({
|
|
107
|
+
statusCode: 500,
|
|
108
|
+
code: 'InternalServerException',
|
|
109
|
+
}));
|
|
110
|
+
const datasource = new url_management_1.URLManagementDataSource({
|
|
111
|
+
context,
|
|
112
|
+
cache: new utils_keyvaluecache_1.InMemoryLRUCache(),
|
|
113
|
+
});
|
|
114
|
+
await expect(datasource.get('original.url')).rejects
|
|
115
|
+
.toMatchInlineSnapshot(`
|
|
116
|
+
UpstreamServiceError: "Bad Gateway" {
|
|
117
|
+
"cause": "HttpError: "Internal Server Error" {
|
|
118
|
+
"cause": null,
|
|
119
|
+
"code": "INTERNALSERVEREXCEPTION",
|
|
120
|
+
"data": {},
|
|
121
|
+
}",
|
|
122
|
+
"code": "URL_MANAGEMENT_SERVER_ERROR",
|
|
123
|
+
"data": {
|
|
124
|
+
"upstreamStatusCode": 500,
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
`);
|
|
128
|
+
});
|
|
129
|
+
it('wraps other HTTP errors in HttpError', async () => {
|
|
130
|
+
const error = new errors_1.BaseError({
|
|
131
|
+
code: 'SomethingElseException',
|
|
132
|
+
});
|
|
133
|
+
Object.assign(error, {
|
|
134
|
+
// HttpError normalises status codes to the 400-599 range
|
|
135
|
+
statusCode: 137,
|
|
136
|
+
});
|
|
137
|
+
getMock.mockRejectedValueOnce(error);
|
|
138
|
+
const datasource = new url_management_1.URLManagementDataSource({
|
|
139
|
+
context,
|
|
140
|
+
cache: new utils_keyvaluecache_1.InMemoryLRUCache(),
|
|
141
|
+
});
|
|
142
|
+
await expect(datasource.get('original.url')).rejects
|
|
143
|
+
.toMatchInlineSnapshot(`
|
|
144
|
+
HttpError: "Internal Server Error" {
|
|
145
|
+
"cause": "BaseError: "An error occurred" {
|
|
146
|
+
"cause": null,
|
|
147
|
+
"code": "SOMETHINGELSEEXCEPTION",
|
|
148
|
+
"data": {},
|
|
149
|
+
}",
|
|
150
|
+
"code": "URL_MANAGEMENT_UNKNOWN_ERROR",
|
|
151
|
+
"data": {
|
|
152
|
+
"upstreamStatusCode": 137,
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
`);
|
|
156
|
+
});
|
|
157
|
+
it('rethrows unknown errors', async () => {
|
|
158
|
+
getMock.mockRejectedValueOnce('not an error');
|
|
159
|
+
const datasource = new url_management_1.URLManagementDataSource({
|
|
160
|
+
context,
|
|
161
|
+
cache: new utils_keyvaluecache_1.InMemoryLRUCache(),
|
|
162
|
+
});
|
|
163
|
+
await expect(datasource.get('original.url')).rejects.toMatchInlineSnapshot(`"not an error"`);
|
|
164
|
+
});
|
|
165
|
+
it("doesn't cache error responses", async () => {
|
|
166
|
+
getMock.mockRejectedValueOnce(new Error());
|
|
167
|
+
const datasource = new url_management_1.URLManagementDataSource({
|
|
168
|
+
context,
|
|
169
|
+
cache: new utils_keyvaluecache_1.InMemoryLRUCache(),
|
|
170
|
+
});
|
|
171
|
+
await expect(datasource.get('original.url')).rejects.toThrow();
|
|
172
|
+
getMock.mockImplementation((fromURL) => Promise.resolve({ fromURL, toURL: `${fromURL}.vanity`, code: 0 }));
|
|
173
|
+
await expect(datasource.get('original.url')).resolves.toEqual(`original.url.vanity`);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
79
176
|
});
|
|
80
177
|
//# sourceMappingURL=url-management.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url-management.test.js","sourceRoot":"","sources":["../../src/datasources/url-management.test.ts"],"names":[],"mappings":";;;;;AAAA,cAAI,CAAC,IAAI,CAAC,mDAAmD,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,GAAG,EAAE,cAAI,CAAC,EAAE,EAAE;IACd,IAAI,EAAE,cAAI,CAAC,EAAE,EAAE;CAChB,CAAC,CAAC,CAAA;AAEH,qDAA0D;AAC1D,yHAA2F;AAG3F,qEAA8D;AAC9D,2CAAoC;
|
|
1
|
+
{"version":3,"file":"url-management.test.js","sourceRoot":"","sources":["../../src/datasources/url-management.test.ts"],"names":[],"mappings":"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"}
|
package/lib/generated/index.d.ts
CHANGED
|
@@ -781,7 +781,7 @@ export type Image = {
|
|
|
781
781
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
782
782
|
/** The type of the image, eg. 'graphic'. */
|
|
783
783
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
784
|
-
/** The url of the image, eg. 'https://
|
|
784
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
785
785
|
readonly url: Scalars['String']['output'];
|
|
786
786
|
/** The width of the image in pixels. */
|
|
787
787
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -807,7 +807,7 @@ export type ImageDesktop = Image & {
|
|
|
807
807
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
808
808
|
/** The type of the image, eg. 'graphic'. */
|
|
809
809
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
810
|
-
/** The url of the image, eg. 'https://
|
|
810
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
811
811
|
readonly url: Scalars['String']['output'];
|
|
812
812
|
/** The width of the image in pixels. */
|
|
813
813
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -833,7 +833,7 @@ export type ImageLandscape = Image & {
|
|
|
833
833
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
834
834
|
/** The type of the image, eg. 'graphic'. */
|
|
835
835
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
836
|
-
/** The url of the image, eg. 'https://
|
|
836
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
837
837
|
readonly url: Scalars['String']['output'];
|
|
838
838
|
/** The width of the image in pixels. */
|
|
839
839
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -859,7 +859,7 @@ export type ImageMobile = Image & {
|
|
|
859
859
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
860
860
|
/** The type of the image, eg. 'graphic'. */
|
|
861
861
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
862
|
-
/** The url of the image, eg. 'https://
|
|
862
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
863
863
|
readonly url: Scalars['String']['output'];
|
|
864
864
|
/** The width of the image in pixels. */
|
|
865
865
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -885,7 +885,7 @@ export type ImagePortrait = Image & {
|
|
|
885
885
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
886
886
|
/** The type of the image, eg. 'graphic'. */
|
|
887
887
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
888
|
-
/** The url of the image, eg. 'https://
|
|
888
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
889
889
|
readonly url: Scalars['String']['output'];
|
|
890
890
|
/** The width of the image in pixels. */
|
|
891
891
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -903,7 +903,7 @@ export type ImageSet = Reference & {
|
|
|
903
903
|
export type ImageSource = {
|
|
904
904
|
/** The device pixel ratio. DPR is calculated as DPR = Physical Pixels (pixels seen on screen) / Logical Pixels (pixel that can fit in a given space). */
|
|
905
905
|
readonly dpr: Scalars['Int']['output'];
|
|
906
|
-
/** The url of the image source, eg. 'https://
|
|
906
|
+
/** The url of the image source, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
907
907
|
readonly url: Scalars['String']['output'];
|
|
908
908
|
/** The width of the image source in pixels. */
|
|
909
909
|
readonly width: Scalars['Int']['output'];
|
|
@@ -925,7 +925,7 @@ export type ImageSquare = Image & {
|
|
|
925
925
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
926
926
|
/** The type of the image, eg. 'graphic'. */
|
|
927
927
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
928
|
-
/** The url of the image, eg. 'https://
|
|
928
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
929
929
|
readonly url: Scalars['String']['output'];
|
|
930
930
|
/** The width of the image in pixels. */
|
|
931
931
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -951,7 +951,7 @@ export type ImageSquareFtEdit = Image & {
|
|
|
951
951
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
952
952
|
/** The type of the image, eg. 'graphic'. */
|
|
953
953
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
954
|
-
/** The url of the image, eg. 'https://
|
|
954
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
955
955
|
readonly url: Scalars['String']['output'];
|
|
956
956
|
/** The width of the image in pixels. */
|
|
957
957
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -977,7 +977,7 @@ export type ImageStandard = Image & {
|
|
|
977
977
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
978
978
|
/** The type of the image, eg. 'graphic'. */
|
|
979
979
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
980
|
-
/** The url of the image, eg. 'https://
|
|
980
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
981
981
|
readonly url: Scalars['String']['output'];
|
|
982
982
|
/** The width of the image in pixels. */
|
|
983
983
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -1003,7 +1003,7 @@ export type ImageStandardInline = Image & {
|
|
|
1003
1003
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
1004
1004
|
/** The type of the image, eg. 'graphic'. */
|
|
1005
1005
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
1006
|
-
/** The url of the image, eg. 'https://
|
|
1006
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
1007
1007
|
readonly url: Scalars['String']['output'];
|
|
1008
1008
|
/** The width of the image in pixels. */
|
|
1009
1009
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -1029,7 +1029,7 @@ export type ImageWide = Image & {
|
|
|
1029
1029
|
readonly sourceSet: ReadonlyArray<ImageSource>;
|
|
1030
1030
|
/** The type of the image, eg. 'graphic'. */
|
|
1031
1031
|
readonly type?: Maybe<Scalars['ImageType']['output']>;
|
|
1032
|
-
/** The url of the image, eg. 'https://
|
|
1032
|
+
/** The url of the image, eg. 'https://images.ft.com/v3/image/raw/ftcms%3Aimage%3A0e7e7b6e-4e7b-11e9-bde6-79e4b4311f90?source=cp-content-pipeline-api&fit=scale-down&width=700'. */
|
|
1033
1033
|
readonly url: Scalars['String']['output'];
|
|
1034
1034
|
/** The width of the image in pixels. */
|
|
1035
1035
|
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
@@ -7,7 +7,7 @@ const DEFAULT_IMAGE_SERVICE_DPR = 1;
|
|
|
7
7
|
exports.MAX_IMAGE_WIDTH = 3840;
|
|
8
8
|
function imageServiceUrl({ url, id, systemCode, width = DEFAULT_IMAGE_SERVICE_WIDTH, dpr = DEFAULT_IMAGE_SERVICE_DPR, }) {
|
|
9
9
|
const imageSource = encodeURIComponent(id ? `ftcms:${id}` : url);
|
|
10
|
-
const imageServiceUrl = new URL(`https://
|
|
10
|
+
const imageServiceUrl = new URL(`https://images.ft.com/v3/image/raw/${imageSource}`);
|
|
11
11
|
const adjustedWidth = width > exports.MAX_IMAGE_WIDTH ? exports.MAX_IMAGE_WIDTH : width;
|
|
12
12
|
imageServiceUrl.searchParams.set('source', systemCode);
|
|
13
13
|
imageServiceUrl.searchParams.set('fit', 'scale-down');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageService.js","sourceRoot":"","sources":["../../src/helpers/imageService.ts"],"names":[],"mappings":";;;AAYA,kCAqBC;AAjCD,MAAM,2BAA2B,GAAG,GAAG,CAAA;AACvC,MAAM,yBAAyB,GAAG,CAAC,CAAA;AACtB,QAAA,eAAe,GAAG,IAAI,CAAA;AAUnC,SAAwB,eAAe,CAAC,EACtC,GAAG,EACH,EAAE,EACF,UAAU,EACV,KAAK,GAAG,2BAA2B,EACnC,GAAG,GAAG,yBAAyB,GACN;IACzB,MAAM,WAAW,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAChE,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,
|
|
1
|
+
{"version":3,"file":"imageService.js","sourceRoot":"","sources":["../../src/helpers/imageService.ts"],"names":[],"mappings":";;;AAYA,kCAqBC;AAjCD,MAAM,2BAA2B,GAAG,GAAG,CAAA;AACvC,MAAM,yBAAyB,GAAG,CAAC,CAAA;AACtB,QAAA,eAAe,GAAG,IAAI,CAAA;AAUnC,SAAwB,eAAe,CAAC,EACtC,GAAG,EACH,EAAE,EACF,UAAU,EACV,KAAK,GAAG,2BAA2B,EACnC,GAAG,GAAG,yBAAyB,GACN;IACzB,MAAM,WAAW,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAChE,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,sCAAsC,WAAW,EAAE,CACpD,CAAA;IAED,MAAM,aAAa,GAAG,KAAK,GAAG,uBAAe,CAAC,CAAC,CAAC,uBAAe,CAAC,CAAC,CAAC,KAAK,CAAA;IAEvE,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACtD,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;IACrD,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IACtD,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAA;IACnE,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEvD,OAAO,eAAe,CAAC,IAAI,CAAA;AAC7B,CAAC"}
|
package/lib/index.d.ts
CHANGED
package/lib/model/Clip.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Clip as ClipMetadata } from './schemas/capi/internal-content';
|
|
2
2
|
import { LiteralUnionScalarValues } from '../resolvers/literal-union';
|
|
3
3
|
import { ClipFormat } from '../resolvers/scalars';
|
|
4
|
+
import { QueryContext } from '..';
|
|
4
5
|
type ClipSource = {
|
|
5
6
|
binaryUrl: string;
|
|
6
7
|
mediaType: string;
|
|
@@ -19,8 +20,9 @@ interface ClipVideo {
|
|
|
19
20
|
}
|
|
20
21
|
export declare class Clip implements ClipVideo {
|
|
21
22
|
private clip;
|
|
23
|
+
private context;
|
|
22
24
|
private layout?;
|
|
23
|
-
constructor(clip: ClipMetadata, layout?: string | undefined);
|
|
25
|
+
constructor(clip: ClipMetadata, context: QueryContext, layout?: string | undefined);
|
|
24
26
|
type(): string;
|
|
25
27
|
id(): string;
|
|
26
28
|
format(): LiteralUnionScalarValues<typeof ClipFormat>;
|
package/lib/model/Clip.js
CHANGED
|
@@ -10,9 +10,11 @@ const scalars_1 = require("../resolvers/scalars");
|
|
|
10
10
|
const imageService_1 = __importDefault(require("../helpers/imageService"));
|
|
11
11
|
class Clip {
|
|
12
12
|
clip;
|
|
13
|
+
context;
|
|
13
14
|
layout;
|
|
14
|
-
constructor(clip, layout) {
|
|
15
|
+
constructor(clip, context, layout) {
|
|
15
16
|
this.clip = clip;
|
|
17
|
+
this.context = context;
|
|
16
18
|
this.layout = layout;
|
|
17
19
|
}
|
|
18
20
|
type() {
|
|
@@ -60,7 +62,7 @@ class Clip {
|
|
|
60
62
|
return url
|
|
61
63
|
? (0, imageService_1.default)({
|
|
62
64
|
url,
|
|
63
|
-
systemCode:
|
|
65
|
+
systemCode: this.context.systemCode,
|
|
64
66
|
width: this.layout && mapSizes[this.layout] ? mapSizes[this.layout] : 700,
|
|
65
67
|
})
|
|
66
68
|
: '';
|
package/lib/model/Clip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Clip.js","sourceRoot":"","sources":["../../src/model/Clip.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAiD;AAEjD,8DAGmC;AACnC,kDAAiD;AACjD,2EAAqD;
|
|
1
|
+
{"version":3,"file":"Clip.js","sourceRoot":"","sources":["../../src/model/Clip.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAiD;AAEjD,8DAGmC;AACnC,kDAAiD;AACjD,2EAAqD;AAqBrD,MAAa,IAAI;IAEL;IACA;IACA;IAHV,YACU,IAAkB,EAClB,OAAqB,EACrB,MAAe;QAFf,SAAI,GAAJ,IAAI,CAAc;QAClB,YAAO,GAAP,OAAO,CAAc;QACrB,WAAM,GAAN,MAAM,CAAS;IACtB,CAAC;IACJ,IAAI;QACF,OAAO,MAAM,CAAA;IACf,CAAC;IAED,EAAE;QACA,MAAM,IAAI,GAAG,IAAA,sBAAW,EAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACtC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,qCAAqC,CAAC,CAAA;QACvE,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;YAEnC,IAAI,UAAU,KAAK,gBAAgB,EAAE,CAAC;gBACpC,OAAO,iBAAiB,CAAA;YAC1B,CAAC;YAED,IAAI,IAAA,sCAAsB,EAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChE,OAAO,UAAU,CAAA;YACnB,CAAC;QACH,CAAC;QAED,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAED,UAAU;QACR,kKAAkK;QAClK,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC5D,IAAI,CAAC,CAAC,SAAS,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;gBAC/D,OAAO,CAAC,CAAC,CAAA;YACX,CAAC;YACD,IAAI,CAAC,CAAC,SAAS,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;gBAC/D,OAAO,CAAC,CAAA;YACV,CAAC;YACD,OAAO,CAAC,CAAA;QACV,CAAC,CAAC,CAAA;QACF,OAAO,UAA0B,CAAA;IACnC,CAAC;IAED,MAAM;QACJ,MAAM,QAAQ,GAEV;YACF,SAAS,EAAE,GAAG;YACd,UAAU,EAAE,GAAG;YACf,WAAW,EAAE,IAAI;SAClB,CAAA;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAA;QACnD,OAAO,GAAG;YACR,CAAC,CAAC,IAAA,sBAAe,EAAC;gBACd,GAAG;gBACH,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;gBACnC,KAAK,EACH,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG;aACrE,CAAC;YACJ,CAAC,CAAC,EAAE,CAAA;IACR,CAAC;CACF;AAnED,oBAmEC"}
|
package/lib/model/Clip.test.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const Clip_1 = require("./Clip");
|
|
4
|
+
const mockContext = {
|
|
5
|
+
systemCode: 'cp-content-pipeline',
|
|
6
|
+
};
|
|
4
7
|
describe('Clip', () => {
|
|
5
8
|
describe('poster', () => {
|
|
6
9
|
it('uses the Origami Image Service when a url is provided', () => {
|
|
7
10
|
const clip = new Clip_1.Clip({
|
|
8
11
|
id: 'http://api.ft.com/things/1234',
|
|
9
|
-
type:
|
|
10
|
-
dataSource: [
|
|
11
|
-
{},
|
|
12
|
-
],
|
|
12
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
13
|
+
dataSource: [{}],
|
|
13
14
|
poster: {
|
|
14
15
|
id: 'http://api.ft.com/things/1234',
|
|
15
16
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -21,17 +22,15 @@ describe('Clip', () => {
|
|
|
21
22
|
},
|
|
22
23
|
],
|
|
23
24
|
},
|
|
24
|
-
});
|
|
25
|
-
expect(clip.poster()).toContain('https://
|
|
25
|
+
}, mockContext);
|
|
26
|
+
expect(clip.poster()).toContain('https://images.ft.com/v3/image/raw/');
|
|
26
27
|
expect(clip.poster()).toContain('source=cp-content-pipeline&fit=scale-down&quality=highest');
|
|
27
28
|
});
|
|
28
29
|
it('returns an empty string if an image url is not provided', () => {
|
|
29
30
|
const clip = new Clip_1.Clip({
|
|
30
31
|
id: 'http://api.ft.com/things/1234',
|
|
31
|
-
type:
|
|
32
|
-
dataSource: [
|
|
33
|
-
{},
|
|
34
|
-
],
|
|
32
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
33
|
+
dataSource: [{}],
|
|
35
34
|
poster: {
|
|
36
35
|
id: 'http://api.ft.com/things/1234',
|
|
37
36
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -43,16 +42,14 @@ describe('Clip', () => {
|
|
|
43
42
|
},
|
|
44
43
|
],
|
|
45
44
|
},
|
|
46
|
-
});
|
|
45
|
+
}, mockContext);
|
|
47
46
|
expect(clip.poster()).toEqual('');
|
|
48
47
|
});
|
|
49
48
|
it('uses a default width if a layout is not provided', () => {
|
|
50
49
|
const clip = new Clip_1.Clip({
|
|
51
50
|
id: 'http://api.ft.com/things/1234',
|
|
52
|
-
type:
|
|
53
|
-
dataSource: [
|
|
54
|
-
{},
|
|
55
|
-
],
|
|
51
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
52
|
+
dataSource: [{}],
|
|
56
53
|
poster: {
|
|
57
54
|
id: 'http://api.ft.com/things/1234',
|
|
58
55
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -64,16 +61,14 @@ describe('Clip', () => {
|
|
|
64
61
|
},
|
|
65
62
|
],
|
|
66
63
|
},
|
|
67
|
-
});
|
|
64
|
+
}, mockContext);
|
|
68
65
|
expect(clip.poster()).toContain('width=700');
|
|
69
66
|
});
|
|
70
67
|
it('uses a default width if a layout is not supported', () => {
|
|
71
68
|
const clip = new Clip_1.Clip({
|
|
72
69
|
id: 'http://api.ft.com/things/1234',
|
|
73
|
-
type:
|
|
74
|
-
dataSource: [
|
|
75
|
-
{},
|
|
76
|
-
],
|
|
70
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
71
|
+
dataSource: [{}],
|
|
77
72
|
poster: {
|
|
78
73
|
id: 'http://api.ft.com/things/1234',
|
|
79
74
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -85,16 +80,14 @@ describe('Clip', () => {
|
|
|
85
80
|
},
|
|
86
81
|
],
|
|
87
82
|
},
|
|
88
|
-
}, 'I-dont-exist');
|
|
89
|
-
expect(clip.poster()).toEqual('https://
|
|
83
|
+
}, mockContext, 'I-dont-exist');
|
|
84
|
+
expect(clip.poster()).toEqual('https://images.ft.com/v3/image/raw/http%3A%2F%2Fvideo.ft.com%2F1234.jpg?source=cp-content-pipeline&fit=scale-down&quality=highest&width=700&dpr=1');
|
|
90
85
|
});
|
|
91
86
|
it('generates an image with the appropriate width for a `in-line` layout', () => {
|
|
92
87
|
const clip = new Clip_1.Clip({
|
|
93
88
|
id: 'http://api.ft.com/things/1234',
|
|
94
|
-
type:
|
|
95
|
-
dataSource: [
|
|
96
|
-
{},
|
|
97
|
-
],
|
|
89
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
90
|
+
dataSource: [{}],
|
|
98
91
|
poster: {
|
|
99
92
|
id: 'http://api.ft.com/things/1234',
|
|
100
93
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -106,16 +99,14 @@ describe('Clip', () => {
|
|
|
106
99
|
},
|
|
107
100
|
],
|
|
108
101
|
},
|
|
109
|
-
}, 'in-line');
|
|
102
|
+
}, mockContext, 'in-line');
|
|
110
103
|
expect(clip.poster()).toContain('width=700');
|
|
111
104
|
});
|
|
112
105
|
it('generates an image with the appropriate width for a `mid-grid` layout', () => {
|
|
113
106
|
const clip = new Clip_1.Clip({
|
|
114
107
|
id: 'http://api.ft.com/things/1234',
|
|
115
|
-
type:
|
|
116
|
-
dataSource: [
|
|
117
|
-
{},
|
|
118
|
-
],
|
|
108
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
109
|
+
dataSource: [{}],
|
|
119
110
|
poster: {
|
|
120
111
|
id: 'http://api.ft.com/things/1234',
|
|
121
112
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -127,16 +118,14 @@ describe('Clip', () => {
|
|
|
127
118
|
},
|
|
128
119
|
],
|
|
129
120
|
},
|
|
130
|
-
}, 'mid-grid');
|
|
121
|
+
}, mockContext, 'mid-grid');
|
|
131
122
|
expect(clip.poster()).toContain('width=900');
|
|
132
123
|
});
|
|
133
124
|
it('generates an image with the appropriate width for a `full-grid` layout', () => {
|
|
134
125
|
const clip = new Clip_1.Clip({
|
|
135
126
|
id: 'http://api.ft.com/things/1234',
|
|
136
|
-
type:
|
|
137
|
-
dataSource: [
|
|
138
|
-
{},
|
|
139
|
-
],
|
|
127
|
+
type: 'http://www.ft.com/ontology/content/Clip',
|
|
128
|
+
dataSource: [{}],
|
|
140
129
|
poster: {
|
|
141
130
|
id: 'http://api.ft.com/things/1234',
|
|
142
131
|
type: 'http://www.ft.com/ontology/content/ImageSet',
|
|
@@ -148,7 +137,7 @@ describe('Clip', () => {
|
|
|
148
137
|
},
|
|
149
138
|
],
|
|
150
139
|
},
|
|
151
|
-
}, 'full-grid');
|
|
140
|
+
}, mockContext, 'full-grid');
|
|
152
141
|
expect(clip.poster()).toContain('width=1200');
|
|
153
142
|
});
|
|
154
143
|
});
|