Skip to content

Commit 54e0e1d

Browse files
committed
Cap feed entries with configurable limit
1 parent 891151a commit 54e0e1d

4 files changed

Lines changed: 38 additions & 5 deletions

File tree

config/default.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
},
4848
"dataset": {
4949
"publishingSchedule": "30 8 * * MON"
50+
},
51+
"collection-api": {
52+
"feed": {
53+
"limit": 100
54+
}
5055
}
5156
}
5257
}

config/test.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@
4747
},
4848
"collection-api": {
4949
"port": 3000,
50-
"basePath": "/collection-api"
50+
"basePath": "/collection-api",
51+
"feed": {
52+
"limit": 3
53+
}
5154
}
5255
}
5356
}

src/collection-api/routes/feed.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import config from 'config';
12
import express from 'express';
23
import { js2xml } from 'xml-js';
34

@@ -12,6 +13,14 @@ const TAG_AUTHORITY = 'opentermsarchive.org,2026';
1213
const FEED_AUTHOR_NAME = 'OTA-Bot';
1314
const DEFAULT_LIMIT = 100;
1415

16+
function getFeedLimit() {
17+
if (config.has('@opentermsarchive/engine.collection-api.feed.limit')) {
18+
return config.get('@opentermsarchive/engine.collection-api.feed.limit');
19+
}
20+
21+
return DEFAULT_LIMIT;
22+
}
23+
1524
const RECORD_TYPES = {
1625
firstRecord: 'First record',
1726
technicalUpgrade: 'Technical upgrade',
@@ -129,7 +138,7 @@ export default function feedRouter(services) {
129138
* - application/atom+xml
130139
* responses:
131140
* 200:
132-
* description: An Atom 1.0 feed listing the latest version records, newest first.
141+
* description: An Atom 1.0 feed listing the latest version records, newest first. The maximum number of entries is server-configured.
133142
* content:
134143
* application/atom+xml:
135144
* schema:
@@ -141,7 +150,7 @@ export default function feedRouter(services) {
141150
const selfHref = `${baseUrl}/feed`;
142151
const feedId = `tag:${TAG_AUTHORITY}:feed:${collection.metadata?.id}`;
143152

144-
const versions = await versionsRepository.findRecent(DEFAULT_LIMIT);
153+
const versions = await versionsRepository.findRecent(getFeedLimit());
145154
const document = buildFeedDocument({ collection, selfHref, feedId, versions, baseUrl });
146155

147156
sendAtom(res, render(document));
@@ -184,7 +193,7 @@ export default function feedRouter(services) {
184193
const selfHref = `${baseUrl}/feed/${encodeURIComponent(service.id)}`;
185194
const feedId = `tag:${TAG_AUTHORITY}:feed:${collection.metadata?.id}:${service.id}`;
186195

187-
const versions = await versionsRepository.findRecent(DEFAULT_LIMIT, { serviceId: service.id });
196+
const versions = await versionsRepository.findRecent(getFeedLimit(), { serviceId: service.id });
188197
const document = buildFeedDocument({ collection, selfHref, feedId, versions, baseUrl });
189198

190199
return sendAtom(res, render(document));
@@ -239,7 +248,7 @@ export default function feedRouter(services) {
239248
const selfHref = `${baseUrl}/feed/${encodeURIComponent(service.id)}/${encodeURIComponent(termsType)}`;
240249
const feedId = `tag:${TAG_AUTHORITY}:feed:${collection.metadata?.id}:${service.id}:${termsType}`;
241250

242-
const versions = await versionsRepository.findRecent(DEFAULT_LIMIT, { serviceId: service.id, termsType });
251+
const versions = await versionsRepository.findRecent(getFeedLimit(), { serviceId: service.id, termsType });
243252
const document = buildFeedDocument({ collection, selfHref, feedId, versions, baseUrl });
244253

245254
return sendAtom(res, render(document));

src/collection-api/routes/feed.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ describe('Feed API', () => {
132132

133133
after(() => repository.removeAll());
134134

135+
it('lists one entry per saved version up to the configured limit', () => {
136+
const limit = config.get('@opentermsarchive/engine.collection-api.feed.limit');
137+
const entries = response.text.match(/<entry>/g) || [];
138+
139+
expect(entries).to.have.length(Math.min(4, limit));
140+
});
141+
135142
it('orders entries newest-first', () => {
136143
const updates = [...response.text.matchAll(/<entry>[\s\S]*?<updated>([^<]+)<\/updated>[\s\S]*?<\/entry>/g)].map(match => match[1]);
137144

@@ -227,6 +234,15 @@ describe('Feed API', () => {
227234
expect(entry).to.match(/term="Technical upgrade"/);
228235
});
229236
});
237+
238+
describe('configurable limit', () => {
239+
it('returns at most the configured number of entries', () => {
240+
const limit = config.get('@opentermsarchive/engine.collection-api.feed.limit');
241+
const entries = response.text.match(/<entry>/g) || [];
242+
243+
expect(entries.length).to.be.at.most(limit);
244+
});
245+
});
230246
});
231247

232248
describe('GET /feed/:serviceId', () => {

0 commit comments

Comments
 (0)