fix: encode dynamic URL path segments (#5963)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
co-authored by
kartik-mem0
parent
87276ef968
commit
cc52f0e367
@@ -118,6 +118,20 @@ describe("MemoryClient - get()", () => {
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
await expect(client.get("nonexistent")).rejects.toThrow("Memory not found");
|
||||
});
|
||||
|
||||
test("URL-encodes memory ID path segments", async () => {
|
||||
const extra = new Map<string, { status: number; body: unknown }>();
|
||||
extra.set("/v1/memories/mem%2Fa%3Fb%23c/", {
|
||||
status: 200,
|
||||
body: createMockMemory({ id: "mem/a?b#c" }),
|
||||
});
|
||||
const mock = setupMockFetch(extra);
|
||||
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
await client.get("mem/a?b#c");
|
||||
|
||||
expect(findFetchCall(mock, "/v1/memories/mem%2Fa%3Fb%23c/")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── update() ────────────────────────────────────────────
|
||||
@@ -213,6 +227,22 @@ describe("MemoryClient - update()", () => {
|
||||
"At least one of text, metadata, timestamp, or expirationDate must be provided",
|
||||
);
|
||||
});
|
||||
|
||||
test("URL-encodes memory ID path segments", async () => {
|
||||
const extra = new Map<string, { status: number; body: unknown }>();
|
||||
extra.set("/v1/memories/mem%2Fa%3Fb%23c/", {
|
||||
status: 200,
|
||||
body: createMockMemory({ id: "mem/a?b#c" }),
|
||||
});
|
||||
const mock = setupMockFetch(extra);
|
||||
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
await client.update("mem/a?b#c", { text: "Updated text" });
|
||||
|
||||
expect(
|
||||
findFetchCall(mock, "/v1/memories/mem%2Fa%3Fb%23c/", "PUT"),
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── delete() ────────────────────────────────────────────
|
||||
@@ -250,6 +280,22 @@ describe("MemoryClient - delete()", () => {
|
||||
expect(call).toBeDefined();
|
||||
expect(call![0]).toContain("delete_linked=true");
|
||||
});
|
||||
|
||||
test("URL-encodes memory ID path segments before adding query params", async () => {
|
||||
const extra = new Map<string, { status: number; body: unknown }>();
|
||||
extra.set("/v1/memories/mem%2Fa%3Fb%23c/", {
|
||||
status: 200,
|
||||
body: { message: "Memory deleted successfully" },
|
||||
});
|
||||
const mock = setupMockFetch(extra);
|
||||
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
await client.delete("mem/a?b#c", { deleteLinked: true });
|
||||
|
||||
const call = findFetchCall(mock, "/v1/memories/mem%2Fa%3Fb%23c/", "DELETE");
|
||||
expect(call).toBeDefined();
|
||||
expect(call![0]).toContain("delete_linked=true");
|
||||
});
|
||||
});
|
||||
|
||||
// ─── deleteAll() ─────────────────────────────────────────
|
||||
@@ -326,4 +372,23 @@ describe("MemoryClient - history()", () => {
|
||||
const result: MemoryHistory[] = await client.history("mem_123");
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
test("URL-encodes memory ID path segments", async () => {
|
||||
const historyEntries = [
|
||||
createMockMemoryHistory({ memory_id: "mem/a?b#c" }),
|
||||
];
|
||||
const extra = new Map<string, { status: number; body: unknown }>();
|
||||
extra.set("/v1/memories/mem%2Fa%3Fb%23c/history/", {
|
||||
status: 200,
|
||||
body: historyEntries,
|
||||
});
|
||||
const mock = setupMockFetch(extra);
|
||||
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
await client.history("mem/a?b#c");
|
||||
|
||||
expect(
|
||||
findFetchCall(mock, "/v1/memories/mem%2Fa%3Fb%23c/history/"),
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,4 +71,43 @@ describe("MemoryClient - deleteUser() (deprecated)", () => {
|
||||
findFetchCall(mock, "/v1/entities/user/456/", "DELETE"),
|
||||
).toBeDefined();
|
||||
});
|
||||
|
||||
test("URL-encodes entity path segments", async () => {
|
||||
const extra = new Map<string, { status: number; body: unknown }>();
|
||||
extra.set("/v1/entities/team%2Ftype/org%2Fteam%3Factive%23frag/", {
|
||||
status: 200,
|
||||
body: { message: "Entity deleted successfully!" },
|
||||
});
|
||||
const mock = setupMockFetch(extra);
|
||||
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
await client.deleteUser({
|
||||
entity_id: "org/team?active#frag" as never,
|
||||
entity_type: "team/type",
|
||||
});
|
||||
|
||||
expect(
|
||||
findFetchCall(
|
||||
mock,
|
||||
"/v1/entities/team%2Ftype/org%2Fteam%3Factive%23frag/",
|
||||
"DELETE",
|
||||
),
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("MemoryClient - deleteUsers()", () => {
|
||||
test("URL-encodes entity path segments", async () => {
|
||||
setupMockFetch();
|
||||
const client = new MemoryClient({ apiKey: TEST_API_KEY });
|
||||
client.telemetryId = "test@example.com";
|
||||
const deleteMock = jest.fn().mockResolvedValue({});
|
||||
client.client = { delete: deleteMock };
|
||||
|
||||
await client.deleteUsers({ userId: "org/team?active#frag" });
|
||||
|
||||
expect(deleteMock).toHaveBeenCalledWith(
|
||||
"/v2/entities/user/org%2Fteam%3Factive%23frag/",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user