Skip to content

Commit 17d301a

Browse files
committed
test: adapter tests and fixes
1 parent eb4bec3 commit 17d301a

File tree

3 files changed

+171
-2
lines changed

3 files changed

+171
-2
lines changed

adapter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Namespaced } from './lib/namespaced.js'
55
import { checkName, handleHyperErr, minioClientSchema } from './lib/utils.js'
66

77
const { Async } = crocks
8-
const { prop, map, always } = R
8+
const { prop, map, always, identity } = R
99

1010
export const HYPER_BUCKET_PREFIX = 'hyper-storage-namespaced'
1111

@@ -190,7 +190,7 @@ export default function (config) {
190190
* @returns {Promise<ResponseObjects>}
191191
*/
192192
function listObjects({ bucket, prefix }) {
193-
return Async.all([checkBucket(bucket), checkName(object)])
193+
return Async.all([checkBucket(bucket), checkName(prefix)])
194194
.chain(() => client.listObjects({ bucket, prefix }))
195195
.bimap(
196196
identity,

adapter.test.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import { assertEquals, assertObjectMatch } from './dev_deps.js'
2+
import { ReadableWebToNodeStream } from './deps.js'
3+
4+
import adapter from './adapter.js'
5+
6+
Deno.test('adapter', async (t) => {
7+
const happyMinio = {
8+
makeBucket: (name) => {
9+
if (name === 'test-exists') return Promise.reject({ code: 'BucketAlreadyExists' })
10+
return Promise.resolve()
11+
},
12+
removeBucket: () => Promise.resolve(),
13+
bucketExists: () => Promise.resolve(true),
14+
listBuckets: () =>
15+
Promise.resolve([
16+
{ name: 'test-foo' },
17+
{ name: 'test-bar' },
18+
]),
19+
getObject: () => {
20+
return Promise.resolve(
21+
new ReadableWebToNodeStream(new Response(JSON.stringify({ fizz: 'buzz' })).body),
22+
)
23+
},
24+
putObject: () => Promise.resolve(),
25+
removeObject: () => {
26+
return Promise.resolve()
27+
},
28+
removeObjects: (bucket, keys) => {
29+
if (bucket === 'test-removeBucketTest') {
30+
assertEquals(keys, ['foo', 'bar'])
31+
}
32+
return Promise.resolve()
33+
},
34+
listObjects: () => {
35+
// Mock stream
36+
return {
37+
on: (event, fn) => {
38+
switch (event) {
39+
case 'data': {
40+
fn({ name: 'foo' })
41+
fn({ name: 'bar' })
42+
break
43+
}
44+
case 'end': {
45+
return fn('foo')
46+
}
47+
}
48+
},
49+
}
50+
},
51+
presignedUrl: () => {
52+
return Promise.resolve('http://presigned')
53+
},
54+
}
55+
56+
const a = adapter({
57+
minio: happyMinio,
58+
bucketPrefix: 'test',
59+
useNamespacedBucket: false,
60+
})
61+
62+
await t.step('makeBucket', async (t) => {
63+
await t.step('should return whether the bucket was created successfully', () => {
64+
return a.makeBucket('foo')
65+
.then((res) => assertEquals(res, { ok: true }))
66+
})
67+
68+
await t.step('should return a HyperErr if the bucket already exists', () => {
69+
return a.makeBucket('exists')
70+
.then((res) => assertObjectMatch(res, { ok: false, status: 409 }))
71+
})
72+
})
73+
74+
await t.step('removeBucket', async (t) => {
75+
await t.step('should return whether the bucket was removed successfully', () => {
76+
return a.removeBucket('foo')
77+
.then((res) => assertEquals(res, { ok: true }))
78+
})
79+
80+
await t.step('should remove all objects in the bucket before removing', () => {
81+
return a.removeBucket('removeBucketTest')
82+
.then((res) => assertEquals(res, { ok: true }))
83+
})
84+
})
85+
86+
await t.step('listBuckets', async (t) => {
87+
await t.step('should return the names of the buckets', () => {
88+
return a.listBuckets()
89+
.then((res) =>
90+
assertObjectMatch(res, {
91+
ok: true,
92+
buckets: [
93+
'test-foo',
94+
'test-bar',
95+
],
96+
})
97+
)
98+
})
99+
})
100+
101+
await t.step('putObject', async (t) => {
102+
await t.step('should return that the object was put successfully', () => {
103+
return a.putObject({
104+
bucket: 'foo',
105+
object: 'bar.png',
106+
stream: new Response(JSON.stringify({ foo: 'bar' })).body,
107+
})
108+
.then((res) => assertEquals(res, { ok: true }))
109+
})
110+
111+
await t.step('should return the presigned url', () => {
112+
return a.putObject({
113+
bucket: 'foo',
114+
object: 'bar.png',
115+
useSignedUrl: true,
116+
})
117+
.then((res) => assertEquals(res, { ok: true, url: 'http://presigned' }))
118+
})
119+
})
120+
121+
await t.step('removeObject', async (t) => {
122+
await t.step('should return that the object was removed successfully', () => {
123+
return a.removeObject({
124+
bucket: 'foo',
125+
object: 'bar.png',
126+
})
127+
.then((res) => assertEquals(res, { ok: true }))
128+
})
129+
})
130+
131+
await t.step('getObject', async (t) => {
132+
await t.step('should return the stream of the object', () => {
133+
return a.getObject({
134+
bucket: 'foo',
135+
object: 'bar.png',
136+
})
137+
.then(async (res) => {
138+
const object = await (new Response(res).json())
139+
assertEquals(object, { fizz: 'buzz' })
140+
})
141+
})
142+
143+
await t.step('should return the presigned url', () => {
144+
return a.getObject({
145+
bucket: 'foo',
146+
object: 'bar.png',
147+
useSignedUrl: true,
148+
})
149+
.then((res) => assertEquals(res, { ok: true, url: 'http://presigned' }))
150+
})
151+
})
152+
153+
await t.step('listObjects', async (t) => {
154+
await t.step('should return names of objects in the bucket', () => {
155+
return a.listObjects({
156+
bucket: 'foo',
157+
prefix: 'fizz',
158+
})
159+
.then((res) => {
160+
assertEquals(res, { ok: true, objects: ['foo', 'bar'] })
161+
})
162+
})
163+
})
164+
})

lib/utils.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ export const minioClientSchema = z.object({
3131
bucket: z.string(),
3232
key: z.string(),
3333
})),
34+
removeObjects: z.function()
35+
.args(z.object({
36+
bucket: z.string(),
37+
keys: z.array(z.string()),
38+
})),
3439
getObject: z.function()
3540
.args(z.object({
3641
bucket: z.string(),

0 commit comments

Comments
 (0)