@verii/server-mockvendor 1.0.0-pre.1752076816

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.
Files changed (82) hide show
  1. package/.localdev.env +15 -0
  2. package/.standalone.env +5 -0
  3. package/LICENSE +201 -0
  4. package/docker/compose.yml +25 -0
  5. package/jest.config.js +20 -0
  6. package/multilingual-string.schema.json +40 -0
  7. package/package.json +70 -0
  8. package/src/config/config.js +55 -0
  9. package/src/controllers/api/accepted-offers/controller.js +9 -0
  10. package/src/controllers/api/accepted-offers/repo.js +25 -0
  11. package/src/controllers/api/applicants/controller.js +9 -0
  12. package/src/controllers/api/applicants/repo.js +30 -0
  13. package/src/controllers/api/create_did_key/controller.js +29 -0
  14. package/src/controllers/api/create_did_key/schemas/index.js +4 -0
  15. package/src/controllers/api/create_did_key/schemas/jwk-did-request.schema.js +20 -0
  16. package/src/controllers/api/create_did_key/schemas/jwk-did-response.schema.js +41 -0
  17. package/src/controllers/api/create_jwk/controller.js +35 -0
  18. package/src/controllers/api/create_jwk/schemas/index.js +3 -0
  19. package/src/controllers/api/create_jwk/schemas/jwk-response.schema.js +33 -0
  20. package/src/controllers/api/credential-submissions/controller.js +59 -0
  21. package/src/controllers/api/credential-submissions/repo.js +16 -0
  22. package/src/controllers/api/identifications/controller.js +67 -0
  23. package/src/controllers/api/identifications/repo.js +22 -0
  24. package/src/controllers/api/issuing-exchanges/controller.js +218 -0
  25. package/src/controllers/api/issuing-exchanges/fetchers.js +45 -0
  26. package/src/controllers/api/issuing-exchanges/repo.js +27 -0
  27. package/src/controllers/api/jwt/controller.js +69 -0
  28. package/src/controllers/api/jwt/schemas/index.js +6 -0
  29. package/src/controllers/api/jwt/schemas/jwt-request.schema.js +40 -0
  30. package/src/controllers/api/jwt/schemas/jwt-response.schema.js +14 -0
  31. package/src/controllers/api/jwt/schemas/jwt-verify-request.schema.js +17 -0
  32. package/src/controllers/api/jwt/schemas/jwt-verify-response.schema.js +17 -0
  33. package/src/controllers/api/offers/autohooks.js +5 -0
  34. package/src/controllers/api/offers/controller.js +87 -0
  35. package/src/controllers/api/offers/new-mockvendor-offer.schema.js +22 -0
  36. package/src/controllers/api/offers/repo.js +33 -0
  37. package/src/controllers/api/users/controller.js +20 -0
  38. package/src/controllers/api/users/repo.js +29 -0
  39. package/src/controllers/autohooks.js +22 -0
  40. package/src/controllers/inspection/controller.js +39 -0
  41. package/src/controllers/issuing/controller.js +158 -0
  42. package/src/controllers/registrar/controller.js +67 -0
  43. package/src/controllers/registrar/repo.js +24 -0
  44. package/src/controllers/root/controller.js +15 -0
  45. package/src/controllers/schemas/index.js +21 -0
  46. package/src/controllers/schemas/issuer-data.schema.json +26 -0
  47. package/src/entities/index.js +4 -0
  48. package/src/entities/key-pairs/index.js +3 -0
  49. package/src/entities/key-pairs/key-pairs.js +73 -0
  50. package/src/entities/offers/index.js +3 -0
  51. package/src/entities/offers/schemas/generate-offers.schema.js +30 -0
  52. package/src/entities/offers/schemas/index.js +3 -0
  53. package/src/index.js +19 -0
  54. package/src/init-server.js +34 -0
  55. package/src/main.js +18 -0
  56. package/src/standalone.js +8 -0
  57. package/src/start-app-server.js +32 -0
  58. package/test/accepted-offers.test.js +47 -0
  59. package/test/api-users.test.js +170 -0
  60. package/test/create_did_key-controller.test.js +94 -0
  61. package/test/create_jwk-controller.test.js +86 -0
  62. package/test/credential-submissions.test.js +331 -0
  63. package/test/factories/accepted-offers.factory.js +16 -0
  64. package/test/factories/delayed-offer.factory.js +17 -0
  65. package/test/factories/identifications.factory.js +33 -0
  66. package/test/factories/offers.factory.js +64 -0
  67. package/test/factories/users.factory.js +24 -0
  68. package/test/helpers/PastEmploymentPosition-2007-2009-Junior-Project-Manager.json +26 -0
  69. package/test/helpers/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
  70. package/test/helpers/helpers/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
  71. package/test/helpers/latest-Adam-Smith.json +49 -0
  72. package/test/helpers/legacy-Adam-Smith.json +33 -0
  73. package/test/helpers/mockvendor-build-fastify.js +16 -0
  74. package/test/helpers/tools/verifgen/templates/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
  75. package/test/identifications.test.js +56 -0
  76. package/test/issuing-exchanges.test.js +335 -0
  77. package/test/issuing-identify.test.js +137 -0
  78. package/test/jwt-controller.test.js +320 -0
  79. package/test/offers.test.js +682 -0
  80. package/test/registrar.test.js +276 -0
  81. package/test/root.test.js +25 -0
  82. package/test/swagger.test.js +21 -0
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ generateOffersSchema: require('./generate-offers.schema'),
3
+ };
package/src/index.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright 2023 Velocity Team
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ module.exports = {
18
+ ...require('./start-app-server'),
19
+ };
@@ -0,0 +1,34 @@
1
+ const initRequest = require('@verii/request');
2
+ const path = require('path');
3
+ const AutoLoad = require('@fastify/autoload');
4
+
5
+ const initServer = (server) => {
6
+ return server
7
+ .register(AutoLoad, {
8
+ dir: path.join(__dirname, 'controllers'),
9
+ ignorePattern: /controller(\.ts|\.js|\.cjs|\.mjs)$/,
10
+ indexPattern: /.*repo(\.ts|\.js|\.cjs|\.mjs)$/,
11
+ })
12
+ .register(AutoLoad, {
13
+ dir: path.join(__dirname, 'controllers'),
14
+ autoHooks: true,
15
+ cascadeHooks: true,
16
+ indexPattern: /controller(\.ts|\.js|\.cjs|\.mjs)$/,
17
+ })
18
+ .after(() =>
19
+ server
20
+ .decorate(
21
+ 'baseAgentFetch',
22
+ initRequest({
23
+ ...server.config,
24
+ prefixUrl: server.config.agentUrl,
25
+ })
26
+ )
27
+ .decorateRequest('agentFetch', null)
28
+ .addHook('preValidation', async (req) => {
29
+ req.agentFetch = server.baseAgentFetch(req);
30
+ })
31
+ );
32
+ };
33
+
34
+ module.exports = { initServer };
package/src/main.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright 2023 Velocity Team
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ const { startAppServer } = require('./start-app-server');
17
+
18
+ startAppServer();
@@ -0,0 +1,8 @@
1
+ /* istanbul ignore file */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ const dotenv = require('dotenv');
4
+
5
+ dotenv.config({ path: '.standalone.env' });
6
+ dotenv.config({ path: '.localdev.env' });
7
+
8
+ require('./main');
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Copyright 2025 Velocity Team
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ /* istanbul ignore next */
19
+ const { flow } = require('lodash/fp');
20
+ const { createServer, listenServer } = require('@verii/server-provider');
21
+ const { initServer } = require('./init-server');
22
+ const config = require('./config/config');
23
+
24
+ process.on('unhandledRejection', (error) => {
25
+ console.error(error);
26
+ process.exit(1);
27
+ });
28
+
29
+ const startAppServer = () =>
30
+ flow(createServer, initServer, listenServer)(config);
31
+
32
+ module.exports = { startAppServer };
@@ -0,0 +1,47 @@
1
+ const { mongoDb } = require('@spencejs/spence-mongo-repos');
2
+ const {
3
+ ISO_DATETIME_FORMAT,
4
+ OBJECT_ID_FORMAT,
5
+ } = require('@verii/test-regexes');
6
+ const buildFastify = require('./helpers/mockvendor-build-fastify');
7
+ const initAcceptedOffersFactory = require('./factories/accepted-offers.factory');
8
+
9
+ describe('Accepted Offer managment', () => {
10
+ let fastify;
11
+ let persistAcceptedOffers;
12
+
13
+ beforeAll(async () => {
14
+ fastify = buildFastify();
15
+ await fastify.ready();
16
+ ({ persistAcceptedOffers } = initAcceptedOffersFactory(fastify));
17
+ });
18
+
19
+ beforeEach(async () => {
20
+ await mongoDb().collection('acceptedOffers').deleteMany({});
21
+ });
22
+
23
+ afterAll(async () => {
24
+ await mongoDb().collection('acceptedOffers').deleteMany({});
25
+ await fastify.close();
26
+ });
27
+
28
+ it('should retrieve the accepted offers', async () => {
29
+ const acceptedOffer = await persistAcceptedOffers();
30
+ const response = await fastify.injectJson({
31
+ method: 'GET',
32
+ url: '/api/accepted-offers',
33
+ });
34
+ expect(response.statusCode).toEqual(200);
35
+ expect(response.json).toEqual(
36
+ expect.arrayContaining([
37
+ {
38
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
39
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
40
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
41
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
42
+ ...acceptedOffer,
43
+ },
44
+ ])
45
+ );
46
+ });
47
+ });
@@ -0,0 +1,170 @@
1
+ const { mongoDb } = require('@spencejs/spence-mongo-repos');
2
+ const {
3
+ ISO_DATETIME_FORMAT,
4
+ OBJECT_ID_FORMAT,
5
+ } = require('@verii/test-regexes');
6
+ const { map, omit, toUpper } = require('lodash/fp');
7
+ const buildFastify = require('./helpers/mockvendor-build-fastify');
8
+ const initUserFactory = require('./factories/users.factory');
9
+
10
+ describe('Users API Test Suite', () => {
11
+ let fastify;
12
+ let newUser;
13
+ let persistUser;
14
+
15
+ beforeAll(async () => {
16
+ fastify = buildFastify();
17
+ await fastify.ready();
18
+ ({ newUser, persistUser } = initUserFactory(fastify));
19
+ });
20
+
21
+ beforeEach(async () => {
22
+ await mongoDb().collection('users').deleteMany({});
23
+ });
24
+
25
+ afterAll(async () => {
26
+ await fastify.close();
27
+ });
28
+
29
+ it('should be able to create a user', async () => {
30
+ const user = await newUser();
31
+ const response = await fastify.injectJson({
32
+ method: 'POST',
33
+ url: '/api/users',
34
+ payload: user,
35
+ });
36
+
37
+ expect(response.statusCode).toEqual(200);
38
+ expect(response.json).toEqual({
39
+ ...user,
40
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
41
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
42
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
43
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
44
+ });
45
+ });
46
+ it('should be able to create a user with an uppercase email', async () => {
47
+ const user = await newUser();
48
+ const response = await fastify.injectJson({
49
+ method: 'POST',
50
+ url: '/api/users',
51
+ payload: { ...user, emails: map(toUpper, user.emails) },
52
+ });
53
+
54
+ expect(response.statusCode).toEqual(200);
55
+ expect(response.json).toEqual({
56
+ ...user,
57
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
58
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
59
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
60
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
61
+ });
62
+ });
63
+ it('should be able to create a user with a token', async () => {
64
+ const user = await newUser({ token: 'foo' });
65
+ const response = await fastify.injectJson({
66
+ method: 'POST',
67
+ url: '/api/users',
68
+ payload: { ...user, emails: map(toUpper, user.emails) },
69
+ });
70
+
71
+ expect(response.statusCode).toEqual(200);
72
+ expect(response.json).toEqual({
73
+ ...user,
74
+ token: 'foo',
75
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
76
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
77
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
78
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
79
+ });
80
+ });
81
+ it('should be able to get a user', async () => {
82
+ const user = await persistUser({ token: 'foo' });
83
+ const response = await fastify.injectJson({
84
+ method: 'GET',
85
+ url: `/api/users/${user._id}`,
86
+ });
87
+
88
+ expect(response.statusCode).toEqual(200);
89
+ expect(response.json).toEqual({
90
+ ...user,
91
+ token: 'foo',
92
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
93
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
94
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
95
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
96
+ });
97
+ });
98
+ it('should be able to get all users', async () => {
99
+ const [user1, user2] = await Promise.all([persistUser(), persistUser()]);
100
+ const response = await fastify.injectJson({
101
+ method: 'GET',
102
+ url: '/api/users',
103
+ });
104
+ expect(response.statusCode).toEqual(200);
105
+ expect(response.json).toEqual(
106
+ expect.arrayContaining([
107
+ {
108
+ ...user1,
109
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
110
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
111
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
112
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
113
+ },
114
+ {
115
+ ...user2,
116
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
117
+ _id: expect.stringMatching(OBJECT_ID_FORMAT),
118
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
119
+ createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
120
+ },
121
+ ])
122
+ );
123
+ });
124
+ it('should be able to update a user', async () => {
125
+ const [user1] = await Promise.all([persistUser(), persistUser()]);
126
+ const response = await fastify.injectJson({
127
+ method: 'PUT',
128
+ url: `/api/users/${user1._id}`,
129
+ payload: {
130
+ ...omit(['id', '_id', 'createdAt', 'updatedAt'], user1),
131
+ firstName: 'Mary',
132
+ token: 'foo',
133
+ },
134
+ });
135
+ expect(response.statusCode).toEqual(200);
136
+ expect(response.json).toEqual({
137
+ ...user1,
138
+ id: expect.stringMatching(OBJECT_ID_FORMAT),
139
+ updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
140
+ token: 'foo',
141
+ firstName: 'Mary',
142
+ });
143
+ });
144
+ it('should be able to delete a user', async () => {
145
+ const [, user2] = await Promise.all([persistUser(), persistUser()]);
146
+ const getResponsePre = await fastify.injectJson({
147
+ method: 'GET',
148
+ url: '/api/users',
149
+ });
150
+ expect(getResponsePre.json).toEqual(
151
+ expect.arrayContaining([
152
+ { ...user2, id: expect.stringMatching(OBJECT_ID_FORMAT) },
153
+ ])
154
+ );
155
+ const response = await fastify.injectJson({
156
+ method: 'DELETE',
157
+ url: `/api/users/${user2._id}`,
158
+ });
159
+ expect(response.statusCode).toEqual(200);
160
+ const getResponsePost = await fastify.injectJson({
161
+ method: 'GET',
162
+ url: '/api/users',
163
+ });
164
+ expect(getResponsePost.json).not.toEqual(
165
+ expect.arrayContaining([
166
+ { ...user2, id: expect.stringMatching(OBJECT_ID_FORMAT) },
167
+ ])
168
+ );
169
+ });
170
+ });
@@ -0,0 +1,94 @@
1
+ const buildFastify = require('./helpers/mockvendor-build-fastify');
2
+
3
+ describe('create_did_key controller test suite', () => {
4
+ let fastify;
5
+
6
+ beforeAll(async () => {
7
+ fastify = await buildFastify({});
8
+ await fastify.ready();
9
+ });
10
+
11
+ afterAll(async () => {
12
+ await fastify.close();
13
+ });
14
+
15
+ it('should return 400 if the request body is invalid', async () => {
16
+ const response = await fastify.injectJson({
17
+ method: 'POST',
18
+ url: '/api/create_did_key',
19
+ payload: {},
20
+ });
21
+ expect(response.statusCode).toEqual(400);
22
+ expect(response.json).toStrictEqual({
23
+ code: 'FST_ERR_VALIDATION',
24
+ message: "body must have required property 'crv'",
25
+ statusCode: 400,
26
+ error: 'Bad Request',
27
+ });
28
+ });
29
+
30
+ it('should return 400 if the crv is invalid', async () => {
31
+ const response = await fastify.injectJson({
32
+ method: 'POST',
33
+ url: '/api/create_did_key',
34
+ payload: {
35
+ crv: 'abc',
36
+ },
37
+ });
38
+ expect(response.statusCode).toEqual(400);
39
+ expect(response.json).toStrictEqual({
40
+ code: 'FST_ERR_VALIDATION',
41
+ message: 'body/crv must be equal to one of the allowed values',
42
+ statusCode: 400,
43
+ error: 'Bad Request',
44
+ });
45
+ });
46
+
47
+ it('should create a new P-256 did key', async () => {
48
+ const response = await fastify.injectJson({
49
+ method: 'POST',
50
+ url: '/api/create_did_key',
51
+ payload: {
52
+ crv: 'P-256',
53
+ didMethod: 'did:jwk',
54
+ didKeyId: 'abc1',
55
+ },
56
+ });
57
+ expect(response.statusCode).toEqual(200);
58
+ expect(response.json).toStrictEqual({
59
+ keyId: expect.any(String),
60
+ kid: expect.any(String),
61
+ did: expect.any(String),
62
+ publicJwk: {
63
+ crv: 'P-256',
64
+ kty: 'EC',
65
+ x: expect.any(String),
66
+ y: expect.any(String),
67
+ },
68
+ });
69
+ });
70
+
71
+ it('should create a new secp256k1 did key', async () => {
72
+ const response = await fastify.injectJson({
73
+ method: 'POST',
74
+ url: '/api/create_did_key',
75
+ payload: {
76
+ crv: 'secp256k1',
77
+ didMethod: 'did:jwk',
78
+ didKeyId: 'abc1',
79
+ },
80
+ });
81
+ expect(response.statusCode).toEqual(200);
82
+ expect(response.json).toStrictEqual({
83
+ keyId: expect.any(String),
84
+ kid: expect.any(String),
85
+ did: expect.any(String),
86
+ publicJwk: {
87
+ crv: 'secp256k1',
88
+ kty: 'EC',
89
+ x: expect.any(String),
90
+ y: expect.any(String),
91
+ },
92
+ });
93
+ });
94
+ });
@@ -0,0 +1,86 @@
1
+ const buildFastify = require('./helpers/mockvendor-build-fastify');
2
+
3
+ describe('create_jwk controller test suite', () => {
4
+ let fastify;
5
+
6
+ beforeAll(async () => {
7
+ fastify = await buildFastify({});
8
+ await fastify.ready();
9
+ });
10
+
11
+ afterAll(async () => {
12
+ await fastify.close();
13
+ });
14
+
15
+ it('should return 400 if the request body is invalid', async () => {
16
+ const response = await fastify.injectJson({
17
+ method: 'POST',
18
+ url: '/api/create_jwk',
19
+ payload: {},
20
+ });
21
+ expect(response.statusCode).toEqual(400);
22
+ expect(response.json).toStrictEqual({
23
+ code: 'FST_ERR_VALIDATION',
24
+ message: "body must have required property 'crv'",
25
+ statusCode: 400,
26
+ error: 'Bad Request',
27
+ });
28
+ });
29
+
30
+ it('should return 400 if the crv is invalid', async () => {
31
+ const response = await fastify.injectJson({
32
+ method: 'POST',
33
+ url: '/api/create_jwk',
34
+ payload: {
35
+ crv: 'abc',
36
+ },
37
+ });
38
+ expect(response.statusCode).toEqual(400);
39
+ expect(response.json).toStrictEqual({
40
+ code: 'FST_ERR_VALIDATION',
41
+ message: 'body/crv must be equal to one of the allowed values',
42
+ statusCode: 400,
43
+ error: 'Bad Request',
44
+ });
45
+ });
46
+
47
+ it('should create a new jwk', async () => {
48
+ const response = await fastify.injectJson({
49
+ method: 'POST',
50
+ url: '/api/create_jwk',
51
+ payload: {
52
+ crv: 'P-256',
53
+ },
54
+ });
55
+ expect(response.statusCode).toEqual(200);
56
+ expect(response.json).toStrictEqual({
57
+ keyId: expect.any(String),
58
+ jwk: {
59
+ crv: 'P-256',
60
+ kty: 'EC',
61
+ x: expect.any(String),
62
+ y: expect.any(String),
63
+ },
64
+ });
65
+ });
66
+
67
+ it('should create a new jwk', async () => {
68
+ const response = await fastify.injectJson({
69
+ method: 'POST',
70
+ url: '/api/create_jwk',
71
+ payload: {
72
+ crv: 'secp256k1',
73
+ },
74
+ });
75
+ expect(response.statusCode).toEqual(200);
76
+ expect(response.json).toStrictEqual({
77
+ keyId: expect.any(String),
78
+ jwk: {
79
+ crv: 'secp256k1',
80
+ kty: 'EC',
81
+ x: expect.any(String),
82
+ y: expect.any(String),
83
+ },
84
+ });
85
+ });
86
+ });