Skip to content

Commit fccd3cc

Browse files
committed
chore: envelope logic works
1 parent 4c502c7 commit fccd3cc

File tree

3 files changed

+341
-306
lines changed

3 files changed

+341
-306
lines changed
Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
{
2-
"name": "evault-core",
3-
"version": "0.1.0",
4-
"description": "",
5-
"main": "index.js",
6-
"scripts": {
7-
"test": "vitest --config vitest.config.ts"
8-
},
9-
"keywords": [],
10-
"author": "",
11-
"license": "ISC",
12-
"devDependencies": {
13-
"@types/node": "^22.13.10",
14-
"dotenv": "^16.5.0",
15-
"testcontainers": "^10.24.2",
16-
"typescript": "^5.8.3",
17-
"uuid": "^11.1.0",
18-
"vitest": "^3.0.9"
19-
},
20-
"dependencies": {
21-
"@testcontainers/neo4j": "^10.24.2",
22-
"neo4j-driver": "^5.28.1",
23-
"w3id": "workspace:*"
24-
}
2+
"name": "evault-core",
3+
"version": "0.1.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "vitest --config vitest.config.ts"
8+
},
9+
"keywords": [],
10+
"author": "",
11+
"license": "ISC",
12+
"devDependencies": {
13+
"@types/json-schema": "^7.0.15",
14+
"@types/node": "^22.13.10",
15+
"dotenv": "^16.5.0",
16+
"testcontainers": "^10.24.2",
17+
"typescript": "^5.8.3",
18+
"uuid": "^11.1.0",
19+
"vitest": "^3.0.9"
20+
},
21+
"dependencies": {
22+
"@testcontainers/neo4j": "^10.24.2",
23+
"json-schema": "^0.4.0",
24+
"neo4j-driver": "^5.28.1",
25+
"w3id": "workspace:*"
26+
}
2527
}
Lines changed: 167 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,157 +1,177 @@
11
import neo4j, { Driver } from "neo4j-driver";
22
import { DbService } from "./db.service"; // adjust if needed
33
import { it, describe, beforeAll, afterAll, expect } from "vitest";
4-
import { v4 as uuidv4 } from "uuid";
54
import { Neo4jContainer, StartedNeo4jContainer } from "@testcontainers/neo4j";
65

76
type Envelope = {
8-
id: string;
9-
ontology: string;
10-
value: any;
7+
id: string;
8+
ontology: string;
9+
value: any;
10+
valueType: string;
1111
};
1212

