@toa.io/extensions.exposition 0.22.0 → 0.23.0-dev.0
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/components/identity.basic/source/authenticate.ts +9 -6
- package/components/identity.basic/source/create.ts +1 -2
- package/components/identity.basic/source/transit.ts +10 -6
- package/components/identity.basic/source/types.ts +2 -2
- package/components/identity.tokens/source/authenticate.ts +6 -5
- package/components/identity.tokens/source/decrypt.ts +12 -4
- package/components/identity.tokens/source/encrypt.test.ts +1 -1
- package/components/identity.tokens/source/types.ts +2 -2
- package/components/octets.storage/manifest.toa.yaml +26 -0
- package/components/octets.storage/operations/delete.js +7 -0
- package/components/octets.storage/operations/fetch.js +46 -0
- package/components/octets.storage/operations/get.js +7 -0
- package/components/octets.storage/operations/list.js +7 -0
- package/components/octets.storage/operations/permute.js +7 -0
- package/components/octets.storage/operations/store.js +11 -0
- package/cucumber.js +0 -1
- package/documentation/octets.md +196 -0
- package/documentation/protocol.md +49 -5
- package/features/access.feature +1 -0
- package/features/errors.feature +18 -0
- package/features/identity.basic.feature +2 -0
- package/features/octets.feature +295 -0
- package/features/octets.workflows.feature +114 -0
- package/features/routes.feature +40 -0
- package/features/steps/HTTP.ts +47 -5
- package/features/steps/Parameters.ts +5 -1
- package/features/steps/Workspace.ts +3 -2
- package/features/steps/components/octets.tester/manifest.toa.yaml +15 -0
- package/features/steps/components/octets.tester/operations/bar.js +12 -0
- package/features/steps/components/octets.tester/operations/baz.js +11 -0
- package/features/steps/components/octets.tester/operations/diversify.js +14 -0
- package/features/steps/components/octets.tester/operations/err.js +16 -0
- package/features/steps/components/octets.tester/operations/foo.js +7 -0
- package/features/steps/components/octets.tester/operations/lenna.png +0 -0
- package/features/steps/components/pots/manifest.toa.yaml +1 -1
- package/features/streams.feature +5 -1
- package/package.json +11 -10
- package/readme.md +7 -5
- package/schemas/octets/context.cos.yaml +1 -0
- package/schemas/octets/delete.cos.yaml +1 -0
- package/schemas/octets/fetch.cos.yaml +3 -0
- package/schemas/octets/list.cos.yaml +1 -0
- package/schemas/octets/permute.cos.yaml +1 -0
- package/schemas/octets/store.cos.yaml +3 -0
- package/source/Gateway.ts +12 -7
- package/source/HTTP/Server.fixtures.ts +2 -6
- package/source/HTTP/Server.test.ts +7 -31
- package/source/HTTP/Server.ts +31 -16
- package/source/HTTP/exceptions.ts +2 -12
- package/source/HTTP/formats/index.ts +7 -4
- package/source/HTTP/formats/json.ts +3 -0
- package/source/HTTP/formats/msgpack.ts +3 -0
- package/source/HTTP/formats/text.ts +3 -0
- package/source/HTTP/formats/yaml.ts +3 -0
- package/source/HTTP/messages.test.ts +3 -49
- package/source/HTTP/messages.ts +58 -33
- package/source/RTD/Route.ts +1 -1
- package/source/RTD/segment.ts +2 -1
- package/source/Remotes.ts +8 -0
- package/source/directives/auth/Family.ts +25 -22
- package/source/directives/auth/Incept.ts +3 -3
- package/source/directives/auth/Rule.ts +1 -1
- package/source/directives/auth/types.ts +2 -2
- package/source/directives/index.ts +2 -1
- package/source/directives/octets/Context.ts +18 -0
- package/source/directives/octets/Delete.ts +32 -0
- package/source/directives/octets/Family.ts +68 -0
- package/source/directives/octets/Fetch.ts +85 -0
- package/source/directives/octets/List.ts +32 -0
- package/source/directives/octets/Permute.ts +37 -0
- package/source/directives/octets/Store.ts +158 -0
- package/source/directives/octets/index.ts +3 -0
- package/source/directives/octets/schemas.ts +12 -0
- package/source/directives/octets/types.ts +13 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
Feature: Octets directive family
|
|
2
|
+
|
|
3
|
+
Background:
|
|
4
|
+
Given the annotation:
|
|
5
|
+
"""yaml
|
|
6
|
+
/:
|
|
7
|
+
auth:anonymous: true
|
|
8
|
+
octets:context: octets
|
|
9
|
+
POST:
|
|
10
|
+
octets:store: ~
|
|
11
|
+
GET:
|
|
12
|
+
octets:list: ~
|
|
13
|
+
PUT:
|
|
14
|
+
octets:permute: ~
|
|
15
|
+
/*:
|
|
16
|
+
GET:
|
|
17
|
+
octets:fetch: ~
|
|
18
|
+
DELETE:
|
|
19
|
+
octets:delete: ~
|
|
20
|
+
/media:
|
|
21
|
+
/jpeg:
|
|
22
|
+
POST:
|
|
23
|
+
octets:store:
|
|
24
|
+
accept: image/jpeg
|
|
25
|
+
/jpeg-or-png:
|
|
26
|
+
POST:
|
|
27
|
+
octets:store:
|
|
28
|
+
accept:
|
|
29
|
+
- image/jpeg
|
|
30
|
+
- image/png
|
|
31
|
+
/images:
|
|
32
|
+
POST:
|
|
33
|
+
octets:store:
|
|
34
|
+
accept: image/*
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
Scenario: Basic storage operations
|
|
38
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
39
|
+
"""
|
|
40
|
+
POST / HTTP/1.1
|
|
41
|
+
accept: application/yaml
|
|
42
|
+
content-type: application/octet-stream
|
|
43
|
+
"""
|
|
44
|
+
Then the following reply is sent:
|
|
45
|
+
"""
|
|
46
|
+
201 Created
|
|
47
|
+
content-type: application/yaml
|
|
48
|
+
|
|
49
|
+
id: 10cf16b458f759e0d617f2f3d83599ff
|
|
50
|
+
type: application/octet-stream
|
|
51
|
+
size: 8169
|
|
52
|
+
"""
|
|
53
|
+
When the following request is received:
|
|
54
|
+
"""
|
|
55
|
+
GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
|
|
56
|
+
"""
|
|
57
|
+
Then the stream equals to `lenna.ascii` is sent with the following headers:
|
|
58
|
+
"""
|
|
59
|
+
200 OK
|
|
60
|
+
content-type: application/octet-stream
|
|
61
|
+
content-length: 8169
|
|
62
|
+
etag: ${{ ETAG }}
|
|
63
|
+
"""
|
|
64
|
+
When the following request is received:
|
|
65
|
+
"""
|
|
66
|
+
GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
|
|
67
|
+
if-none-match: ${{ ETAG }}
|
|
68
|
+
"""
|
|
69
|
+
Then the following reply is sent:
|
|
70
|
+
"""
|
|
71
|
+
304 Not Modified
|
|
72
|
+
"""
|
|
73
|
+
When the following request is received:
|
|
74
|
+
"""
|
|
75
|
+
GET /10cf16b458f759e0d617f2f3d83599ff:meta HTTP/1.1
|
|
76
|
+
accept: text/plain
|
|
77
|
+
"""
|
|
78
|
+
Then the following reply is sent:
|
|
79
|
+
"""
|
|
80
|
+
403 Forbidden
|
|
81
|
+
|
|
82
|
+
Metadata is not accessible.
|
|
83
|
+
"""
|
|
84
|
+
When the following request is received:
|
|
85
|
+
"""
|
|
86
|
+
GET / HTTP/1.1
|
|
87
|
+
accept: application/yaml
|
|
88
|
+
"""
|
|
89
|
+
Then the following reply is sent:
|
|
90
|
+
"""
|
|
91
|
+
200 OK
|
|
92
|
+
content-type: application/yaml
|
|
93
|
+
|
|
94
|
+
- 10cf16b458f759e0d617f2f3d83599ff
|
|
95
|
+
"""
|
|
96
|
+
When the following request is received:
|
|
97
|
+
"""
|
|
98
|
+
GET /10cf16b458f759e0d617f2f3d83599ff?foo=bar HTTP/1.1
|
|
99
|
+
"""
|
|
100
|
+
Then the following reply is sent:
|
|
101
|
+
"""
|
|
102
|
+
404 Not Found
|
|
103
|
+
"""
|
|
104
|
+
When the following request is received:
|
|
105
|
+
"""
|
|
106
|
+
DELETE /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
|
|
107
|
+
"""
|
|
108
|
+
Then the following reply is sent:
|
|
109
|
+
"""
|
|
110
|
+
204 No Content
|
|
111
|
+
"""
|
|
112
|
+
When the following request is received:
|
|
113
|
+
"""
|
|
114
|
+
GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
|
|
115
|
+
"""
|
|
116
|
+
Then the following reply is sent:
|
|
117
|
+
"""
|
|
118
|
+
404 Not Found
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
Scenario: Entries permutation
|
|
122
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
123
|
+
"""
|
|
124
|
+
POST / HTTP/1.1
|
|
125
|
+
accept: application/yaml
|
|
126
|
+
content-type: application/octet-stream
|
|
127
|
+
"""
|
|
128
|
+
And the stream of `lenna.png` is received with the following headers:
|
|
129
|
+
"""
|
|
130
|
+
POST / HTTP/1.1
|
|
131
|
+
accept: application/yaml
|
|
132
|
+
content-type: application/octet-stream
|
|
133
|
+
"""
|
|
134
|
+
When the following request is received:
|
|
135
|
+
"""
|
|
136
|
+
GET / HTTP/1.1
|
|
137
|
+
accept: application/yaml
|
|
138
|
+
"""
|
|
139
|
+
Then the following reply is sent:
|
|
140
|
+
"""
|
|
141
|
+
200 OK
|
|
142
|
+
content-type: application/yaml
|
|
143
|
+
|
|
144
|
+
- 10cf16b458f759e0d617f2f3d83599ff
|
|
145
|
+
- 814a0034f5549e957ee61360d87457e5
|
|
146
|
+
"""
|
|
147
|
+
When the following request is received:
|
|
148
|
+
"""
|
|
149
|
+
PUT / HTTP/1.1
|
|
150
|
+
content-type: application/yaml
|
|
151
|
+
|
|
152
|
+
- 814a0034f5549e957ee61360d87457e5
|
|
153
|
+
- 10cf16b458f759e0d617f2f3d83599ff
|
|
154
|
+
"""
|
|
155
|
+
Then the following reply is sent:
|
|
156
|
+
"""
|
|
157
|
+
204 No Content
|
|
158
|
+
"""
|
|
159
|
+
When the following request is received:
|
|
160
|
+
"""
|
|
161
|
+
GET / HTTP/1.1
|
|
162
|
+
accept: application/yaml
|
|
163
|
+
"""
|
|
164
|
+
Then the following reply is sent:
|
|
165
|
+
"""
|
|
166
|
+
200 OK
|
|
167
|
+
content-type: application/yaml
|
|
168
|
+
|
|
169
|
+
- 814a0034f5549e957ee61360d87457e5
|
|
170
|
+
- 10cf16b458f759e0d617f2f3d83599ff
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
Scenario: Media type control
|
|
174
|
+
When the stream of `lenna.png` is received with the following headers:
|
|
175
|
+
"""
|
|
176
|
+
POST /media/jpeg-or-png/ HTTP/1.1
|
|
177
|
+
content-type: image/jpeg
|
|
178
|
+
"""
|
|
179
|
+
Then the following reply is sent:
|
|
180
|
+
"""
|
|
181
|
+
400 Bad Request
|
|
182
|
+
"""
|
|
183
|
+
When the stream of `lenna.png` is received with the following headers:
|
|
184
|
+
"""
|
|
185
|
+
POST /media/jpeg/ HTTP/1.1
|
|
186
|
+
"""
|
|
187
|
+
Then the following reply is sent:
|
|
188
|
+
"""
|
|
189
|
+
415 Unsupported Media Type
|
|
190
|
+
"""
|
|
191
|
+
When the stream of `lenna.png` is received with the following headers:
|
|
192
|
+
"""
|
|
193
|
+
POST /media/jpeg-or-png/ HTTP/1.1
|
|
194
|
+
"""
|
|
195
|
+
Then the following reply is sent:
|
|
196
|
+
"""
|
|
197
|
+
201 Created
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
Scenario Outline: Receiving <format> images
|
|
201
|
+
When the stream of `sample.<format>` is received with the following headers:
|
|
202
|
+
"""
|
|
203
|
+
POST /media/images/ HTTP/1.1
|
|
204
|
+
"""
|
|
205
|
+
Then the following reply is sent:
|
|
206
|
+
"""
|
|
207
|
+
201 Created
|
|
208
|
+
"""
|
|
209
|
+
Examples:
|
|
210
|
+
| format |
|
|
211
|
+
| jpeg |
|
|
212
|
+
| jxl |
|
|
213
|
+
| gif |
|
|
214
|
+
| heic |
|
|
215
|
+
| avif |
|
|
216
|
+
| webp |
|
|
217
|
+
|
|
218
|
+
Scenario: Fetching non-existent BLOB
|
|
219
|
+
When the following request is received:
|
|
220
|
+
"""
|
|
221
|
+
GET /whatever HTTP/1.1
|
|
222
|
+
"""
|
|
223
|
+
Then the following reply is sent:
|
|
224
|
+
"""
|
|
225
|
+
404 Not Found
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
Scenario: Fetching a BLOB with trailing slash
|
|
229
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
230
|
+
"""
|
|
231
|
+
POST / HTTP/1.1
|
|
232
|
+
accept: application/yaml
|
|
233
|
+
content-type: application/octet-stream
|
|
234
|
+
"""
|
|
235
|
+
And the following request is received:
|
|
236
|
+
"""
|
|
237
|
+
GET /10cf16b458f759e0d617f2f3d83599ff/ HTTP/1.1
|
|
238
|
+
accept: text/plain
|
|
239
|
+
"""
|
|
240
|
+
Then the following reply is sent:
|
|
241
|
+
"""
|
|
242
|
+
404 Not Found
|
|
243
|
+
content-type: text/plain
|
|
244
|
+
|
|
245
|
+
Trailing slash is redundant.
|
|
246
|
+
"""
|
|
247
|
+
|
|
248
|
+
Scenario: Accessing an Entry and the original BLOLB
|
|
249
|
+
Given the annotation:
|
|
250
|
+
"""yaml
|
|
251
|
+
debug: true
|
|
252
|
+
/:
|
|
253
|
+
auth:anonymous: true
|
|
254
|
+
octets:context: octets
|
|
255
|
+
POST:
|
|
256
|
+
octets:store: ~
|
|
257
|
+
/*:
|
|
258
|
+
GET:
|
|
259
|
+
octets:fetch:
|
|
260
|
+
meta: true
|
|
261
|
+
blob: false
|
|
262
|
+
"""
|
|
263
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
264
|
+
"""
|
|
265
|
+
POST / HTTP/1.1
|
|
266
|
+
"""
|
|
267
|
+
Then the following reply is sent:
|
|
268
|
+
"""
|
|
269
|
+
201 Created
|
|
270
|
+
"""
|
|
271
|
+
When the following request is received:
|
|
272
|
+
"""
|
|
273
|
+
GET /10cf16b458f759e0d617f2f3d83599ff:meta HTTP/1.1
|
|
274
|
+
accept: application/yaml
|
|
275
|
+
"""
|
|
276
|
+
Then the following reply is sent:
|
|
277
|
+
"""
|
|
278
|
+
200 OK
|
|
279
|
+
content-type: application/yaml
|
|
280
|
+
content-length: 124
|
|
281
|
+
|
|
282
|
+
id: 10cf16b458f759e0d617f2f3d83599ff
|
|
283
|
+
type: application/octet-stream
|
|
284
|
+
size: 8169
|
|
285
|
+
"""
|
|
286
|
+
When the following request is received:
|
|
287
|
+
"""
|
|
288
|
+
GET /10cf16b458f759e0d617f2f3d83599ff HTTP/1.1
|
|
289
|
+
"""
|
|
290
|
+
Then the following reply is sent:
|
|
291
|
+
"""
|
|
292
|
+
403 Forbidden
|
|
293
|
+
|
|
294
|
+
BLOB variant must be specified.
|
|
295
|
+
"""
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Feature: Octets storage workflows
|
|
2
|
+
|
|
3
|
+
Scenario: Running a workflow
|
|
4
|
+
Given the `octets.tester` is running
|
|
5
|
+
Given the annotation:
|
|
6
|
+
"""yaml
|
|
7
|
+
/:
|
|
8
|
+
auth:anonymous: true
|
|
9
|
+
octets:context: octets
|
|
10
|
+
POST:
|
|
11
|
+
octets:store:
|
|
12
|
+
workflow:
|
|
13
|
+
- add-foo: octets.tester.foo
|
|
14
|
+
add-bar: octets.tester.bar
|
|
15
|
+
- add-baz: octets.tester.baz
|
|
16
|
+
- diversify: octets.tester.diversify
|
|
17
|
+
/*:
|
|
18
|
+
GET:
|
|
19
|
+
octets:fetch:
|
|
20
|
+
meta: true
|
|
21
|
+
"""
|
|
22
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
23
|
+
"""
|
|
24
|
+
POST / HTTP/1.1
|
|
25
|
+
accept: application/yaml
|
|
26
|
+
content-type: application/octet-stream
|
|
27
|
+
"""
|
|
28
|
+
Then the following reply is sent:
|
|
29
|
+
"""
|
|
30
|
+
201 Created
|
|
31
|
+
content-type: multipart/yaml; boundary=cut
|
|
32
|
+
|
|
33
|
+
--cut
|
|
34
|
+
id: 10cf16b458f759e0d617f2f3d83599ff
|
|
35
|
+
type: application/octet-stream
|
|
36
|
+
size: 8169
|
|
37
|
+
--cut
|
|
38
|
+
add-foo: null
|
|
39
|
+
--cut
|
|
40
|
+
add-bar:
|
|
41
|
+
bar: baz
|
|
42
|
+
--cut
|
|
43
|
+
add-baz: null
|
|
44
|
+
--cut
|
|
45
|
+
diversify: null
|
|
46
|
+
--cut--
|
|
47
|
+
"""
|
|
48
|
+
When the following request is received:
|
|
49
|
+
"""
|
|
50
|
+
GET /10cf16b458f759e0d617f2f3d83599ff:meta HTTP/1.1
|
|
51
|
+
accept: application/yaml
|
|
52
|
+
"""
|
|
53
|
+
Then the following reply is sent:
|
|
54
|
+
"""
|
|
55
|
+
200 OK
|
|
56
|
+
content-type: application/yaml
|
|
57
|
+
|
|
58
|
+
id: 10cf16b458f759e0d617f2f3d83599ff
|
|
59
|
+
type: application/octet-stream
|
|
60
|
+
size: 8169
|
|
61
|
+
meta:
|
|
62
|
+
foo: bar
|
|
63
|
+
bar: baz
|
|
64
|
+
baz: qux
|
|
65
|
+
"""
|
|
66
|
+
When the following request is received:
|
|
67
|
+
"""
|
|
68
|
+
GET /10cf16b458f759e0d617f2f3d83599ff.hello.png HTTP/1.1
|
|
69
|
+
"""
|
|
70
|
+
Then the stream equals to `lenna.png` is sent with the following headers:
|
|
71
|
+
"""
|
|
72
|
+
200 OK
|
|
73
|
+
content-type: image/png
|
|
74
|
+
content-length: 473831
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
Scenario: Getting error when adding metadata to a file
|
|
78
|
+
Given the `octets.tester` is running
|
|
79
|
+
Given the annotation:
|
|
80
|
+
"""yaml
|
|
81
|
+
/:
|
|
82
|
+
auth:anonymous: true
|
|
83
|
+
octets:context: octets
|
|
84
|
+
POST:
|
|
85
|
+
octets:store:
|
|
86
|
+
workflow:
|
|
87
|
+
add-foo: octets.tester.foo
|
|
88
|
+
add-bar: octets.tester.err
|
|
89
|
+
add-baz: octets.tester.baz
|
|
90
|
+
"""
|
|
91
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
92
|
+
"""
|
|
93
|
+
POST / HTTP/1.1
|
|
94
|
+
accept: application/yaml
|
|
95
|
+
content-type: application/octet-stream
|
|
96
|
+
"""
|
|
97
|
+
Then the following reply is sent:
|
|
98
|
+
"""
|
|
99
|
+
201 Created
|
|
100
|
+
content-type: multipart/yaml; boundary=cut
|
|
101
|
+
|
|
102
|
+
--cut
|
|
103
|
+
id: 10cf16b458f759e0d617f2f3d83599ff
|
|
104
|
+
type: application/octet-stream
|
|
105
|
+
size: 8169
|
|
106
|
+
--cut
|
|
107
|
+
add-foo: null
|
|
108
|
+
--cut
|
|
109
|
+
error:
|
|
110
|
+
step: add-bar
|
|
111
|
+
code: ERROR
|
|
112
|
+
message: Something went wrong
|
|
113
|
+
--cut--
|
|
114
|
+
"""
|
package/features/routes.feature
CHANGED
|
@@ -47,3 +47,43 @@ Feature: Routes
|
|
|
47
47
|
|
|
48
48
|
Hello
|
|
49
49
|
"""
|
|
50
|
+
|
|
51
|
+
Scenario: Wildcard routes
|
|
52
|
+
Given the `greeter` is running with the following manifest:
|
|
53
|
+
"""yaml
|
|
54
|
+
exposition:
|
|
55
|
+
/*:
|
|
56
|
+
GET: greet
|
|
57
|
+
/foo/*/bar:
|
|
58
|
+
GET: greet
|
|
59
|
+
"""
|
|
60
|
+
When the following request is received:
|
|
61
|
+
"""
|
|
62
|
+
GET /greeter/baz/ HTTP/1.1
|
|
63
|
+
accept: text/plain
|
|
64
|
+
"""
|
|
65
|
+
Then the following reply is sent:
|
|
66
|
+
"""
|
|
67
|
+
200 OK
|
|
68
|
+
|
|
69
|
+
Hello
|
|
70
|
+
"""
|
|
71
|
+
When the following request is received:
|
|
72
|
+
"""
|
|
73
|
+
GET /greeter/baz/qux/ HTTP/1.1
|
|
74
|
+
"""
|
|
75
|
+
Then the following reply is sent:
|
|
76
|
+
"""
|
|
77
|
+
404 Not Found
|
|
78
|
+
"""
|
|
79
|
+
When the following request is received:
|
|
80
|
+
"""
|
|
81
|
+
GET /greeter/foo/baz/bar/ HTTP/1.1
|
|
82
|
+
accept: text/plain
|
|
83
|
+
"""
|
|
84
|
+
Then the following reply is sent:
|
|
85
|
+
"""
|
|
86
|
+
200 OK
|
|
87
|
+
|
|
88
|
+
Hello
|
|
89
|
+
"""
|
package/features/steps/HTTP.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { binding, when, then } from 'cucumber-tsflow'
|
|
1
|
+
import { AssertionError } from 'node:assert'
|
|
2
|
+
import { binding, then, when } from 'cucumber-tsflow'
|
|
4
3
|
import * as http from '@toa.io/http'
|
|
5
4
|
import { trim } from '@toa.io/generic'
|
|
5
|
+
import { buffer } from '@toa.io/streams'
|
|
6
|
+
import { open } from '../../../storages/source/test/util'
|
|
6
7
|
import { Parameters } from './parameters'
|
|
7
8
|
import { Gateway } from './Gateway'
|
|
8
9
|
|
|
@@ -47,7 +48,11 @@ export class HTTP {
|
|
|
47
48
|
const match = this.response.match(rx)
|
|
48
49
|
|
|
49
50
|
if (match === null)
|
|
50
|
-
throw new AssertionError({
|
|
51
|
+
throw new AssertionError({
|
|
52
|
+
message: `Response is missing '${line}'`,
|
|
53
|
+
expected: line,
|
|
54
|
+
actual: this.response
|
|
55
|
+
})
|
|
51
56
|
|
|
52
57
|
Object.assign(this.variables, match.groups)
|
|
53
58
|
}
|
|
@@ -62,9 +67,46 @@ export class HTTP {
|
|
|
62
67
|
|
|
63
68
|
const includes = this.response.includes(line)
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
if (includes)
|
|
71
|
+
throw new AssertionError({
|
|
72
|
+
message: `Response contains '${line}'`,
|
|
73
|
+
expected: line,
|
|
74
|
+
actual: this.response
|
|
75
|
+
})
|
|
66
76
|
}
|
|
67
77
|
}
|
|
78
|
+
|
|
79
|
+
@when('the stream of `{word}` is received with the following headers:')
|
|
80
|
+
public async streamRequest (filename: string, head: string): Promise<any> {
|
|
81
|
+
head = trim(head) + '\n\n'
|
|
82
|
+
|
|
83
|
+
await this.gateway.start()
|
|
84
|
+
|
|
85
|
+
const { url, method, headers } = http.parse.request(head)
|
|
86
|
+
const href = new URL(url, this.origin).href
|
|
87
|
+
const body = open(filename)
|
|
88
|
+
const request = { method, headers, body, duplex: 'half' } as unknown as RequestInit
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const response = await fetch(href, request)
|
|
92
|
+
|
|
93
|
+
this.response = await http.parse.response(response)
|
|
94
|
+
} catch (e: any) {
|
|
95
|
+
console.error(e)
|
|
96
|
+
console.error(e.cause)
|
|
97
|
+
|
|
98
|
+
throw e
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@then('the stream equals to `{word}` is sent with the following headers:')
|
|
103
|
+
public async responseStreamMatch (filename: string, head: string): Promise<any> {
|
|
104
|
+
const buf = await buffer(open(filename))
|
|
105
|
+
const text = buf.toString('utf8')
|
|
106
|
+
const expected = head + '\n\n' + text
|
|
107
|
+
|
|
108
|
+
this.responseIncludes(expected)
|
|
109
|
+
}
|
|
68
110
|
}
|
|
69
111
|
|
|
70
112
|
const CAPTURE = /\\\$\\{\\{ (?<name>[A-Za-z_]{0,32}) \\}\\}/g
|
|
@@ -4,9 +4,13 @@ export class Parameters {
|
|
|
4
4
|
public readonly origin: string
|
|
5
5
|
|
|
6
6
|
public constructor () {
|
|
7
|
-
this.origin = 'http://
|
|
7
|
+
this.origin = 'http://127.0.0.1:8000'
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
setDefaultTimeout(10 * 1000)
|
|
12
|
+
|
|
12
13
|
process.env.TOA_DEV = '1'
|
|
14
|
+
|
|
15
|
+
// { octets: tmp:///exposition-octets }
|
|
16
|
+
process.env.TOA_STORAGES = '3gABpm9jdGV0c7h0bXA6Ly8vZXhwb3NpdGlvbi1vY3RldHM='
|
|
@@ -6,7 +6,7 @@ export class Workspace {
|
|
|
6
6
|
private root: string = devnull
|
|
7
7
|
|
|
8
8
|
public static exists
|
|
9
|
-
(
|
|
9
|
+
(_0: unknown, _1: unknown, descriptor: PropertyDescriptor): PropertyDescriptor {
|
|
10
10
|
const method = descriptor.value
|
|
11
11
|
|
|
12
12
|
descriptor.value = async function (this: Workspace, ...args: any[]): Promise<any> {
|
|
@@ -25,7 +25,8 @@ export class Workspace {
|
|
|
25
25
|
|
|
26
26
|
await directory.copy(source, target)
|
|
27
27
|
|
|
28
|
-
if (patch !== undefined)
|
|
28
|
+
if (patch !== undefined)
|
|
29
|
+
await this.patchManifest(target, patch)
|
|
29
30
|
|
|
30
31
|
return target
|
|
31
32
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { join } = require('node:path')
|
|
4
|
+
const { createReadStream } = require('node:fs')
|
|
5
|
+
|
|
6
|
+
const lenna = join(__dirname, 'lenna.png')
|
|
7
|
+
|
|
8
|
+
async function diversify (input, context) {
|
|
9
|
+
const stream = createReadStream(lenna)
|
|
10
|
+
|
|
11
|
+
return context.storages[input.storage].diversify(input.path, 'hello.png', stream)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.effect = diversify
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { setTimeout } from 'node:timers/promises'
|
|
4
|
+
|
|
5
|
+
async function err (_) {
|
|
6
|
+
await setTimeout(20)
|
|
7
|
+
|
|
8
|
+
const err = Object.create(Error.prototype)
|
|
9
|
+
|
|
10
|
+
err.code = 'ERROR'
|
|
11
|
+
err.message = 'Something went wrong'
|
|
12
|
+
|
|
13
|
+
return err
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.effect = err
|
|
Binary file
|
package/features/streams.feature
CHANGED