@opentermsarchive/engine 7.2.2 → 7.2.4
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/package.json
CHANGED
|
@@ -9,7 +9,7 @@ export default class DeclarationUtils {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
static getServiceIdFromFilePath(filePath) {
|
|
12
|
-
return path.parse(filePath.replace(/\.history|\.filters
|
|
12
|
+
return path.parse(filePath.replace(/\.history|\.filters/g, '')).name;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async getJSONFromFile(ref, filePath) {
|
|
@@ -47,7 +47,7 @@ export default class DeclarationUtils {
|
|
|
47
47
|
return; // Assuming history modifications imply corresponding changes in the service declaration and that the analysis of which terms types of this service have changed will be done when analysing the related declaration, no further action is required here
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
if (modifiedFilePath.endsWith('.filters.js')) {
|
|
50
|
+
if (modifiedFilePath.endsWith('.filters.js') || modifiedFilePath.endsWith('.filters.history.js')) {
|
|
51
51
|
const declaration = await this.getJSONFromFile(this.defaultBranch, `declarations/${serviceId}.json`);
|
|
52
52
|
|
|
53
53
|
servicesTermsTypes[serviceId] = Object.keys(declaration.terms); // Considering how rarely filters are used, simply return all term types that could potentially be impacted to spare implementing a function change check
|
|
@@ -39,6 +39,24 @@ const removeLatestCommit = async () => {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
describe('DeclarationUtils', () => {
|
|
42
|
+
describe('#getServiceIdFromFilePath', () => {
|
|
43
|
+
it('extracts service ID from regular file path', () => {
|
|
44
|
+
expect(DeclarationUtils.getServiceIdFromFilePath('declarations/ServiceA.json')).to.equal('ServiceA');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('extracts service ID from history file path', () => {
|
|
48
|
+
expect(DeclarationUtils.getServiceIdFromFilePath('declarations/ServiceA.history.json')).to.equal('ServiceA');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('extracts service ID from filters file path', () => {
|
|
52
|
+
expect(DeclarationUtils.getServiceIdFromFilePath('declarations/ServiceA.filters.js')).to.equal('ServiceA');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('extracts service ID from filters history file path', () => {
|
|
56
|
+
expect(DeclarationUtils.getServiceIdFromFilePath('declarations/ServiceA.filters.history.js')).to.equal('ServiceA');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
42
60
|
describe('#getModifiedServicesAndTermsTypes', () => {
|
|
43
61
|
before(async () => {
|
|
44
62
|
await loadFixtures();
|
|
@@ -137,6 +155,50 @@ describe('DeclarationUtils', () => {
|
|
|
137
155
|
});
|
|
138
156
|
});
|
|
139
157
|
});
|
|
158
|
+
|
|
159
|
+
context('when filters file is modified', () => {
|
|
160
|
+
before(async () => {
|
|
161
|
+
await fs.writeFile(path.resolve(SUBJECT_PATH, './declarations/ServiceA.filters.js'), 'module.exports = {};');
|
|
162
|
+
await declarationUtils.git.add('./declarations/ServiceA.filters.js');
|
|
163
|
+
await declarationUtils.git.commit('Add filters file', './declarations/ServiceA.filters.js');
|
|
164
|
+
});
|
|
165
|
+
after(removeLatestCommit);
|
|
166
|
+
|
|
167
|
+
it('returns all terms types from the service declaration', async () => {
|
|
168
|
+
const result = await declarationUtils.getModifiedServicesAndTermsTypes();
|
|
169
|
+
|
|
170
|
+
expect(result.services).to.include('ServiceA');
|
|
171
|
+
expect(result.servicesTermsTypes.ServiceA).to.have.members([ 'Privacy Policy', 'Terms of Service' ]);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
context('when filters history file is modified', () => {
|
|
176
|
+
before(async () => {
|
|
177
|
+
await fs.writeFile(path.resolve(SUBJECT_PATH, './declarations/ServiceA.filters.history.js'), 'module.exports = {};');
|
|
178
|
+
await declarationUtils.git.add('./declarations/ServiceA.filters.history.js');
|
|
179
|
+
await declarationUtils.git.commit('Add filters history file', './declarations/ServiceA.filters.history.js');
|
|
180
|
+
});
|
|
181
|
+
after(removeLatestCommit);
|
|
182
|
+
|
|
183
|
+
it('returns all terms types from the service declaration', async () => {
|
|
184
|
+
const result = await declarationUtils.getModifiedServicesAndTermsTypes();
|
|
185
|
+
|
|
186
|
+
expect(result.services).to.include('ServiceA');
|
|
187
|
+
expect(result.servicesTermsTypes.ServiceA).to.have.members([ 'Privacy Policy', 'Terms of Service' ]);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
context('when history file is modified without declaration changes', () => {
|
|
192
|
+
before(() => commitChanges(COMMIT_PATHS.serviceAHistory, FIXTURES.serviceATermsUpdatedHistory.content));
|
|
193
|
+
after(removeLatestCommit);
|
|
194
|
+
|
|
195
|
+
it('returns no services and no terms types', async () => {
|
|
196
|
+
expect(await declarationUtils.getModifiedServicesAndTermsTypes()).to.deep.equal({
|
|
197
|
+
services: [],
|
|
198
|
+
servicesTermsTypes: {},
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
});
|
|
140
202
|
});
|
|
141
203
|
});
|
|
142
204
|
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
export function removeQueryParams(webPageDOM, paramsToRemove = []) {
|
|
2
|
-
|
|
3
|
-
paramsToRemove = [paramsToRemove];
|
|
4
|
-
}
|
|
2
|
+
const normalizedParams = Array.isArray(paramsToRemove) ? paramsToRemove : [paramsToRemove];
|
|
5
3
|
|
|
6
|
-
if (!
|
|
4
|
+
if (!normalizedParams.length) {
|
|
7
5
|
return;
|
|
8
6
|
}
|
|
9
7
|
|
|
10
|
-
const elements = [
|
|
11
|
-
...webPageDOM.querySelectorAll('a[href]'),
|
|
12
|
-
...webPageDOM.querySelectorAll('img[src]'),
|
|
13
|
-
];
|
|
8
|
+
const elements = webPageDOM.querySelectorAll('a[href], img[src]');
|
|
14
9
|
|
|
15
|
-
|
|
10
|
+
for (const element of elements) {
|
|
16
11
|
try {
|
|
17
|
-
const
|
|
12
|
+
const urlString = element.href || element.src;
|
|
13
|
+
const url = new URL(urlString);
|
|
14
|
+
|
|
15
|
+
const hasTargetParams = normalizedParams.some(param => url.searchParams.has(param));
|
|
16
|
+
|
|
17
|
+
if (hasTargetParams) {
|
|
18
|
+
normalizedParams.forEach(param => url.searchParams.delete(param));
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const attributeName = element.tagName === 'A' ? 'href' : 'src';
|
|
21
|
+
|
|
22
|
+
element[attributeName] = url.toString();
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
// Silently ignore invalid URLs
|
|
23
26
|
}
|
|
24
|
-
}
|
|
27
|
+
}
|
|
25
28
|
}
|
|
@@ -7,7 +7,7 @@ describe('exposedFilters', () => {
|
|
|
7
7
|
let webPageDOM;
|
|
8
8
|
|
|
9
9
|
before(() => {
|
|
10
|
-
webPageDOM = createWebPageDOM('<!DOCTYPE html><html><body></body></html>');
|
|
10
|
+
webPageDOM = createWebPageDOM('<!DOCTYPE html><html><body></body></html>', 'https://example.com');
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
describe('#removeQueryParams', () => {
|
|
@@ -16,7 +16,7 @@ describe('exposedFilters', () => {
|
|
|
16
16
|
|
|
17
17
|
before(() => {
|
|
18
18
|
link = webPageDOM.createElement('a');
|
|
19
|
-
link.href
|
|
19
|
+
link.setAttribute('href', 'https://example.com/page?utm_source=test&keep=value');
|
|
20
20
|
webPageDOM.body.appendChild(link);
|
|
21
21
|
});
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ describe('exposedFilters', () => {
|
|
|
27
27
|
it('removes the specified query parameters', () => {
|
|
28
28
|
removeQueryParams(webPageDOM, ['utm_source']);
|
|
29
29
|
|
|
30
|
-
expect(link.href).to.equal('https://example.com/page?keep=value');
|
|
30
|
+
expect(link.getAttribute('href')).to.equal('https://example.com/page?keep=value');
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
|
|
@@ -36,7 +36,7 @@ describe('exposedFilters', () => {
|
|
|
36
36
|
|
|
37
37
|
before(() => {
|
|
38
38
|
img = webPageDOM.createElement('img');
|
|
39
|
-
img.src
|
|
39
|
+
img.setAttribute('src', 'https://example.com/image.jpg?width=100&keep=value');
|
|
40
40
|
webPageDOM.body.appendChild(img);
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -47,7 +47,7 @@ describe('exposedFilters', () => {
|
|
|
47
47
|
it('removes the specified query parameters', () => {
|
|
48
48
|
removeQueryParams(webPageDOM, ['width']);
|
|
49
49
|
|
|
50
|
-
expect(img.src).to.equal('https://example.com/image.jpg?keep=value');
|
|
50
|
+
expect(img.getAttribute('src')).to.equal('https://example.com/image.jpg?keep=value');
|
|
51
51
|
});
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -56,7 +56,7 @@ describe('exposedFilters', () => {
|
|
|
56
56
|
|
|
57
57
|
before(() => {
|
|
58
58
|
link = webPageDOM.createElement('a');
|
|
59
|
-
link.href
|
|
59
|
+
link.setAttribute('href', 'https://example.com/page?utm_source=test&keep=value');
|
|
60
60
|
webPageDOM.body.appendChild(link);
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -67,7 +67,7 @@ describe('exposedFilters', () => {
|
|
|
67
67
|
it('removes a single query parameter passed as string', () => {
|
|
68
68
|
removeQueryParams(webPageDOM, 'utm_source');
|
|
69
69
|
|
|
70
|
-
expect(link.href).to.equal('https://example.com/page?keep=value');
|
|
70
|
+
expect(link.getAttribute('href')).to.equal('https://example.com/page?keep=value');
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
73
|
|
|
@@ -76,7 +76,7 @@ describe('exposedFilters', () => {
|
|
|
76
76
|
|
|
77
77
|
before(() => {
|
|
78
78
|
link = webPageDOM.createElement('a');
|
|
79
|
-
link.href
|
|
79
|
+
link.setAttribute('href', 'https://example.com/page?utm_source=test&keep=value');
|
|
80
80
|
webPageDOM.body.appendChild(link);
|
|
81
81
|
});
|
|
82
82
|
|
|
@@ -87,17 +87,23 @@ describe('exposedFilters', () => {
|
|
|
87
87
|
it('leaves the URL unchanged', () => {
|
|
88
88
|
removeQueryParams(webPageDOM, []);
|
|
89
89
|
|
|
90
|
-
expect(link.href).to.equal('https://example.com/page?utm_source=test&keep=value');
|
|
90
|
+
expect(link.getAttribute('href')).to.equal('https://example.com/page?utm_source=test&keep=value');
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
describe('with invalid URLs', () => {
|
|
95
95
|
let link;
|
|
96
|
+
let webPageDOMWithBaseURL;
|
|
97
|
+
const invalidURL = 'ht^THIS_IS_WRONG^tp://example.com?utm_source=test';
|
|
96
98
|
|
|
97
99
|
before(() => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
webPageDOMWithBaseURL = createWebPageDOM('<!DOCTYPE html><html><body></body></html>');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
before(() => {
|
|
104
|
+
link = webPageDOMWithBaseURL.createElement('a');
|
|
105
|
+
link.setAttribute('href', invalidURL);
|
|
106
|
+
webPageDOMWithBaseURL.body.appendChild(link);
|
|
101
107
|
});
|
|
102
108
|
|
|
103
109
|
after(() => {
|
|
@@ -105,9 +111,9 @@ describe('exposedFilters', () => {
|
|
|
105
111
|
});
|
|
106
112
|
|
|
107
113
|
it('ignores elements with invalid URLs', () => {
|
|
108
|
-
removeQueryParams(
|
|
114
|
+
removeQueryParams(webPageDOMWithBaseURL, ['utm_source']);
|
|
109
115
|
|
|
110
|
-
expect(link.href).to.equal(
|
|
116
|
+
expect(link.getAttribute('href')).to.equal(invalidURL);
|
|
111
117
|
});
|
|
112
118
|
});
|
|
113
119
|
|
|
@@ -116,7 +122,7 @@ describe('exposedFilters', () => {
|
|
|
116
122
|
|
|
117
123
|
before(() => {
|
|
118
124
|
link = webPageDOM.createElement('a');
|
|
119
|
-
link.href
|
|
125
|
+
link.setAttribute('href', 'https://example.com/page?utm_source=test&utm_medium=email&keep=value&remove=me');
|
|
120
126
|
webPageDOM.body.appendChild(link);
|
|
121
127
|
});
|
|
122
128
|
|
|
@@ -127,7 +133,7 @@ describe('exposedFilters', () => {
|
|
|
127
133
|
it('removes all specified query parameters', () => {
|
|
128
134
|
removeQueryParams(webPageDOM, [ 'utm_source', 'utm_medium', 'remove' ]);
|
|
129
135
|
|
|
130
|
-
expect(link.href).to.equal('https://example.com/page?keep=value');
|
|
136
|
+
expect(link.getAttribute('href')).to.equal('https://example.com/page?keep=value');
|
|
131
137
|
});
|
|
132
138
|
});
|
|
133
139
|
|
|
@@ -136,7 +142,7 @@ describe('exposedFilters', () => {
|
|
|
136
142
|
|
|
137
143
|
before(() => {
|
|
138
144
|
link = webPageDOM.createElement('a');
|
|
139
|
-
link.href
|
|
145
|
+
link.setAttribute('href', 'https://example.com/test?utm_source=to_remove_1&keep=true&utm_source=to_remove_2');
|
|
140
146
|
webPageDOM.body.appendChild(link);
|
|
141
147
|
});
|
|
142
148
|
|
|
@@ -147,7 +153,61 @@ describe('exposedFilters', () => {
|
|
|
147
153
|
it('removes all instances of duplicate query parameters', () => {
|
|
148
154
|
removeQueryParams(webPageDOM, ['utm_source']);
|
|
149
155
|
|
|
150
|
-
expect(link.href).to.equal('https://example.com/test?keep=true');
|
|
156
|
+
expect(link.getAttribute('href')).to.equal('https://example.com/test?keep=true');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('with URLs without target parameters', () => {
|
|
161
|
+
let absoluteLink;
|
|
162
|
+
let relativeLink;
|
|
163
|
+
let anchorLink;
|
|
164
|
+
let img;
|
|
165
|
+
const originalAbsoluteHref = 'https://example.com/page?keep=value&preserve=me';
|
|
166
|
+
const originalRelativeHref = './relative/path?existing=param';
|
|
167
|
+
const originalAnchorHref = '#section1';
|
|
168
|
+
const originalImgSrc = 'https://example.com/image.jpg?width=100&height=200';
|
|
169
|
+
|
|
170
|
+
before(() => {
|
|
171
|
+
absoluteLink = webPageDOM.createElement('a');
|
|
172
|
+
absoluteLink.setAttribute('href', originalAbsoluteHref);
|
|
173
|
+
webPageDOM.body.appendChild(absoluteLink);
|
|
174
|
+
|
|
175
|
+
relativeLink = webPageDOM.createElement('a');
|
|
176
|
+
relativeLink.setAttribute('href', originalRelativeHref);
|
|
177
|
+
webPageDOM.body.appendChild(relativeLink);
|
|
178
|
+
|
|
179
|
+
anchorLink = webPageDOM.createElement('a');
|
|
180
|
+
anchorLink.setAttribute('href', originalAnchorHref);
|
|
181
|
+
webPageDOM.body.appendChild(anchorLink);
|
|
182
|
+
|
|
183
|
+
img = webPageDOM.createElement('img');
|
|
184
|
+
img.setAttribute('src', originalImgSrc);
|
|
185
|
+
webPageDOM.body.appendChild(img);
|
|
186
|
+
|
|
187
|
+
removeQueryParams(webPageDOM, [ 'utm_source', 'utm_medium', 'session_id' ]);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
after(() => {
|
|
191
|
+
absoluteLink.remove();
|
|
192
|
+
relativeLink.remove();
|
|
193
|
+
anchorLink.remove();
|
|
194
|
+
img.remove();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('leaves absolute link URLs untouched', () => {
|
|
198
|
+
expect(absoluteLink.getAttribute('href')).to.equal(originalAbsoluteHref);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('leaves relative link URLs untouched', () => {
|
|
202
|
+
expect(relativeLink.getAttribute('href')).to.equal(originalRelativeHref);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('leaves anchor link URLs untouched', () => {
|
|
206
|
+
expect(anchorLink.getAttribute('href')).to.equal(originalAnchorHref);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('leaves image source URLs untouched', () => {
|
|
210
|
+
expect(img.getAttribute('src')).to.equal(originalImgSrc);
|
|
151
211
|
});
|
|
152
212
|
});
|
|
153
213
|
|