@opentermsarchive/engine 0.26.1 → 0.27.1
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/README.md +1 -3
- package/bin/ota-track.js +3 -3
- package/bin/ota-validate.js +2 -2
- package/bin/ota.js +1 -1
- package/config/default.json +1 -1
- package/package.json +3 -4
- package/scripts/dataset/export/index.js +4 -4
- package/scripts/dataset/export/index.test.js +11 -17
- package/scripts/declarations/lint/index.mocha.js +1 -1
- package/scripts/declarations/utils/index.js +12 -12
- package/scripts/declarations/validate/definitions.js +1 -1
- package/scripts/declarations/validate/index.mocha.js +30 -34
- package/scripts/declarations/validate/service.history.schema.js +11 -11
- package/scripts/declarations/validate/service.schema.js +13 -13
- package/scripts/history/migrate-services.js +4 -4
- package/scripts/history/update-to-full-hash.js +2 -2
- package/scripts/import/index.js +14 -14
- package/scripts/rewrite/rewrite-snapshots.js +3 -3
- package/scripts/rewrite/rewrite-versions.js +14 -14
- package/scripts/utils/renamer/README.md +3 -3
- package/scripts/utils/renamer/index.js +13 -13
- package/src/archivist/errors.js +1 -1
- package/src/archivist/extract/exports.js +3 -0
- package/src/archivist/{filter → extract}/index.js +23 -27
- package/src/archivist/extract/index.test.js +516 -0
- package/src/archivist/index.js +101 -140
- package/src/archivist/index.test.js +178 -166
- package/src/archivist/recorder/index.js +11 -55
- package/src/archivist/recorder/index.test.js +310 -356
- package/src/archivist/recorder/record.js +18 -7
- package/src/archivist/recorder/repositories/git/dataMapper.js +41 -31
- package/src/archivist/recorder/repositories/git/index.js +11 -15
- package/src/archivist/recorder/repositories/git/index.test.js +1058 -463
- package/src/archivist/recorder/repositories/interface.js +8 -6
- package/src/archivist/recorder/repositories/mongo/dataMapper.js +21 -14
- package/src/archivist/recorder/repositories/mongo/index.js +8 -8
- package/src/archivist/recorder/repositories/mongo/index.test.js +898 -479
- package/src/archivist/recorder/snapshot.js +5 -0
- package/src/archivist/recorder/snapshot.test.js +65 -0
- package/src/archivist/recorder/version.js +14 -0
- package/src/archivist/recorder/version.test.js +65 -0
- package/src/archivist/services/index.js +60 -51
- package/src/archivist/services/index.test.js +63 -83
- package/src/archivist/services/service.js +26 -22
- package/src/archivist/services/service.test.js +46 -68
- package/src/archivist/services/{pageDeclaration.js → sourceDocument.js} +11 -9
- package/src/archivist/services/{pageDeclaration.test.js → sourceDocument.test.js} +21 -21
- package/src/archivist/services/terms.js +26 -0
- package/src/archivist/services/{documentDeclaration.test.js → terms.test.js} +15 -15
- package/src/exports.js +2 -2
- package/src/index.js +16 -13
- package/src/logger/index.js +35 -36
- package/src/notifier/index.js +8 -8
- package/src/tracker/index.js +6 -6
- package/src/archivist/filter/exports.js +0 -3
- package/src/archivist/filter/index.test.js +0 -564
- package/src/archivist/recorder/record.test.js +0 -91
- package/src/archivist/services/documentDeclaration.js +0 -26
- /package/scripts/utils/renamer/rules/{documentTypes.json → termsTypes.json} +0 -0
- /package/scripts/utils/renamer/rules/{documentTypesByService.json → termsTypesByService.json} +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import chai from 'chai';
|
|
2
|
+
|
|
3
|
+
import Snapshot from './snapshot.js';
|
|
4
|
+
|
|
5
|
+
const { expect } = chai;
|
|
6
|
+
|
|
7
|
+
describe('Snapshot', () => {
|
|
8
|
+
let subject;
|
|
9
|
+
|
|
10
|
+
describe('#validate', () => {
|
|
11
|
+
Snapshot.REQUIRED_PARAMS.forEach(requiredParam => {
|
|
12
|
+
const validParamsExceptTheOneTested = Snapshot.REQUIRED_PARAMS.filter(paramName => paramName != requiredParam).reduce(
|
|
13
|
+
(accumulator, currentValue) => {
|
|
14
|
+
accumulator[currentValue] = 'non null value';
|
|
15
|
+
|
|
16
|
+
return accumulator;
|
|
17
|
+
},
|
|
18
|
+
{},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
describe(`"${requiredParam}"`, () => {
|
|
22
|
+
context('when missing', () => {
|
|
23
|
+
it('throws an error', async () => {
|
|
24
|
+
subject = new Snapshot({ ...validParamsExceptTheOneTested });
|
|
25
|
+
expect(subject.validate.bind(subject)).to.throw(RegExp(requiredParam));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
context('when null', () => {
|
|
30
|
+
it('throws an error', async () => {
|
|
31
|
+
subject = new Snapshot({ ...validParamsExceptTheOneTested, [requiredParam]: null });
|
|
32
|
+
expect(subject.validate.bind(subject)).to.throw(RegExp(requiredParam));
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('Content access', () => {
|
|
40
|
+
const recordParams = {
|
|
41
|
+
serviceId: 'ServiceA',
|
|
42
|
+
termsType: 'Terms of Service',
|
|
43
|
+
mimeType: 'text/html',
|
|
44
|
+
fetchDate: new Date('2000-01-01T12:00:00.000Z'),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
before(async () => {
|
|
48
|
+
subject = new Snapshot(recordParams);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
context('when it is neither defined nor loaded', () => {
|
|
52
|
+
it('throws an error explaining how to recover', async () => {
|
|
53
|
+
try {
|
|
54
|
+
console.log(subject.content);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
expect(e).to.be.an('error');
|
|
57
|
+
expect(e.message).to.have.string('set the content or use Repository#loadRecordContent');
|
|
58
|
+
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
expect.fail('No error was thrown');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import mime from 'mime';
|
|
2
|
+
|
|
3
|
+
import Record from './record.js';
|
|
4
|
+
|
|
5
|
+
export default class Version extends Record {
|
|
6
|
+
static REQUIRED_PARAMS = Object.freeze([ ...Record.REQUIRED_PARAMS, 'snapshotIds' ]);
|
|
7
|
+
|
|
8
|
+
static SOURCE_DOCUMENTS_SEPARATOR = '\n\n';
|
|
9
|
+
|
|
10
|
+
constructor(params) {
|
|
11
|
+
super(params);
|
|
12
|
+
this.mimeType = mime.getType('markdown');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import chai from 'chai';
|
|
2
|
+
|
|
3
|
+
import Version from './version.js';
|
|
4
|
+
|
|
5
|
+
const { expect } = chai;
|
|
6
|
+
|
|
7
|
+
describe('Version', () => {
|
|
8
|
+
let subject;
|
|
9
|
+
|
|
10
|
+
describe('#validate', () => {
|
|
11
|
+
Version.REQUIRED_PARAMS.forEach(requiredParam => {
|
|
12
|
+
const validParamsExceptTheOneTested = Version.REQUIRED_PARAMS.filter(paramName => paramName != requiredParam).reduce(
|
|
13
|
+
(accumulator, currentValue) => {
|
|
14
|
+
accumulator[currentValue] = 'non null value';
|
|
15
|
+
|
|
16
|
+
return accumulator;
|
|
17
|
+
},
|
|
18
|
+
{},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
describe(`"${requiredParam}"`, () => {
|
|
22
|
+
context('when missing', () => {
|
|
23
|
+
it('throws an error', async () => {
|
|
24
|
+
subject = new Version({ ...validParamsExceptTheOneTested });
|
|
25
|
+
expect(subject.validate.bind(subject)).to.throw(RegExp(requiredParam));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
context('when null', () => {
|
|
30
|
+
it('throws an error', async () => {
|
|
31
|
+
subject = new Version({ ...validParamsExceptTheOneTested, [requiredParam]: null });
|
|
32
|
+
expect(subject.validate.bind(subject)).to.throw(RegExp(requiredParam));
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('Content access', () => {
|
|
40
|
+
const recordParams = {
|
|
41
|
+
serviceId: 'ServiceA',
|
|
42
|
+
termsType: 'Terms of Service',
|
|
43
|
+
fetchDate: new Date('2000-01-01T12:00:00.000Z'),
|
|
44
|
+
snapshotIds: ['dd263f270b3065e1c18201b49ab898474b357566'],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
before(async () => {
|
|
48
|
+
subject = new Version(recordParams);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
context('when it is neither defined nor loaded', () => {
|
|
52
|
+
it('throws an error explaining how to recover', async () => {
|
|
53
|
+
try {
|
|
54
|
+
console.log(subject.content);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
expect(e).to.be.an('error');
|
|
57
|
+
expect(e.message).to.have.string('set the content or use Repository#loadRecordContent');
|
|
58
|
+
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
expect.fail('No error was thrown');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -2,18 +2,15 @@ import fsApi from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { pathToFileURL } from 'url';
|
|
4
4
|
|
|
5
|
-
import TERMS_TYPES from '@opentermsarchive/terms-types';
|
|
6
5
|
import config from 'config';
|
|
7
6
|
|
|
8
|
-
import DocumentDeclaration from './documentDeclaration.js';
|
|
9
|
-
import PageDeclaration from './pageDeclaration.js';
|
|
10
7
|
import Service from './service.js';
|
|
8
|
+
import SourceDocument from './sourceDocument.js';
|
|
9
|
+
import Terms from './terms.js';
|
|
11
10
|
|
|
12
11
|
const fs = fsApi.promises;
|
|
13
12
|
const declarationsPath = path.resolve(process.cwd(), config.get('services.declarationsPath'));
|
|
14
13
|
|
|
15
|
-
export const DOCUMENT_TYPES = TERMS_TYPES;
|
|
16
|
-
|
|
17
14
|
export async function load(servicesIdsToLoad = []) {
|
|
18
15
|
let servicesIds = await getDeclaredServicesIds();
|
|
19
16
|
|
|
@@ -24,11 +21,11 @@ export async function load(servicesIdsToLoad = []) {
|
|
|
24
21
|
const services = {};
|
|
25
22
|
|
|
26
23
|
await Promise.all(servicesIds.map(async serviceId => {
|
|
27
|
-
const { name, documents:
|
|
24
|
+
const { name, documents: terms } = await loadServiceDeclaration(serviceId);
|
|
28
25
|
|
|
29
26
|
const service = new Service({ id: serviceId, name });
|
|
30
27
|
|
|
31
|
-
await Promise.all(Object.keys(
|
|
28
|
+
await Promise.all(Object.keys(terms).map(termsType => loadServiceDocument(service, termsType, terms[termsType])));
|
|
32
29
|
|
|
33
30
|
services[serviceId] = service;
|
|
34
31
|
}));
|
|
@@ -58,32 +55,38 @@ async function loadServiceFilters(serviceId, filterNames) {
|
|
|
58
55
|
return filterNames.map(filterName => serviceFilters[filterName]);
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
async function loadServiceDocument(service,
|
|
62
|
-
const { filter: filterNames, fetch: location, executeClientScripts, select: contentSelectors, remove:
|
|
58
|
+
async function loadServiceDocument(service, termsType, termsTypeDeclaration) {
|
|
59
|
+
const { filter: filterNames, fetch: location, executeClientScripts, select: contentSelectors, remove: insignificantContentSelectors, combine } = termsTypeDeclaration;
|
|
63
60
|
|
|
64
|
-
const
|
|
61
|
+
const sourceDocuments = [];
|
|
65
62
|
|
|
66
63
|
const filters = await loadServiceFilters(service.id, filterNames);
|
|
67
64
|
|
|
68
65
|
if (!combine) {
|
|
69
|
-
|
|
66
|
+
sourceDocuments.push(new SourceDocument({ location, executeClientScripts, contentSelectors, insignificantContentSelectors, filters }));
|
|
70
67
|
} else {
|
|
71
|
-
for (const
|
|
72
|
-
const {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
68
|
+
for (const sourceDocument of combine) {
|
|
69
|
+
const {
|
|
70
|
+
filter: sourceDocumentFilterNames,
|
|
71
|
+
fetch: sourceDocumentLocation,
|
|
72
|
+
executeClientScripts: sourceDocumentExecuteClientScripts,
|
|
73
|
+
select: sourceDocumentContentSelectors,
|
|
74
|
+
remove: sourceDocumentInsignificantContentSelectors,
|
|
75
|
+
} = sourceDocument;
|
|
76
|
+
|
|
77
|
+
const sourceDocumentFilters = await loadServiceFilters(service.id, sourceDocumentFilterNames); // eslint-disable-line no-await-in-loop
|
|
78
|
+
|
|
79
|
+
sourceDocuments.push(new SourceDocument({
|
|
80
|
+
location: sourceDocumentLocation || location,
|
|
81
|
+
executeClientScripts: (sourceDocumentExecuteClientScripts === undefined || sourceDocumentExecuteClientScripts === null ? executeClientScripts : sourceDocumentExecuteClientScripts),
|
|
82
|
+
contentSelectors: sourceDocumentContentSelectors || contentSelectors,
|
|
83
|
+
insignificantContentSelectors: sourceDocumentInsignificantContentSelectors || insignificantContentSelectors,
|
|
84
|
+
filters: sourceDocumentFilters || filters,
|
|
82
85
|
}));
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
service.
|
|
89
|
+
service.addTerms(new Terms({ service, type: termsType, sourceDocuments }));
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
async function getDeclaredServicesIds() {
|
|
@@ -100,18 +103,18 @@ export async function loadWithHistory(servicesIds = []) {
|
|
|
100
103
|
for (const serviceId of Object.keys(services)) {
|
|
101
104
|
const { declarations, filters } = await loadServiceHistoryFiles(serviceId); // eslint-disable-line no-await-in-loop
|
|
102
105
|
|
|
103
|
-
for (const
|
|
104
|
-
const
|
|
105
|
-
const filterNames = [...new Set(
|
|
106
|
-
const allHistoryDates = extractHistoryDates({
|
|
106
|
+
for (const termsType of Object.keys(declarations)) {
|
|
107
|
+
const termsTypeDeclarationEntries = declarations[termsType];
|
|
108
|
+
const filterNames = [...new Set(termsTypeDeclarationEntries.flatMap(declaration => declaration.filter))].filter(Boolean);
|
|
109
|
+
const allHistoryDates = extractHistoryDates({ termsTypeDeclarationEntries, filters, filterNames });
|
|
107
110
|
|
|
108
|
-
const
|
|
111
|
+
const latestValidTerms = termsTypeDeclarationEntries.find(entry => !entry.validUntil);
|
|
109
112
|
|
|
110
113
|
allHistoryDates.forEach(async date => {
|
|
111
|
-
const declarationForThisDate =
|
|
114
|
+
const declarationForThisDate = termsTypeDeclarationEntries.find(entry => new Date(date) <= new Date(entry.validUntil)) || latestValidTerms;
|
|
112
115
|
const { filter: declarationForThisDateFilterNames, combine } = declarationForThisDate;
|
|
113
116
|
|
|
114
|
-
const
|
|
117
|
+
const sourceDocuments = [];
|
|
115
118
|
let actualFilters;
|
|
116
119
|
|
|
117
120
|
if (declarationForThisDateFilterNames) {
|
|
@@ -125,33 +128,39 @@ export async function loadWithHistory(servicesIds = []) {
|
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
if (!combine) {
|
|
128
|
-
|
|
131
|
+
sourceDocuments.push(new SourceDocument({
|
|
129
132
|
location: declarationForThisDate.fetch,
|
|
130
133
|
executeClientScripts: declarationForThisDate.executeClientScripts,
|
|
131
134
|
contentSelectors: declarationForThisDate.select,
|
|
132
|
-
|
|
135
|
+
insignificantContentSelectors: declarationForThisDate.remove,
|
|
133
136
|
filters: actualFilters,
|
|
134
137
|
}));
|
|
135
138
|
} else {
|
|
136
|
-
for (const
|
|
137
|
-
const {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
139
|
+
for (const sourceDocument of combine) {
|
|
140
|
+
const {
|
|
141
|
+
filter: sourceDocumentFilterNames,
|
|
142
|
+
fetch: sourceDocumentLocation,
|
|
143
|
+
executeClientScripts: sourceDocumentExecuteClientScripts,
|
|
144
|
+
select: sourceDocumentContentSelectors,
|
|
145
|
+
remove: sourceDocumentInsignificantContentSelectors,
|
|
146
|
+
} = sourceDocument;
|
|
147
|
+
|
|
148
|
+
const sourceDocumentFilters = await loadServiceFilters(serviceId, sourceDocumentFilterNames); // eslint-disable-line no-await-in-loop
|
|
149
|
+
|
|
150
|
+
sourceDocuments.push(new SourceDocument({
|
|
151
|
+
location: sourceDocumentLocation || declarationForThisDate.fetch,
|
|
152
|
+
executeClientScripts: (sourceDocumentExecuteClientScripts === undefined || sourceDocumentExecuteClientScripts === null ? declarationForThisDate.executeClientScripts : sourceDocumentExecuteClientScripts),
|
|
153
|
+
contentSelectors: sourceDocumentContentSelectors || declarationForThisDate.select,
|
|
154
|
+
insignificantContentSelectors: sourceDocumentInsignificantContentSelectors || declarationForThisDate.remove,
|
|
155
|
+
filters: sourceDocumentFilters || actualFilters,
|
|
147
156
|
}));
|
|
148
157
|
}
|
|
149
158
|
}
|
|
150
159
|
|
|
151
|
-
services[serviceId].
|
|
160
|
+
services[serviceId].addTerms(new Terms({
|
|
152
161
|
service: services[serviceId],
|
|
153
|
-
type:
|
|
154
|
-
|
|
162
|
+
type: termsType,
|
|
163
|
+
sourceDocuments,
|
|
155
164
|
validUntil: date,
|
|
156
165
|
}));
|
|
157
166
|
});
|
|
@@ -161,7 +170,7 @@ export async function loadWithHistory(servicesIds = []) {
|
|
|
161
170
|
return services;
|
|
162
171
|
}
|
|
163
172
|
|
|
164
|
-
function extractHistoryDates({ filters, filterNames,
|
|
173
|
+
function extractHistoryDates({ filters, filterNames, termsTypeDeclarationEntries }) {
|
|
165
174
|
const allHistoryDates = [];
|
|
166
175
|
|
|
167
176
|
Object.keys(filters).forEach(filterName => {
|
|
@@ -170,7 +179,7 @@ function extractHistoryDates({ filters, filterNames, documentTypeDeclarationEntr
|
|
|
170
179
|
}
|
|
171
180
|
});
|
|
172
181
|
|
|
173
|
-
|
|
182
|
+
termsTypeDeclarationEntries.forEach(({ validUntil }) => allHistoryDates.push(validUntil));
|
|
174
183
|
|
|
175
184
|
const sortedDates = allHistoryDates.sort((a, b) => new Date(a) - new Date(b));
|
|
176
185
|
const uniqSortedDates = [...new Set(sortedDates)];
|
|
@@ -211,9 +220,9 @@ async function loadServiceHistoryFiles(serviceId) {
|
|
|
211
220
|
}
|
|
212
221
|
}
|
|
213
222
|
|
|
214
|
-
Object.keys(serviceDeclaration.documents).forEach(
|
|
215
|
-
serviceHistory[
|
|
216
|
-
serviceHistory[
|
|
223
|
+
Object.keys(serviceDeclaration.documents).forEach(termsType => {
|
|
224
|
+
serviceHistory[termsType] = serviceHistory[termsType] || [];
|
|
225
|
+
serviceHistory[termsType].push(serviceDeclaration.documents[termsType]);
|
|
217
226
|
});
|
|
218
227
|
|
|
219
228
|
sortHistory(serviceHistory);
|
|
@@ -14,57 +14,57 @@ describe('Services', () => {
|
|
|
14
14
|
|
|
15
15
|
async function validateServiceWithoutHistory(serviceId, expected) {
|
|
16
16
|
/* eslint-disable no-loop-func */
|
|
17
|
-
for (const
|
|
18
|
-
context(`${
|
|
19
|
-
let
|
|
17
|
+
for (const termsType of expected.getTermsTypes()) {
|
|
18
|
+
context(`${termsType}`, () => {
|
|
19
|
+
let actualTerms;
|
|
20
20
|
let actualFilters;
|
|
21
21
|
let actualContentSelectors;
|
|
22
|
-
let
|
|
22
|
+
let actualInsignificantContentSelectors;
|
|
23
23
|
let actualExecuteClientScripts;
|
|
24
24
|
|
|
25
|
-
const
|
|
25
|
+
const expectedTerms = expected.getTerms(termsType);
|
|
26
26
|
|
|
27
|
-
const {
|
|
27
|
+
const { sourceDocuments } = expectedTerms;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
sourceDocuments.forEach((sourceDocument, index) => {
|
|
30
30
|
const {
|
|
31
31
|
filters: expectedFilters,
|
|
32
32
|
contentSelectors: expectedContentSelectors,
|
|
33
|
-
|
|
33
|
+
insignificantContentSelectors: expectedInsignificantContentSelectors,
|
|
34
34
|
executeClientScripts: expectedExecuteClientScripts,
|
|
35
|
-
} =
|
|
35
|
+
} = sourceDocument;
|
|
36
36
|
|
|
37
|
-
context(`
|
|
37
|
+
context(`source document: ${sourceDocument.id}`, () => {
|
|
38
38
|
before(() => {
|
|
39
|
-
|
|
40
|
-
const {
|
|
39
|
+
actualTerms = result[serviceId].getTerms(termsType);
|
|
40
|
+
const { sourceDocuments: actualDocuments } = actualTerms;
|
|
41
41
|
|
|
42
42
|
({
|
|
43
43
|
filters: actualFilters,
|
|
44
44
|
contentSelectors: actualContentSelectors,
|
|
45
|
-
|
|
45
|
+
insignificantContentSelectors: actualInsignificantContentSelectors,
|
|
46
46
|
executeClientScripts: actualExecuteClientScripts,
|
|
47
|
-
} =
|
|
47
|
+
} = actualDocuments[index]);
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
it('has the proper service name', () => {
|
|
51
|
-
expect(
|
|
51
|
+
expect(actualTerms.service.name).to.eql(expectedTerms.service.name);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
it('has the proper terms type', () => {
|
|
55
|
-
expect(
|
|
55
|
+
expect(actualTerms.type).to.eql(expectedTerms.type);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
it('has no validity date', () => {
|
|
59
|
-
expect(
|
|
59
|
+
expect(actualTerms.validUntil).to.be.undefined;
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it('has the proper content selectors', async () => {
|
|
63
63
|
expect(actualContentSelectors).to.equal(expectedContentSelectors);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
it('has the proper
|
|
67
|
-
expect(
|
|
66
|
+
it('has the proper insignificant content selectors', async () => {
|
|
67
|
+
expect(actualInsignificantContentSelectors).to.equal(expectedInsignificantContentSelectors);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
it('has the proper executeClientScripts option', async () => {
|
|
@@ -105,34 +105,24 @@ describe('Services', () => {
|
|
|
105
105
|
await validateServiceWithoutHistory('service_B', expectedServices.service_B);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await validateServiceWithoutHistory('service_without_history', expectedServices.service_without_history);
|
|
111
|
-
});
|
|
108
|
+
describe('Service without history', async () => {
|
|
109
|
+
await validateServiceWithoutHistory('service_without_history', expectedServices.service_without_history);
|
|
112
110
|
});
|
|
113
111
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
await validateServiceWithoutHistory('service_with_declaration_history', expectedServices.service_with_declaration_history);
|
|
117
|
-
});
|
|
112
|
+
describe('Service with declaration history only', async () => {
|
|
113
|
+
await validateServiceWithoutHistory('service_with_declaration_history', expectedServices.service_with_declaration_history);
|
|
118
114
|
});
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
await validateServiceWithoutHistory('service_with_filters_history', expectedServices.service_with_filters_history);
|
|
123
|
-
});
|
|
116
|
+
describe('Service with filters history only', async () => {
|
|
117
|
+
await validateServiceWithoutHistory('service_with_filters_history', expectedServices.service_with_filters_history);
|
|
124
118
|
});
|
|
125
119
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await validateServiceWithoutHistory('service_with_history', expectedServices.service_with_history);
|
|
129
|
-
});
|
|
120
|
+
describe('Service with both filters and declarations histories', async () => {
|
|
121
|
+
await validateServiceWithoutHistory('service_with_history', expectedServices.service_with_history);
|
|
130
122
|
});
|
|
131
123
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
await validateServiceWithoutHistory('service_with_multipage_document', expectedServices.service_with_multipage_document);
|
|
135
|
-
});
|
|
124
|
+
describe('Service with terms with multiple source documents', async () => {
|
|
125
|
+
await validateServiceWithoutHistory('service_with_multiple_source_documents_terms', expectedServices.service_with_multiple_source_documents_terms);
|
|
136
126
|
});
|
|
137
127
|
|
|
138
128
|
context('when specifying services to load', async () => {
|
|
@@ -151,37 +141,37 @@ describe('Services', () => {
|
|
|
151
141
|
|
|
152
142
|
async function validateServiceWithHistory(serviceId, expected) {
|
|
153
143
|
/* eslint-disable no-loop-func */
|
|
154
|
-
for (const
|
|
155
|
-
context(`${
|
|
156
|
-
const { history: expectedHistory } = expected.
|
|
144
|
+
for (const termsType of expected.getTermsTypes()) {
|
|
145
|
+
context(`${termsType}`, () => {
|
|
146
|
+
const { history: expectedHistory } = expected.terms[termsType];
|
|
157
147
|
const expectedHistoryDates = expectedHistory && [ ...expectedHistory.map(entry => entry.validUntil), null ]; // add `null` entry to simulate the still current valid declaration
|
|
158
148
|
|
|
159
|
-
let
|
|
149
|
+
let actualTerms;
|
|
160
150
|
let actualFilters;
|
|
161
|
-
const
|
|
151
|
+
const expectedTerms = expected.getTerms(termsType);
|
|
162
152
|
|
|
163
|
-
const {
|
|
153
|
+
const { sourceDocuments } = expectedTerms;
|
|
164
154
|
|
|
165
155
|
before(() => {
|
|
166
|
-
|
|
156
|
+
actualTerms = result[serviceId].getTerms(termsType);
|
|
167
157
|
});
|
|
168
158
|
|
|
169
159
|
it('has the proper service name', () => {
|
|
170
|
-
expect(
|
|
160
|
+
expect(actualTerms.service.name).to.eql(expectedTerms.service.name);
|
|
171
161
|
});
|
|
172
162
|
|
|
173
163
|
it('has the proper terms type', () => {
|
|
174
|
-
expect(
|
|
164
|
+
expect(actualTerms.type).to.eql(expectedTerms.type);
|
|
175
165
|
});
|
|
176
166
|
|
|
177
|
-
|
|
178
|
-
const { filters: expectedFilters } =
|
|
167
|
+
sourceDocuments.forEach((sourceDocument, index) => {
|
|
168
|
+
const { filters: expectedFilters } = sourceDocument;
|
|
179
169
|
|
|
180
|
-
context(`${
|
|
170
|
+
context(`${sourceDocument.id} sourceDocument`, () => {
|
|
181
171
|
before(() => {
|
|
182
|
-
const {
|
|
172
|
+
const { sourceDocuments: actualDocuments } = actualTerms;
|
|
183
173
|
|
|
184
|
-
({ filters: actualFilters } =
|
|
174
|
+
({ filters: actualFilters } = actualDocuments[index]);
|
|
185
175
|
});
|
|
186
176
|
|
|
187
177
|
if (expectedHistoryDates) {
|
|
@@ -189,34 +179,34 @@ describe('Services', () => {
|
|
|
189
179
|
context(`${date || 'Current'}`, () => {
|
|
190
180
|
let actualFiltersForThisDate;
|
|
191
181
|
let contentSelectorsForThisDate;
|
|
192
|
-
let
|
|
182
|
+
let insignificantContentSelectorsForThisDate;
|
|
193
183
|
let actualExecuteClientScriptsForThisDate;
|
|
194
184
|
|
|
195
|
-
const {
|
|
185
|
+
const { sourceDocuments: documentsForThisDate } = expected.getTerms(termsType, date);
|
|
196
186
|
const {
|
|
197
187
|
filters: expectedFiltersForThisDate,
|
|
198
188
|
contentSelectors: expectedContentSelectors,
|
|
199
|
-
|
|
189
|
+
insignificantContentSelectors: expectedInsignificantContentSelectors,
|
|
200
190
|
expectedExecuteClientScripts: expectedExecuteClientScriptsForThisDate,
|
|
201
|
-
} =
|
|
191
|
+
} = documentsForThisDate[index];
|
|
202
192
|
|
|
203
193
|
before(() => {
|
|
204
|
-
const {
|
|
194
|
+
const { sourceDocuments: actualDocumentsForThisDate } = result[serviceId].getTerms(termsType, date);
|
|
205
195
|
|
|
206
196
|
({
|
|
207
197
|
filters: actualFiltersForThisDate,
|
|
208
198
|
contentSelectors: contentSelectorsForThisDate,
|
|
209
|
-
|
|
199
|
+
insignificantContentSelectors: insignificantContentSelectorsForThisDate,
|
|
210
200
|
expectedExecuteClientScripts: actualExecuteClientScriptsForThisDate,
|
|
211
|
-
} =
|
|
201
|
+
} = actualDocumentsForThisDate[index]);
|
|
212
202
|
});
|
|
213
203
|
|
|
214
204
|
it('has the proper content selectors', async () => {
|
|
215
205
|
expect(contentSelectorsForThisDate).to.equal(expectedContentSelectors);
|
|
216
206
|
});
|
|
217
207
|
|
|
218
|
-
it('has the proper
|
|
219
|
-
expect(
|
|
208
|
+
it('has the proper insignificant content selectors', async () => {
|
|
209
|
+
expect(insignificantContentSelectorsForThisDate).to.equal(expectedInsignificantContentSelectors);
|
|
220
210
|
});
|
|
221
211
|
|
|
222
212
|
it('has the proper executeClientScripts option', async () => {
|
|
@@ -242,7 +232,7 @@ describe('Services', () => {
|
|
|
242
232
|
}
|
|
243
233
|
} else {
|
|
244
234
|
it('has no history', async () => {
|
|
245
|
-
expect(
|
|
235
|
+
expect(actualTerms.validUntil).to.be.undefined;
|
|
246
236
|
});
|
|
247
237
|
|
|
248
238
|
if (expectedFilters) {
|
|
@@ -284,34 +274,24 @@ describe('Services', () => {
|
|
|
284
274
|
await validateServiceWithHistory('service_B', expectedServices.service_B);
|
|
285
275
|
});
|
|
286
276
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
await validateServiceWithHistory('service_without_history', expectedServices.service_without_history);
|
|
290
|
-
});
|
|
277
|
+
describe('Service without history', async () => {
|
|
278
|
+
await validateServiceWithHistory('service_without_history', expectedServices.service_without_history);
|
|
291
279
|
});
|
|
292
280
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
await validateServiceWithHistory('service_with_declaration_history', expectedServices.service_with_declaration_history);
|
|
296
|
-
});
|
|
281
|
+
describe('Service with declaration history only', async () => {
|
|
282
|
+
await validateServiceWithHistory('service_with_declaration_history', expectedServices.service_with_declaration_history);
|
|
297
283
|
});
|
|
298
284
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
await validateServiceWithHistory('service_with_filters_history', expectedServices.service_with_filters_history);
|
|
302
|
-
});
|
|
285
|
+
describe('Service with filters history only', async () => {
|
|
286
|
+
await validateServiceWithHistory('service_with_filters_history', expectedServices.service_with_filters_history);
|
|
303
287
|
});
|
|
304
288
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
await validateServiceWithHistory('service_with_history', expectedServices.service_with_history);
|
|
308
|
-
});
|
|
289
|
+
describe('Service with both filters and declarations histories', async () => {
|
|
290
|
+
await validateServiceWithHistory('service_with_history', expectedServices.service_with_history);
|
|
309
291
|
});
|
|
310
292
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
await validateServiceWithHistory('service_with_multipage_document', expectedServices.service_with_multipage_document);
|
|
314
|
-
});
|
|
293
|
+
describe('Service with terms with multiple source documents', async () => {
|
|
294
|
+
await validateServiceWithHistory('service_with_multiple_source_documents_terms', expectedServices.service_with_multiple_source_documents_terms);
|
|
315
295
|
});
|
|
316
296
|
|
|
317
297
|
context('when specifying services to load', async () => {
|