1313
describe("DbService (integration)", () => {
14-
let container: StartedNeo4jContainer;
15-
let service: DbService;
16-
let driver: Driver;
17-
18-
beforeAll(async () => {
19-
container = await new Neo4jContainer("neo4j:4.4.12").start();
20-
21-
const username = container.getUsername();
22-
const password = container.getPassword();
23-
const boltPort = container.getMappedPort(7687);
24-
const uri = `bolt://localhost:${boltPort}`;
25-
26-
driver = neo4j.driver(uri, neo4j.auth.basic(username, password));
27-
service = new DbService(uri, username, password);
28-
});
29-
30-
afterAll(async () => {
31-
await service.close();
32-
await driver.close();
33-
await container.stop();
34-
});
35-
36-
it("should store and retrieve a meta-envelope", async () => {
37-
const input = {
38-
ontology: "SocialMediaPost",
39-
payload: {
40-
text: "hello world",
41-
dateCreated: "2025-04-10",
42-
likes: ["user1", "user2"],
43-
},
44-
acl: ["@test-user"],
45-
};
46-
47-
const result = await service.storeMetaEnvelope(input, input.acl);
48-
const id = result.metaEnvelope.id;
49-
50-
const fetched = await service.findMetaEnvelopeById(id);
51-
expect(fetched).toBeDefined();
52-
expect(fetched.id).toBeDefined();
53-
expect(fetched.ontology).toBe("SocialMediaPost");
54-
expect(fetched.acl).toEqual(["@test-user"]);
55-
expect(fetched.envelopes).toHaveLength(3);
56-
expect(fetched.envelopes[0]).toEqual(
57-
expect.objectContaining({
58-
id: expect.any(String),
59-
ontology: expect.any(String),
60-
value: expect.any(String),
61-
}),
62-
);
63-
64-
console.log(fetched);
65-
});
66-
67-
it("should find meta-envelopes containing the search term in any envelope value", async () => {
68-
const input = {
69-
ontology: "SocialMediaPost",
70-
payload: {
71-
text: "This is a searchable tweet",
72-
image: "https://example.com/image.jpg",
73-
likes: ["user1", "user2"],
74-
},
75-
acl: ["@search-test-user"],
76-
};
77-
78-
const metaEnv = await service.storeMetaEnvelope(input, input.acl);
79-
80-
const found = await service.findMetaEnvelopesBySearchTerm(
81-
"SocialMediaPost",
82-
"searchable",
83-
);
84-
85-
expect(Array.isArray(found)).toBe(true);
86-
const match = found.find((m) => m.id === metaEnv.metaEnvelope.id);
87-
expect(match).toBeDefined();
88-
if (!match) throw new Error();
89-
expect(match.envelopes.length).toBeGreaterThan(0);
90-
expect(
91-
match.envelopes.some((e) => e.value.includes("searchable")),
92-
).toBe(true);
93-
});
94-
95-
it("should return empty array if no values contain the search term", async () => {
96-
const found = await service.findMetaEnvelopesBySearchTerm(
97-
"SocialMediaPost",
98-
"notfoundterm",
99-
);
100-
expect(Array.isArray(found)).toBe(true);
101-
expect(found.length).toBe(0);
102-
});
103-
104-
it("should find meta-envelopes by ontology", async () => {
105-
const results =
106-
await service.findMetaEnvelopesByOntology("SocialMediaPost");
107-
expect(Array.isArray(results)).toBe(true);
108-
expect(results.length).toBeGreaterThan(0);
109-
});
110-
111-
it("should delete a meta-envelope and its envelopes", async () => {
112-
const meta = {
113-
ontology: "TempPost",
114-
payload: {
115-
value: "to be deleted",
116-
},
117-
acl: ["@delete-user"],
118-
};
119-
120-
const stored = await service.storeMetaEnvelope(meta, meta.acl);
121-
await service.deleteMetaEnvelope(stored.metaEnvelope.id);
122-
123-
const deleted = await service.findMetaEnvelopeById(
124-
stored.metaEnvelope.id,
125-
);
126-
expect(deleted).toBeNull();
127-
});
128-
129-
it("should update envelope value", async () => {
130-
const meta = {
131-
ontology: "UpdateTest",
132-
payload: {
133-
value: "original",
134-
},
135-
acl: ["@updater"],
136-
};
137-
138-
const stored = await service.storeMetaEnvelope(meta, meta.acl);
139-
140-
const result = await service.findMetaEnvelopeById(
141-
stored.metaEnvelope.id,
142-
);
143-
const targetEnvelope = result.envelopes.find(
144-
(e: Envelope) => e.ontology === "value",
145-
);
146-
147-
await service.updateEnvelopeValue(targetEnvelope.id, "updated");
148-
149-
const updated = await service.findMetaEnvelopeById(
150-
stored.metaEnvelope.id,
151-
);
152-
const updatedValue = updated.envelopes.find(
153-
(e: Envelope) => e.id === targetEnvelope.id,
154-
);
155-
expect(updatedValue.value).toBe("updated");
156-
});
14+
let container: StartedNeo4jContainer;
15+
let service: DbService;
16+
let driver: Driver;
17+
18+
beforeAll(async () => {
19+
container = await new Neo4jContainer("neo4j:4.4.12").start();
20+
21+
const username = container.getUsername();
22+
const password = container.getPassword();
23+
const boltPort = container.getMappedPort(7687);
24+
const uri = `bolt://localhost:${boltPort}`;
25+
26+
driver = neo4j.driver(uri, neo4j.auth.basic(username, password));
27+
service = new DbService(uri, username, password);
28+
});
29+
30+
afterAll(async () => {
31+
await service.close();
32+
await driver.close();
33+
await container.stop();
34+
});
35+
36+
it("should store and retrieve a meta-envelope with various data types", async () => {
37+
const input = {
38+
ontology: "TestTypes",
39+
payload: {
40+
string: "hello world",
41+
number: 42,
42+
boolean: true,
43+
date: new Date("2025-04-10T00:00:00Z"),
44+
array: [1, 2, 3],
45+
object: { nested: { value: "deep" } },
46+
},
47+
acl: ["@test-user"],
48+
};
49+
50+
const result = await service.storeMetaEnvelope(input, input.acl);
51+
const id = result.metaEnvelope.id;
52+
53+
const fetched = await service.findMetaEnvelopeById(id);
54+
expect(fetched).toBeDefined();
55+
expect(fetched.id).toBeDefined();
56+
expect(fetched.ontology).toBe("TestTypes");
57+
expect(fetched.acl).toEqual(["@test-user"]);
58+
expect(fetched.envelopes).toHaveLength(6);
59+
60+
// Verify each data type is properly stored and retrieved
61+
const envelopes = fetched.envelopes.reduce(
62+
(acc: Record<string, Envelope>, e: Envelope) => {
63+
acc[e.ontology] = e;
64+
return acc;
65+
},
66+
{}
67+
);
68+
69+
expect(envelopes.string.value).toBe("hello world");
70+
expect(envelopes.string.valueType).toBe("string");
71+
72+
expect(envelopes.number.value).toBe(42);
73+
expect(envelopes.number.valueType).toBe("number");
74+
75+
expect(envelopes.boolean.value).toBe(true);
76+
expect(envelopes.boolean.valueType).toBe("boolean");
77+
78+
expect(envelopes.date.value).toBeInstanceOf(Date);
79+
expect(envelopes.date.value.toISOString()).toBe("2025-04-10T00:00:00.000Z");
80+
expect(envelopes.date.valueType).toBe("date");
81+
82+
expect(envelopes.array.value).toEqual([1, 2, 3]);
83+
expect(envelopes.array.valueType).toBe("array");
84+
85+
expect(envelopes.object.value).toEqual({ nested: { value: "deep" } });
86+
expect(envelopes.object.valueType).toBe("object");
87+
});
88+
89+
it("should find meta-envelopes containing the search term in any envelope value", async () => {
90+
const input = {
91+
ontology: "SocialMediaPost",
92+
payload: {
93+
text: "This is a searchable tweet",
94+
image: "https://example.com/image.jpg",
95+
likes: ["user1", "user2"],
96+
},
97+
acl: ["@search-test-user"],
98+
};
99+
100+
const metaEnv = await service.storeMetaEnvelope(input, input.acl);
101+
102+
const found = await service.findMetaEnvelopesBySearchTerm(
103+
"SocialMediaPost",
104+
"searchable"
105+
);
106+
107+
expect(Array.isArray(found)).toBe(true);
108+
const match = found.find((m) => m.id === metaEnv.metaEnvelope.id);
109+
expect(match).toBeDefined();
110+
if (!match) throw new Error();
111+
expect(match.envelopes.length).toBeGreaterThan(0);
112+
expect(match.envelopes.some((e) => e.value.includes("searchable"))).toBe(
113+
true
114+
);
115+
});
116+
117+
it("should return empty array if no values contain the search term", async () => {
118+
const found = await service.findMetaEnvelopesBySearchTerm(
119+
"SocialMediaPost",
120+
"notfoundterm"
121+
);
122+
expect(Array.isArray(found)).toBe(true);
123+
expect(found.length).toBe(0);
124+
});
125+
126+
it("should find meta-envelopes by ontology", async () => {
127+
const results =
128+
await service.findMetaEnvelopesByOntology("SocialMediaPost");
129+
expect(Array.isArray(results)).toBe(true);
130+
expect(results.length).toBeGreaterThan(0);
131+
});
132+
133+
it("should delete a meta-envelope and its envelopes", async () => {
134+
const meta = {
135+
ontology: "TempPost",
136+
payload: {
137+
value: "to be deleted",
138+
},
139+
acl: ["@delete-user"],
140+
};
141+
142+
const stored = await service.storeMetaEnvelope(meta, meta.acl);
143+
await service.deleteMetaEnvelope(stored.metaEnvelope.id);
144+
145+
const deleted = await service.findMetaEnvelopeById(stored.metaEnvelope.id);
146+
expect(deleted).toBeNull();
147+
});
148+
149+
it("should update envelope value with proper type handling", async () => {
150+
const meta = {
151+
ontology: "UpdateTest",
152+
payload: {
153+
value: "original",
154+
},
155+
acl: ["@updater"],
156+
};
157+
158+
const stored = await service.storeMetaEnvelope(meta, meta.acl);
159+
160+
const result = await service.findMetaEnvelopeById(stored.metaEnvelope.id);
161+
const targetEnvelope = result.envelopes.find(
162+
(e: Envelope) => e.ontology === "value"
163+
);
164+
165+
// Update with a different type
166+
const newValue = new Date("2025-04-10T00:00:00Z");
167+
await service.updateEnvelopeValue(targetEnvelope.id, newValue);
168+
169+
const updated = await service.findMetaEnvelopeById(stored.metaEnvelope.id);
170+
const updatedValue = updated.envelopes.find(
171+
(e: Envelope) => e.id === targetEnvelope.id
172+
);
173+
expect(updatedValue.value).toBeInstanceOf(Date);
174+
expect(updatedValue.value.toISOString()).toBe("2025-04-10T00:00:00.000Z");
175+
expect(updatedValue.valueType).toBe("date");
176+
});
157177
});

0 commit comments

Comments
 (0)