Skip to content

Commit 6e07018

Browse files
committed
test: add tests for metadata validation
1 parent 16ec028 commit 6e07018

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

packages/miniflare/src/workers/kv/namespace.worker.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
validatePutOptions,
2323
} from "./validator.worker";
2424

25+
const MAX_BULK_GET_KEYS = 100;
2526
interface KVParams {
2627
key: string;
2728
}
@@ -81,17 +82,22 @@ async function processKeyValue(
8182
withMetadata: boolean = false
8283
) {
8384
const decoder = new TextDecoder();
84-
let r = "";
85+
let decodedValue = "";
8586
if (obj?.value) {
8687
for await (const chunk of obj?.value) {
87-
r += decoder.decode(chunk, { stream: true });
88+
decodedValue += decoder.decode(chunk, { stream: true });
8889
}
89-
r += decoder.decode();
90+
decodedValue += decoder.decode();
9091
}
9192

9293
let val = null;
9394
try {
94-
val = obj?.value == null ? null : type === "json" ? JSON.parse(r) : r;
95+
val =
96+
obj?.value == null
97+
? null
98+
: type === "json"
99+
? JSON.parse(decodedValue)
100+
: decodedValue;
95101
} catch (err: any) {
96102
throw new HttpError(
97103
400,
@@ -104,7 +110,7 @@ async function processKeyValue(
104110
if (withMetadata) {
105111
return {
106112
value: val,
107-
metadata: obj?.metadata ? JSON.stringify(obj?.metadata) : null,
113+
metadata: obj?.metadata,
108114
};
109115
}
110116
return val;
@@ -121,20 +127,20 @@ export class KVNamespaceObject extends MiniflareDurableObject {
121127
@POST("/bulk/get")
122128
get: RouteHandler<KVParams> = async (req, params, url) => {
123129
if (req.method === "POST" && req.body != null) {
124-
let r = "";
130+
let decodedBody = "";
125131
const decoder = new TextDecoder();
126132
for await (const chunk of req.body) {
127-
r += decoder.decode(chunk, { stream: true });
133+
decodedBody += decoder.decode(chunk, { stream: true });
128134
}
129-
r += decoder.decode();
130-
const parsedBody = JSON.parse(r);
135+
decodedBody += decoder.decode();
136+
const parsedBody = JSON.parse(decodedBody);
131137
const keys: string[] = parsedBody.keys;
132138
const type = parsedBody?.type;
133139
if (type && type !== "text" && type !== "json") {
134140
return new Response("", { status: 400 });
135141
}
136142
const obj: { [key: string]: any } = {};
137-
if (keys.length > 100) {
143+
if (keys.length > MAX_BULK_GET_KEYS) {
138144
return new Response("", { status: 400 });
139145
}
140146
for (const key of keys) {

packages/miniflare/test/plugins/kv/index.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,40 @@ test("bulk get: request json type", async (t) => {
172172
}
173173
});
174174

175+
test("bulk get: check metadata", async (t) => {
176+
const { kv } = t.context;
177+
await kv.put("key1", "value1", {
178+
expiration: TIME_FUTURE,
179+
metadata: { testing: true },
180+
});
181+
const result: any = await kv.getWithMetadata(["key1"]);
182+
const expectedResult: any = new Map([
183+
["key1", { value: "value1", metadata: { testing: true } }],
184+
]);
185+
t.deepEqual(result, expectedResult);
186+
});
187+
188+
test("bulk get: check metadata as string", async (t) => {
189+
const { kv } = t.context;
190+
await kv.put("key1", "value1", {
191+
expiration: TIME_FUTURE,
192+
metadata: "example",
193+
});
194+
const result: any = await kv.getWithMetadata(["key1"]);
195+
const expectedResult: any = new Map([
196+
["key1", { value: "value1", metadata: "example" }],
197+
]);
198+
t.deepEqual(result, expectedResult);
199+
});
200+
201+
test("bulk get: get with metadata for 404", async (t) => {
202+
const { kv } = t.context;
203+
204+
const result: any = await kv.getWithMetadata(["key1"]);
205+
const expectedResult: any = new Map([["key1", null]]);
206+
t.deepEqual(result, expectedResult);
207+
});
208+
175209
test("get: returns null for non-existent keys", async (t) => {
176210
const { kv } = t.context;
177211
t.is(await kv.get("key"), null);

packages/miniflare/test/test-shared/miniflare.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export function namespace<T>(ns: string, binding: T): Namespaced<T> {
4444
);
4545
if (result instanceof Promise) {
4646
return result.then((res) => {
47+
// KV.get([a,b,c]) would be prefixed with ns, so we strip this prefix from response.
48+
// Map keys => [ns-a, ns-b, ns-c] -> [a,b,c]
4749
if (res instanceof Map) {
4850
const newResult = new Map<string, unknown>();
4951
for (const [key, value] of res) {

0 commit comments

Comments
 (0)