@verii/data-loader 1.1.0-pre.1775646065 → 1.1.0-pre.1775953178
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verii/data-loader",
|
|
3
|
-
"version": "1.1.0-pre.
|
|
3
|
+
"version": "1.1.0-pre.1775953178",
|
|
4
4
|
"description": "A tool for uploading data to the different target systems.",
|
|
5
5
|
"repository": "https://github.com/LFDT-Verii/core",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
"eslint-watch": "8.0.0",
|
|
30
30
|
"expect": "30.3.0",
|
|
31
31
|
"globals": "17.4.0",
|
|
32
|
-
"nock": "15.0.0",
|
|
32
|
+
"nock": "15.0.0-beta.10",
|
|
33
33
|
"prettier": "3.8.1"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@verii/http-client": "1.1.0-pre.1775953178",
|
|
36
37
|
"chalk": "~4.1.2",
|
|
37
38
|
"commander": "~14.0.0",
|
|
38
39
|
"csv-parser": "~3.2.0",
|
|
39
40
|
"date-fns": "4.1.0",
|
|
40
|
-
"got": "11.8.6",
|
|
41
41
|
"handlebars": "^4.7.7",
|
|
42
42
|
"inquirer": "^8.0.0",
|
|
43
43
|
"lodash": "^4.17.21",
|
|
44
44
|
"nanoid": "5.1.6",
|
|
45
45
|
"strip-bom-stream": "^4.0.0"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "05090118369e202d7c77fc4a420b14f94338a3e5"
|
|
48
48
|
}
|
|
@@ -1,78 +1,77 @@
|
|
|
1
1
|
const { env } = require('node:process');
|
|
2
|
-
const
|
|
2
|
+
const { initHttpClient } = require('@verii/http-client');
|
|
3
3
|
const { map, isEmpty } = require('lodash/fp');
|
|
4
4
|
const { printInfo } = require('../helpers/common');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const setupHttpClient = ({ endpoint, authToken }) => {
|
|
7
7
|
const options = {};
|
|
8
8
|
if (endpoint != null) {
|
|
9
9
|
options.prefixUrl = `${endpoint}/operator-api/v0.8`;
|
|
10
10
|
}
|
|
11
11
|
if (authToken != null) {
|
|
12
|
-
options.
|
|
12
|
+
options.bearerToken = authToken;
|
|
13
13
|
}
|
|
14
14
|
if (env.NODE_TLS_REJECT_UNAUTHORIZED === '0') {
|
|
15
|
-
options.
|
|
16
|
-
rejectUnauthorized: false,
|
|
17
|
-
};
|
|
15
|
+
options.tlsRejectUnauthorized = false;
|
|
18
16
|
}
|
|
19
|
-
|
|
17
|
+
if (env.NODE_ENV === 'test') {
|
|
18
|
+
options.isTest = true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return initHttpClient(options)({
|
|
22
|
+
log: console,
|
|
23
|
+
traceId: 'TRACE-ID',
|
|
24
|
+
});
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
const initFetchers = (options) => {
|
|
23
|
-
const
|
|
28
|
+
const credentialAgentTenantClient = setupHttpClient(options);
|
|
24
29
|
const param = getTenantsRouteParam(options);
|
|
25
30
|
return {
|
|
26
31
|
getTenant: async () => {
|
|
27
32
|
printInfo('Retrieving tenant');
|
|
28
|
-
return
|
|
33
|
+
return credentialAgentTenantClient
|
|
34
|
+
.get(`tenants/${param}`)
|
|
35
|
+
.then((res) => res.json());
|
|
29
36
|
},
|
|
30
37
|
createDisclosure: async (disclosureRequest) => {
|
|
31
38
|
printInfo('Creating disclosure');
|
|
32
|
-
return
|
|
33
|
-
.post(`tenants/${param}/disclosures`,
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
.json();
|
|
39
|
+
return credentialAgentTenantClient
|
|
40
|
+
.post(`tenants/${param}/disclosures`, disclosureRequest)
|
|
41
|
+
.then((res) => res.json());
|
|
37
42
|
},
|
|
38
43
|
getDisclosureList: async (vendorEndpoints) => {
|
|
39
44
|
printInfo('Retrieving disclosure list');
|
|
40
|
-
const
|
|
41
|
-
`tenants/${param}/disclosures`,
|
|
42
|
-
credentialAgentTenantGot.defaults.options.prefixUrl,
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
+
const searchParams = new URLSearchParams();
|
|
45
46
|
if (!isEmpty(vendorEndpoints)) {
|
|
46
47
|
vendorEndpoints.forEach((vendorEndpoint) => {
|
|
47
|
-
|
|
48
|
+
searchParams.append('vendorEndpoint', vendorEndpoint);
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
return
|
|
52
|
+
return credentialAgentTenantClient
|
|
53
|
+
.get(`tenants/${param}/disclosures`, { searchParams })
|
|
54
|
+
.then((res) => res.json());
|
|
52
55
|
},
|
|
53
56
|
getDisclosure: async (disclosureId) => {
|
|
54
57
|
printInfo('Retrieving disclosure');
|
|
55
|
-
return
|
|
58
|
+
return credentialAgentTenantClient
|
|
56
59
|
.get(`tenants/${param}/disclosures/${disclosureId}`)
|
|
57
|
-
.json();
|
|
60
|
+
.then((res) => res.json());
|
|
58
61
|
},
|
|
59
62
|
createOfferExchange: async (newExchange) => {
|
|
60
63
|
printInfo('Creating exchange');
|
|
61
|
-
return
|
|
62
|
-
.post(`tenants/${param}/exchanges`,
|
|
63
|
-
|
|
64
|
-
})
|
|
65
|
-
.json();
|
|
64
|
+
return credentialAgentTenantClient
|
|
65
|
+
.post(`tenants/${param}/exchanges`, newExchange)
|
|
66
|
+
.then((res) => res.json());
|
|
66
67
|
},
|
|
67
68
|
createOffer: async (exchange, newOffer) => {
|
|
68
69
|
printInfo(
|
|
69
70
|
`Adding offer ${newOffer.offerId} to exchange id: ${exchange.id}`,
|
|
70
71
|
);
|
|
71
|
-
return
|
|
72
|
-
.post(`tenants/${param}/exchanges/${exchange.id}/offers`,
|
|
73
|
-
|
|
74
|
-
})
|
|
75
|
-
.json();
|
|
72
|
+
return credentialAgentTenantClient
|
|
73
|
+
.post(`tenants/${param}/exchanges/${exchange.id}/offers`, newOffer)
|
|
74
|
+
.then((res) => res.json());
|
|
76
75
|
},
|
|
77
76
|
submitCompleteOffer: async (exchange, offers) => {
|
|
78
77
|
printInfo(
|
|
@@ -81,30 +80,34 @@ const initFetchers = (options) => {
|
|
|
81
80
|
offers,
|
|
82
81
|
)}`,
|
|
83
82
|
);
|
|
84
|
-
return
|
|
83
|
+
return credentialAgentTenantClient
|
|
85
84
|
.post(`tenants/${param}/exchanges/${exchange.id}/offers/complete`)
|
|
86
|
-
.json();
|
|
85
|
+
.then((res) => res.json());
|
|
87
86
|
},
|
|
88
87
|
loadExchangeQrcode: async (exchange) =>
|
|
89
|
-
(
|
|
90
|
-
await
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
Buffer.from(
|
|
89
|
+
await (
|
|
90
|
+
await credentialAgentTenantClient.get(
|
|
91
|
+
`tenants/${param}/exchanges/${exchange.id}/qrcode.png`,
|
|
92
|
+
)
|
|
93
|
+
).rawBody.arrayBuffer(),
|
|
94
|
+
),
|
|
94
95
|
loadExchangeDeeplink: async (exchange) =>
|
|
95
|
-
|
|
96
|
+
credentialAgentTenantClient
|
|
96
97
|
.get(`tenants/${param}/exchanges/${exchange.id}/qrcode.uri`)
|
|
97
|
-
.text(),
|
|
98
|
+
.then((res) => res.text()),
|
|
98
99
|
loadDisclosureQrcode: async (disclosure) =>
|
|
99
|
-
(
|
|
100
|
-
await
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
Buffer.from(
|
|
101
|
+
await (
|
|
102
|
+
await credentialAgentTenantClient.get(
|
|
103
|
+
`tenants/${param}/disclosures/${disclosure.id}/qrcode.png`,
|
|
104
|
+
)
|
|
105
|
+
).rawBody.arrayBuffer(),
|
|
106
|
+
),
|
|
104
107
|
loadDisclosureDeeplink: async (disclosure) =>
|
|
105
|
-
|
|
108
|
+
credentialAgentTenantClient
|
|
106
109
|
.get(`tenants/${param}/disclosures/${disclosure.id}/qrcode.uri`)
|
|
107
|
-
.text(),
|
|
110
|
+
.then((res) => res.text()),
|
|
108
111
|
};
|
|
109
112
|
};
|
|
110
113
|
|
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { initHttpClient } = require('@verii/http-client');
|
|
2
2
|
const { printInfo } = require('../helpers/common');
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
const options = {
|
|
6
|
-
prefixUrl: endpoint,
|
|
7
|
-
};
|
|
4
|
+
const setupHttpClient = ({ endpoint, authToken }) => {
|
|
5
|
+
const options = { prefixUrl: endpoint };
|
|
8
6
|
if (authToken != null) {
|
|
9
|
-
options.
|
|
7
|
+
options.bearerToken = authToken;
|
|
8
|
+
}
|
|
9
|
+
if (process.env.NODE_ENV === 'test') {
|
|
10
|
+
options.isTest = true;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
return initHttpClient(options)({
|
|
14
|
+
log: console,
|
|
15
|
+
traceId: 'TRACE-ID',
|
|
16
|
+
});
|
|
12
17
|
};
|
|
13
18
|
|
|
14
19
|
const initExecuteUpdate = (options) => {
|
|
15
|
-
const
|
|
20
|
+
const vendorHttpClient = setupHttpClient(options);
|
|
16
21
|
return async ({ person, offer }) => {
|
|
17
22
|
if (person) {
|
|
18
23
|
printInfo({
|
|
19
|
-
createdPerson: await
|
|
20
|
-
.post('api/users',
|
|
21
|
-
.json(),
|
|
24
|
+
createdPerson: await vendorHttpClient
|
|
25
|
+
.post('api/users', person)
|
|
26
|
+
.then((res) => res.json()),
|
|
22
27
|
});
|
|
23
28
|
}
|
|
24
29
|
printInfo({
|
|
25
|
-
createdOffer: await
|
|
30
|
+
createdOffer: await vendorHttpClient
|
|
31
|
+
.post('api/offers', offer)
|
|
32
|
+
.then((res) => res.json()),
|
|
26
33
|
});
|
|
27
34
|
};
|
|
28
35
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const { after, before, describe, it } = require('node:test');
|
|
2
2
|
const { expect } = require('expect');
|
|
3
3
|
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const os = require('os');
|
|
4
6
|
const path = require('path');
|
|
5
7
|
const nock = require('nock');
|
|
6
8
|
|
|
@@ -1465,4 +1467,151 @@ describe('batch issuing test', () => {
|
|
|
1465
1467
|
});
|
|
1466
1468
|
});
|
|
1467
1469
|
});
|
|
1470
|
+
|
|
1471
|
+
it('should create disclosure and exchange payloads through the full issuing flow', async () => {
|
|
1472
|
+
const agentUrl = 'https://exampleUrl';
|
|
1473
|
+
const tempDir = fs.mkdtempSync(
|
|
1474
|
+
path.join(os.tmpdir(), 'data-loader-batch-issuing-'),
|
|
1475
|
+
);
|
|
1476
|
+
const expectedDisclosure = {
|
|
1477
|
+
configurationType: 'issuing',
|
|
1478
|
+
vendorEndpoint: 'integrated-issuing-identification',
|
|
1479
|
+
types: [{ type: 'EmailV1.0' }],
|
|
1480
|
+
identityMatchers: {
|
|
1481
|
+
rules: [
|
|
1482
|
+
{
|
|
1483
|
+
valueIndex: 0,
|
|
1484
|
+
path: ['$.emails'],
|
|
1485
|
+
rule: 'pick',
|
|
1486
|
+
},
|
|
1487
|
+
],
|
|
1488
|
+
vendorUserIdIndex: 2,
|
|
1489
|
+
},
|
|
1490
|
+
setIssuingDefault: true,
|
|
1491
|
+
duration: '1h',
|
|
1492
|
+
purpose: 'Issuing Career Credential',
|
|
1493
|
+
authTokenExpiresIn: 525600,
|
|
1494
|
+
termsUrl: 'http://example.com/terms.html',
|
|
1495
|
+
};
|
|
1496
|
+
const expectedFirstExchange = {
|
|
1497
|
+
type: 'ISSUING',
|
|
1498
|
+
identityMatcherValues: ['joan.lee@sap.com'],
|
|
1499
|
+
disclosureId: 'disclosure-id',
|
|
1500
|
+
};
|
|
1501
|
+
const expectedSecondExchange = {
|
|
1502
|
+
type: 'ISSUING',
|
|
1503
|
+
identityMatcherValues: ['john.smith@sap.com'],
|
|
1504
|
+
disclosureId: 'disclosure-id',
|
|
1505
|
+
};
|
|
1506
|
+
const expectedFirstOffer = {
|
|
1507
|
+
type: ['EmailV1.0'],
|
|
1508
|
+
issuer: { id: 'did:sap:123' },
|
|
1509
|
+
credentialSubject: {
|
|
1510
|
+
vendorUserId: 'joan.lee@sap.com',
|
|
1511
|
+
email: 'joan.lee@sap.com',
|
|
1512
|
+
},
|
|
1513
|
+
};
|
|
1514
|
+
const expectedSecondOffer = {
|
|
1515
|
+
type: ['EmailV1.0'],
|
|
1516
|
+
issuer: { id: 'did:sap:123' },
|
|
1517
|
+
credentialSubject: {
|
|
1518
|
+
vendorUserId: 'john.smith@sap.com',
|
|
1519
|
+
email: 'john.smith@sap.com',
|
|
1520
|
+
},
|
|
1521
|
+
};
|
|
1522
|
+
|
|
1523
|
+
const disclosureScope = nock(agentUrl, {
|
|
1524
|
+
reqheaders: { Authorization: 'Bearer fakeToken' },
|
|
1525
|
+
})
|
|
1526
|
+
.post('/operator-api/v0.8/tenants/tenant-id/disclosures', (body) => {
|
|
1527
|
+
expect(body).toMatchObject(expectedDisclosure);
|
|
1528
|
+
expect(body.vendorDisclosureId).toEqual(expect.any(Number));
|
|
1529
|
+
expect(body.activationDate).toEqual(
|
|
1530
|
+
expect.stringMatching(ISO_DATETIME_TZ_FORMAT),
|
|
1531
|
+
);
|
|
1532
|
+
return true;
|
|
1533
|
+
})
|
|
1534
|
+
.reply(200, { id: 'disclosure-id' });
|
|
1535
|
+
|
|
1536
|
+
const exchangeOfferScope = nock(agentUrl, {
|
|
1537
|
+
reqheaders: { Authorization: 'Bearer fakeToken' },
|
|
1538
|
+
})
|
|
1539
|
+
.post(
|
|
1540
|
+
'/operator-api/v0.8/tenants/tenant-id/exchanges',
|
|
1541
|
+
expectedFirstExchange,
|
|
1542
|
+
)
|
|
1543
|
+
.reply(200, { id: 'exchange-1' })
|
|
1544
|
+
.post(
|
|
1545
|
+
'/operator-api/v0.8/tenants/tenant-id/exchanges/exchange-1/offers',
|
|
1546
|
+
(body) => {
|
|
1547
|
+
expect(body).toMatchObject(expectedFirstOffer);
|
|
1548
|
+
expect(body.offerId).toEqual(expect.any(String));
|
|
1549
|
+
return true;
|
|
1550
|
+
},
|
|
1551
|
+
)
|
|
1552
|
+
.reply(200, { id: 'offer-1' })
|
|
1553
|
+
.post(
|
|
1554
|
+
'/operator-api/v0.8/tenants/tenant-id/exchanges/exchange-1/offers/complete',
|
|
1555
|
+
)
|
|
1556
|
+
.reply(200, {})
|
|
1557
|
+
.post(
|
|
1558
|
+
'/operator-api/v0.8/tenants/tenant-id/exchanges',
|
|
1559
|
+
expectedSecondExchange,
|
|
1560
|
+
)
|
|
1561
|
+
.reply(200, { id: 'exchange-2' })
|
|
1562
|
+
.post(
|
|
1563
|
+
'/operator-api/v0.8/tenants/tenant-id/exchanges/exchange-2/offers',
|
|
1564
|
+
(body) => {
|
|
1565
|
+
expect(body).toMatchObject(expectedSecondOffer);
|
|
1566
|
+
expect(body.offerId).toEqual(expect.any(String));
|
|
1567
|
+
return true;
|
|
1568
|
+
},
|
|
1569
|
+
)
|
|
1570
|
+
.reply(200, { id: 'offer-2' })
|
|
1571
|
+
.post(
|
|
1572
|
+
'/operator-api/v0.8/tenants/tenant-id/exchanges/exchange-2/offers/complete',
|
|
1573
|
+
)
|
|
1574
|
+
.reply(200, {})
|
|
1575
|
+
.get(
|
|
1576
|
+
'/operator-api/v0.8/tenants/tenant-id/disclosures/disclosure-id/qrcode.uri',
|
|
1577
|
+
)
|
|
1578
|
+
.reply(200, 'https://example.com/disclosure')
|
|
1579
|
+
.get(
|
|
1580
|
+
'/operator-api/v0.8/tenants/tenant-id/disclosures/disclosure-id/qrcode.png',
|
|
1581
|
+
)
|
|
1582
|
+
.reply(200, Buffer.from('fake-png'));
|
|
1583
|
+
|
|
1584
|
+
const options = {
|
|
1585
|
+
csvFilename: path.join(__dirname, 'data/variables.csv'),
|
|
1586
|
+
offerTemplateFilename: path.join(
|
|
1587
|
+
__dirname,
|
|
1588
|
+
'data/email-offer.template.json',
|
|
1589
|
+
),
|
|
1590
|
+
tenant: 'tenant-id',
|
|
1591
|
+
did: 'did:sap:123',
|
|
1592
|
+
termsUrl: 'http://example.com/terms.html',
|
|
1593
|
+
idCredentialType: 'EmailV1.0',
|
|
1594
|
+
vendorUseridColumn: 'email',
|
|
1595
|
+
new: true,
|
|
1596
|
+
endpoint: agentUrl,
|
|
1597
|
+
authToken: 'fakeToken',
|
|
1598
|
+
path: tempDir,
|
|
1599
|
+
};
|
|
1600
|
+
|
|
1601
|
+
try {
|
|
1602
|
+
await expect(runBatchIssuing(options)).resolves.toBeUndefined();
|
|
1603
|
+
|
|
1604
|
+
disclosureScope.done();
|
|
1605
|
+
exchangeOfferScope.done();
|
|
1606
|
+
expect(
|
|
1607
|
+
fs.existsSync(path.join(tempDir, 'disclosure-disclosure-id.json')),
|
|
1608
|
+
).toBe(true);
|
|
1609
|
+
expect(fs.existsSync(path.join(tempDir, 'lastrun.json'))).toBe(true);
|
|
1610
|
+
expect(fs.existsSync(path.join(tempDir, 'qrcode-generic.png'))).toBe(
|
|
1611
|
+
true,
|
|
1612
|
+
);
|
|
1613
|
+
} finally {
|
|
1614
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
1615
|
+
}
|
|
1616
|
+
});
|
|
1468
1617
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
const { describe, it } = require('node:test');
|
|
1
|
+
const { after, before, describe, it } = require('node:test');
|
|
2
2
|
const { expect } = require('expect');
|
|
3
|
+
const nock = require('nock');
|
|
3
4
|
|
|
4
5
|
const path = require('path');
|
|
5
6
|
const {
|
|
@@ -7,6 +8,15 @@ const {
|
|
|
7
8
|
} = require('../src/vendor-credentials/orchestrator');
|
|
8
9
|
|
|
9
10
|
describe('vendor credentials test', () => {
|
|
11
|
+
before(() => {
|
|
12
|
+
nock.cleanAll();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
after(() => {
|
|
16
|
+
nock.cleanAll();
|
|
17
|
+
nock.restore();
|
|
18
|
+
});
|
|
19
|
+
|
|
10
20
|
it('should load the templates and csv', async () => {
|
|
11
21
|
const options = {
|
|
12
22
|
csvFilename: path.join(__dirname, 'data/variables.csv'),
|
|
@@ -227,4 +237,88 @@ describe('vendor credentials test', () => {
|
|
|
227
237
|
},
|
|
228
238
|
]);
|
|
229
239
|
});
|
|
240
|
+
|
|
241
|
+
it('should post prepared person and offer payloads when endpoint is provided', async () => {
|
|
242
|
+
const endpoint = 'https://vendor.example';
|
|
243
|
+
const firstPerson = {
|
|
244
|
+
emails: [{ email: 'joan.lee@sap.com' }],
|
|
245
|
+
firstName: { localized: { en: 'Joan' } },
|
|
246
|
+
lastName: { localized: { en: 'Lee' } },
|
|
247
|
+
};
|
|
248
|
+
const secondPerson = {
|
|
249
|
+
emails: [{ email: 'john.smith@sap.com' }],
|
|
250
|
+
firstName: { localized: { en: 'John' } },
|
|
251
|
+
lastName: { localized: { en: 'Smith' } },
|
|
252
|
+
};
|
|
253
|
+
const firstOffer = {
|
|
254
|
+
type: ['OpenBadgeV1.0'],
|
|
255
|
+
issuer: {
|
|
256
|
+
id: 'did:ion:sap123',
|
|
257
|
+
},
|
|
258
|
+
credentialSubject: {
|
|
259
|
+
vendorUserId: 'joan.lee@sap.com',
|
|
260
|
+
holds: {
|
|
261
|
+
name: 'SAP Sapphire Attendance',
|
|
262
|
+
description:
|
|
263
|
+
'Digital Badge for the Conference Attendees of SAPs Sapphire Conference',
|
|
264
|
+
type: 'BadgeClass',
|
|
265
|
+
issuer: {
|
|
266
|
+
type: 'Profile',
|
|
267
|
+
id: 'did:ion:sap123',
|
|
268
|
+
name: 'SAP',
|
|
269
|
+
uri: 'https://sap.com',
|
|
270
|
+
},
|
|
271
|
+
image: 'https://example.com/badge-image.png',
|
|
272
|
+
criteria: 'https://example.com/sap/criteria.html',
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
const secondOffer = {
|
|
277
|
+
type: ['OpenBadgeV1.0'],
|
|
278
|
+
issuer: {
|
|
279
|
+
id: 'did:ion:sap123',
|
|
280
|
+
},
|
|
281
|
+
credentialSubject: {
|
|
282
|
+
vendorUserId: 'john.smith@sap.com',
|
|
283
|
+
holds: {
|
|
284
|
+
name: 'SAP Sapphire Attendance',
|
|
285
|
+
description:
|
|
286
|
+
'Digital Badge for the Conference Attendees of SAPs Sapphire Conference',
|
|
287
|
+
type: 'BadgeClass',
|
|
288
|
+
issuer: {
|
|
289
|
+
type: 'Profile',
|
|
290
|
+
id: 'did:ion:sap123',
|
|
291
|
+
name: 'SAP',
|
|
292
|
+
uri: 'https://sap.com',
|
|
293
|
+
},
|
|
294
|
+
image: 'https://example.com/badge-image.png',
|
|
295
|
+
criteria: 'https://example.com/sap/criteria.html',
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const scope = nock(endpoint, {
|
|
301
|
+
reqheaders: { Authorization: 'Bearer fakeToken' },
|
|
302
|
+
})
|
|
303
|
+
.post('/api/users', firstPerson)
|
|
304
|
+
.reply(200, { id: 'person-id-1' })
|
|
305
|
+
.post('/api/offers', firstOffer)
|
|
306
|
+
.reply(200, { id: 'offer-id-1' })
|
|
307
|
+
.post('/api/users', secondPerson)
|
|
308
|
+
.reply(200, { id: 'person-id-2' })
|
|
309
|
+
.post('/api/offers', secondOffer)
|
|
310
|
+
.reply(200, { id: 'offer-id-2' });
|
|
311
|
+
|
|
312
|
+
const options = {
|
|
313
|
+
csvFilename: path.join(__dirname, 'data/variables.csv'),
|
|
314
|
+
offerTemplateFilename: path.join(__dirname, 'data/offer.template.json'),
|
|
315
|
+
personTemplateFilename: path.join(__dirname, 'data/person.template.json'),
|
|
316
|
+
endpoint,
|
|
317
|
+
authToken: 'fakeToken',
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
await expect(executeVendorCredentials(options)).resolves.toBeUndefined();
|
|
321
|
+
|
|
322
|
+
scope.done();
|
|
323
|
+
});
|
|
230
324
|
});
|