fiftyone.pipeline.cloudrequestengine 4.5.46 → 4.5.48
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/cloudRequestEngine.js
CHANGED
|
@@ -422,10 +422,16 @@ class CloudRequestEngine extends Engine {
|
|
|
422
422
|
*/
|
|
423
423
|
addQueryData (flowData, queryData, allEvidence, evidence) {
|
|
424
424
|
for (const [evidenceKey, evidenceValue] of Object.entries(evidence)) {
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
const
|
|
425
|
+
// Split the key at its first dot only. The prefix is the part before
|
|
426
|
+
// it and the name sent to the cloud is everything after it, so a name
|
|
427
|
+
// that itself contains a dot, such as id.usage, is sent whole.
|
|
428
|
+
const separatorIndex = evidenceKey.indexOf('.');
|
|
429
|
+
const prefix = separatorIndex >= 0
|
|
430
|
+
? evidenceKey.substring(0, separatorIndex)
|
|
431
|
+
: evidenceKey;
|
|
432
|
+
const suffix = separatorIndex >= 0
|
|
433
|
+
? evidenceKey.substring(separatorIndex + 1)
|
|
434
|
+
: evidenceKey;
|
|
429
435
|
|
|
430
436
|
// Check and add the evidence to the query parameters.
|
|
431
437
|
if ((suffix in queryData) === false) {
|
package/package.json
CHANGED
|
@@ -208,3 +208,60 @@ each([
|
|
|
208
208
|
const result = engine.getContent(data);
|
|
209
209
|
expect(result['User-Agent']).toBe(expectedValue);
|
|
210
210
|
});
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Test that an evidence name which itself contains a dot keeps every part
|
|
214
|
+
* after the prefix. The cloud service reads the 51Did usage from id.usage,
|
|
215
|
+
* so evidence named query.id.usage must be sent as id.usage and not cut
|
|
216
|
+
* down to id, otherwise the service never creates a 51Did.
|
|
217
|
+
*/
|
|
218
|
+
each([
|
|
219
|
+
['query.id.usage', 'standard', 'id.usage'],
|
|
220
|
+
['header.id.usage', 'standard', 'id.usage'],
|
|
221
|
+
['query.id.email', 'someone@example.com', 'id.email'],
|
|
222
|
+
['server.client-ip', '81.2.69.142', 'client-ip'],
|
|
223
|
+
['query.user-agent', 'iPhone', 'user-agent']
|
|
224
|
+
])
|
|
225
|
+
.test('get content keeps the full name - %s', (key, value, expectedName) => {
|
|
226
|
+
const client = new MockRequestClient();
|
|
227
|
+
const engine = new CloudRequestEngine({
|
|
228
|
+
resourceKey: testResourceKey,
|
|
229
|
+
requestClient: client
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const pipeline = new PipelineBuilder()
|
|
233
|
+
.add(engine)
|
|
234
|
+
.build();
|
|
235
|
+
|
|
236
|
+
const data = pipeline.createFlowData();
|
|
237
|
+
data.evidence.add(key, value);
|
|
238
|
+
|
|
239
|
+
const result = engine.getContent(data);
|
|
240
|
+
expect(result).toStrictEqual({ [expectedName]: value });
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Test that two dotted names which share their first part after the prefix
|
|
245
|
+
* are sent as two separate parameters rather than one overwriting the other.
|
|
246
|
+
*/
|
|
247
|
+
test('get content keeps dotted names apart', () => {
|
|
248
|
+
const client = new MockRequestClient();
|
|
249
|
+
const engine = new CloudRequestEngine({
|
|
250
|
+
resourceKey: testResourceKey,
|
|
251
|
+
requestClient: client
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
const pipeline = new PipelineBuilder()
|
|
255
|
+
.add(engine)
|
|
256
|
+
.build();
|
|
257
|
+
|
|
258
|
+
const data = pipeline.createFlowData();
|
|
259
|
+
data.evidence.add('query.id.usage', 'standard');
|
|
260
|
+
data.evidence.add('query.id.email', 'someone@example.com');
|
|
261
|
+
|
|
262
|
+
const result = engine.getContent(data);
|
|
263
|
+
expect(result).toStrictEqual({
|
|
264
|
+
'id.usage': 'standard',
|
|
265
|
+
'id.email': 'someone@example.com'
|
|
266
|
+
});
|
|
267
|
+
});
|
|
@@ -106,3 +106,46 @@ test('post with sequence evidence', done => {
|
|
|
106
106
|
done();
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Verify that a server using the engine gets a 51Did on its first call.
|
|
112
|
+
* The engine sends the end user's User-Agent as evidence and never as its
|
|
113
|
+
* own HTTP User-Agent header, so the cloud service does not treat the call
|
|
114
|
+
* as a browser page that still has snippets to run. The usage is sent as
|
|
115
|
+
* query.id.usage, whose name contains a dot and must reach the service
|
|
116
|
+
* whole. This is an integration test that uses the live cloud service. It
|
|
117
|
+
* is skipped when the resource key does not include the fodid product.
|
|
118
|
+
*/
|
|
119
|
+
test('51Did on the first call', async () => {
|
|
120
|
+
if (myResourceKey === '!!YOUR_RESOURCE_KEY!!') {
|
|
121
|
+
fail('You need to supply a resource key in the ' +
|
|
122
|
+
'_51DEGREES_RESOURCE_KEY environment variable.');
|
|
123
|
+
}
|
|
124
|
+
const cloud = new CloudRequestEngine({ resourceKey: myResourceKey });
|
|
125
|
+
const pipeline = new PipelineBuilder()
|
|
126
|
+
.add(cloud)
|
|
127
|
+
.build();
|
|
128
|
+
await cloud.ready();
|
|
129
|
+
// The product name keeps the case the service gives it, such as FODid.
|
|
130
|
+
const fodidProduct = Object.entries(cloud.flowElementProperties)
|
|
131
|
+
.find(([name]) => name.toLowerCase() === 'fodid');
|
|
132
|
+
if (!fodidProduct || !fodidProduct[1].idprobglobal) {
|
|
133
|
+
console.warn('The resource key does not include ' +
|
|
134
|
+
'fodid.idprobglobal, so the 51Did check was skipped.');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const data = pipeline.createFlowData();
|
|
139
|
+
data.evidence.add('header.user-agent', 'Mozilla/5.0 (Windows NT 10.0; ' +
|
|
140
|
+
'Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' +
|
|
141
|
+
'Chrome/120.0.0.0 Safari/537.36');
|
|
142
|
+
data.evidence.add('server.client-ip', '81.2.69.142');
|
|
143
|
+
data.evidence.add('query.id.usage', 'standard');
|
|
144
|
+
await data.process();
|
|
145
|
+
|
|
146
|
+
const fodid = JSON.parse(data.cloud.cloud).fodid;
|
|
147
|
+
expect(fodid).toBeDefined();
|
|
148
|
+
expect(fodid.idprobglobalnullreason).toBeUndefined();
|
|
149
|
+
expect(typeof fodid.idprobglobal).toBe('string');
|
|
150
|
+
expect(fodid.idprobglobal.length).toBeGreaterThan(0);
|
|
151
|
+
});
|
|
@@ -212,3 +212,35 @@ test('post - data', done => {
|
|
|
212
212
|
},
|
|
213
213
|
done);
|
|
214
214
|
});
|
|
215
|
+
|
|
216
|
+
// The cloud service treats a request whose own User-Agent header names a
|
|
217
|
+
// browser as a browser page, and such a page gets no 51Did until it has run
|
|
218
|
+
// its snippets. The end user's User-Agent must therefore only travel as the
|
|
219
|
+
// user-agent parameter in the body and never as the HTTP User-Agent header.
|
|
220
|
+
each([
|
|
221
|
+
['post', (client, url, data) => client.post(url, data)],
|
|
222
|
+
['get', (client, url) => client.get(url)]
|
|
223
|
+
])
|
|
224
|
+
.test('%s - end user User-Agent is not sent as the header', (name, send, done) => {
|
|
225
|
+
const browserUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
|
|
226
|
+
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 ' +
|
|
227
|
+
'Safari/537.36';
|
|
228
|
+
const port = POST_PORT;
|
|
229
|
+
let header;
|
|
230
|
+
server.addListener('request', (req, res) => {
|
|
231
|
+
header = req.headers['user-agent'];
|
|
232
|
+
res.writeHead(200);
|
|
233
|
+
res.end('{}');
|
|
234
|
+
});
|
|
235
|
+
server.listen(port, () => {
|
|
236
|
+
send(
|
|
237
|
+
new RequestClient(),
|
|
238
|
+
`http://localhost:${port}`,
|
|
239
|
+
{ 'user-agent': browserUserAgent })
|
|
240
|
+
.then(() => {
|
|
241
|
+
expect(header === undefined || !header.includes('Mozilla'))
|
|
242
|
+
.toBe(true);
|
|
243
|
+
})
|
|
244
|
+
.then(() => done(), done);
|
|
245
|
+
});
|
|
246
|
+
});
|