holosphere 1.0.7 → 1.1.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/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "holosphere",
3
- "version": "1.0.7",
3
+ "version": "1.1.0",
4
4
  "description": "Holonic Geospatial Communication Infrastructure",
5
5
  "main": "holosphere.js",
6
6
  "types": "holosphere.d.ts",
7
7
  "type": "module",
8
8
  "scripts": {
9
- "test": "echo \"Error: no test specified\" && exit 1"
9
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
10
10
  },
11
11
  "author": "Roberto Valenti",
12
12
  "license": "GPL-3.0-or-later",
@@ -15,5 +15,16 @@
15
15
  "gun": "^0.2020.1240",
16
16
  "h3-js": "^4.1.0",
17
17
  "openai": "^4.29.2"
18
+ },
19
+ "devDependencies": {
20
+ "jest": "^29.7.0",
21
+ "jest-environment-node": "^29.7.0"
22
+ },
23
+ "jest": {
24
+ "testEnvironment": "node",
25
+ "transform": {},
26
+ "moduleNameMapper": {
27
+ "^(\\.{1,2}/.*)\\.js$": "$1"
28
+ }
18
29
  }
19
30
  }
@@ -1,32 +1,314 @@
1
1
  import HoloSphere from '../holosphere.js';
2
+ import * as h3 from 'h3-js';
2
3
 
3
4
  describe('HoloSphere', () => {
4
5
  let holoSphere;
5
-
6
+ const testAppName = 'test-app';
7
+
6
8
  beforeEach(() => {
7
- holoSphere = new HoloSphere('test-app', {
8
- gunPeers: ['http://localhost:8765/gun'],
9
+ holoSphere = new HoloSphere(testAppName);
10
+ });
11
+
12
+ describe('Constructor', () => {
13
+ test('should create instance with app name', () => {
14
+ expect(holoSphere).toBeInstanceOf(HoloSphere);
15
+ expect(holoSphere.gun).toBeDefined();
16
+ expect(holoSphere.validator).toBeDefined();
17
+ expect(holoSphere.openai).toBeUndefined();
18
+ });
19
+
20
+ test('should initialize with OpenAI when key provided', () => {
21
+ const hsWithAI = new HoloSphere(testAppName, false, 'fake-key');
22
+ expect(hsWithAI.openai).toBeDefined();
9
23
  });
10
24
  });
11
25
 
12
- test('initialization', () => {
13
- expect(holoSphere).toBeDefined();
14
- expect(holoSphere.users).toEqual({});
15
- expect(holoSphere.hexagonVotes).toEqual({});
26
+ describe('Schema Operations', () => {
27
+ const testLens = 'testLens';
28
+ const validSchema = {
29
+ type: 'object',
30
+ properties: {
31
+ id: { type: 'string' },
32
+ data: { type: 'string' }
33
+ },
34
+ required: ['id', 'data']
35
+ };
36
+
37
+ test('should set and get schema', async () => {
38
+ // Set the schema
39
+ const setResult = await holoSphere.setSchema(testLens, validSchema);
40
+ expect(setResult).toBe(true);
41
+
42
+ // Wait for GunDB to process
43
+ await new Promise(resolve => setTimeout(resolve, 100));
44
+
45
+ // Get and verify the schema
46
+ const retrievedSchema = await holoSphere.getSchema(testLens);
47
+ expect(retrievedSchema).toBeDefined();
48
+ expect(retrievedSchema).toEqual(validSchema);
49
+ }, 5000);
50
+
51
+ test('should handle invalid schema parameters', async () => {
52
+ const nullResult = await holoSphere.setSchema(null, null);
53
+ expect(nullResult).toBe(false);
54
+
55
+ const missingLensResult = await holoSphere.setSchema(undefined, validSchema);
56
+ expect(missingLensResult).toBe(false);
57
+
58
+ const missingSchemaResult = await holoSphere.setSchema(testLens, null);
59
+ expect(missingSchemaResult).toBe(false);
60
+ });
61
+
62
+ test('should enforce strict mode schema validation', async () => {
63
+ const strictHoloSphere = new HoloSphere(testAppName, true);
64
+
65
+ // Test cases for invalid schemas
66
+ const invalidSchemas = [
67
+ {
68
+ // Missing type field
69
+ properties: {
70
+ id: { type: 'string' }
71
+ }
72
+ },
73
+ {
74
+ // Missing properties
75
+ type: 'object'
76
+ },
77
+ {
78
+ // Missing required fields
79
+ type: 'object',
80
+ properties: {
81
+ id: { type: 'string' }
82
+ }
83
+ },
84
+ {
85
+ // Invalid property type
86
+ type: 'object',
87
+ properties: {
88
+ id: { type: 123 } // Should be string
89
+ },
90
+ required: ['id']
91
+ }
92
+ ];
93
+
94
+ // Test each invalid schema
95
+ for (const invalidSchema of invalidSchemas) {
96
+ const setResult = await strictHoloSphere.setSchema(testLens, invalidSchema);
97
+ expect(setResult).toBe(false);
98
+ }
99
+
100
+ // Valid schema should work in strict mode
101
+ const validSchema = {
102
+ type: 'object',
103
+ properties: {
104
+ id: { type: 'string' },
105
+ data: { type: 'string' }
106
+ },
107
+ required: ['id', 'data']
108
+ };
109
+
110
+ const validResult = await strictHoloSphere.setSchema(testLens, validSchema);
111
+ expect(validResult).toBe(true);
112
+
113
+ // Verify schema was stored correctly
114
+ const retrievedSchema = await strictHoloSphere.getSchema(testLens);
115
+ expect(retrievedSchema).toEqual(validSchema);
116
+ }, 5000);
117
+
118
+ test('should handle schema retrieval for non-existent lens', async () => {
119
+ const result = await holoSphere.getSchema('nonexistent-lens');
120
+ expect(result).toBeNull();
121
+ });
122
+
123
+ afterEach(async () => {
124
+ // Clean up schemas after each test
125
+ await holoSphere.gun.get(holoSphere.appname)
126
+ .get(testLens)
127
+ .get('schema')
128
+ .put(null);
129
+
130
+ // Wait for GunDB to process
131
+ await new Promise(resolve => setTimeout(resolve, 100));
132
+ });
16
133
  });
17
134
 
18
- test('voting system', async () => {
19
- const userId = 'test-user';
20
- const hexId = '8928308280fffff';
21
- const topic = 'test-topic';
22
- const vote = 'yes';
135
+ describe('Data Operations', () => {
136
+ const testHolon = h3.latLngToCell(40.7128, -74.0060, 7);
137
+ const testLens = 'testLens';
138
+ const validData = { id: 'test123', data: 'test data' };
139
+ const invalidData = { id: 'test456', wrongField: 'wrong data' };
140
+
141
+ beforeEach(async () => {
142
+ // Set up schema for validation tests
143
+ const schema = {
144
+ type: 'object',
145
+ properties: {
146
+ id: { type: 'string' },
147
+ data: { type: 'string' }
148
+ },
149
+ required: ['id', 'data']
150
+ };
151
+ await holoSphere.setSchema(testLens, schema);
152
+ });
153
+
154
+ test('should put and get data with schema validation', async () => {
155
+ // Test valid data
156
+ const putResult = await holoSphere.put(testHolon, testLens, validData);
157
+ expect(putResult).toBe(true);
23
158
 
24
- await holoSphere.initializeUser(userId);
25
- await holoSphere.vote(userId, hexId, topic, vote);
159
+ const getResult = await holoSphere.get(testHolon, testLens, validData.id);
160
+ expect(getResult).toEqual(validData);
26
161
 
27
- const votes = holoSphere.aggregateVotes(hexId, topic);
28
- expect(votes).toHaveProperty('yes', 1);
162
+ // Test invalid data
163
+ const invalidPutResult = await holoSphere.put(testHolon, testLens, invalidData);
164
+ expect(invalidPutResult).toBe(false);
165
+ }, 10000);
166
+
167
+ test('should get all data with schema validation', async () => {
168
+ await holoSphere.put(testHolon, testLens, validData);
169
+ await holoSphere.put(testHolon, testLens, { id: 'test789', data: 'more test data' });
170
+
171
+ const results = await holoSphere.getAll(testHolon, testLens);
172
+ expect(Array.isArray(results)).toBeTruthy();
173
+ expect(results.length).toBeGreaterThan(0);
174
+ expect(results.some(item => item.id === validData.id)).toBeTruthy();
175
+ }, 10000);
176
+
177
+ test('should delete data', async () => {
178
+ await holoSphere.put(testHolon, testLens, validData);
179
+ await holoSphere.delete(testHolon, testLens, validData.id);
180
+
181
+ const result = await holoSphere.get(testHolon, testLens, validData.id);
182
+ expect(result).toBeNull();
183
+ }, 10000);
184
+
185
+ test('should delete all data', async () => {
186
+ await holoSphere.put(testHolon, testLens, validData);
187
+ await holoSphere.put(testHolon, testLens, { id: 'test789', data: 'more test data' });
188
+
189
+ const deleteResult = await holoSphere.deleteAll(testHolon, testLens);
190
+ expect(deleteResult).toBe(true);
191
+
192
+ const results = await holoSphere.getAll(testHolon, testLens);
193
+ expect(results).toEqual([]);
194
+ }, 10000);
195
+
196
+ test('should enforce strict mode data validation', async () => {
197
+ const strictHoloSphere = new HoloSphere(testAppName, true);
198
+
199
+ // Define schema for strict mode tests
200
+ const strictSchema = {
201
+ type: 'object',
202
+ properties: {
203
+ id: { type: 'string' },
204
+ data: { type: 'string' }
205
+ },
206
+ required: ['id', 'data']
207
+ };
208
+
209
+ // Set up schema
210
+ await strictHoloSphere.setSchema(testLens, strictSchema);
211
+
212
+ // Try to put data without schema in strict mode
213
+ const noSchemaResult = await strictHoloSphere.put(testHolon, 'no-schema-lens', validData);
214
+ expect(noSchemaResult).toBe(false);
215
+
216
+ // Try to get data without schema in strict mode
217
+ const noSchemaData = await strictHoloSphere.getAll(testHolon, 'no-schema-lens');
218
+ expect(noSchemaData).toEqual([]);
219
+
220
+ // Invalid data should be removed in strict mode
221
+ await strictHoloSphere.put(testHolon, testLens, invalidData);
222
+ const results = await strictHoloSphere.getAll(testHolon, testLens);
223
+ expect(results.some(item => item.id === invalidData.id)).toBe(false);
224
+ }, 10000);
29
225
  });
30
226
 
31
- // Add more tests...
227
+ describe('Node Operations', () => {
228
+ const testHolon = h3.latLngToCell(40.7128, -74.0060, 7);
229
+ const testLens = 'testLens';
230
+ const testNode = { value: 'test node data' };
231
+
232
+ test('should put and get node', async () => {
233
+ await holoSphere.putNode(testHolon, testLens, testNode);
234
+
235
+ // Wait for GunDB to process
236
+ await new Promise(resolve => setTimeout(resolve, 100));
237
+
238
+ const result = await holoSphere.getNode(testHolon, testLens, 'value');
239
+ expect(result).toBeDefined();
240
+ expect(result).toBe('test node data');
241
+ }, 10000);
242
+
243
+ test('should delete node', async () => {
244
+ // First put the node
245
+ await holoSphere.putNode(testHolon, testLens, testNode);
246
+ await new Promise(resolve => setTimeout(resolve, 100));
247
+
248
+ // Verify node exists
249
+ const beforeDelete = await holoSphere.getNode(testHolon, testLens, 'value');
250
+ expect(beforeDelete).toBe('test node data');
251
+
252
+ // Delete the node
253
+ const deleteResult = await holoSphere.deleteNode(testHolon, testLens, 'value');
254
+ expect(deleteResult).toBe(true);
255
+
256
+ // Wait for deletion to process
257
+ await new Promise(resolve => setTimeout(resolve, 100));
258
+
259
+ // Verify node is deleted
260
+ const afterDelete = await holoSphere.getNode(testHolon, testLens, 'value');
261
+ expect(afterDelete).toBeNull();
262
+ }, 10000);
263
+
264
+ test('should handle invalid node operations', async () => {
265
+ // Test missing parameters
266
+ const nullResult = await holoSphere.deleteNode(null, null, null);
267
+ expect(nullResult).toBe(false);
268
+
269
+ const nullGet = await holoSphere.getNode(null, null, null);
270
+ expect(nullGet).toBeNull();
271
+ });
272
+
273
+ afterEach(async () => {
274
+ // Clean up after each test
275
+ await holoSphere.deleteNode(testHolon, testLens, 'value');
276
+ await new Promise(resolve => setTimeout(resolve, 100));
277
+ });
278
+ });
279
+
280
+ describe('Geospatial Operations', () => {
281
+ const lat = 40.7128;
282
+ const lng = -74.0060;
283
+ const resolution = 7;
284
+
285
+ test('should get holon from coordinates', async () => {
286
+ const holon = await holoSphere.getHolon(lat, lng, resolution);
287
+ expect(holon).toBeDefined();
288
+ expect(typeof holon).toBe('string');
289
+ });
290
+
291
+ test('should get scalespace from coordinates', () => {
292
+ const scales = holoSphere.getScalespace(lat, lng);
293
+ expect(Array.isArray(scales)).toBeTruthy();
294
+ expect(scales.length).toBe(15); // 0-14 resolution levels
295
+ });
296
+
297
+ test('should get holon scalespace', () => {
298
+ const holon = h3.latLngToCell(lat, lng, resolution);
299
+ const scales = holoSphere.getHolonScalespace(holon);
300
+ expect(Array.isArray(scales)).toBeTruthy();
301
+ expect(scales.length).toBe(resolution + 1);
302
+ });
303
+ });
304
+
305
+ afterAll(async () => {
306
+ // Clean up test data
307
+ const testLens = 'testLens';
308
+ const testHolon = h3.latLngToCell(40.7128, -74.0060, 7);
309
+ await holoSphere.deleteAll(testHolon, testLens);
310
+
311
+ // Allow time for Gun to process
312
+ await new Promise(resolve => setTimeout(resolve, 1000));
313
+ });
32
314
  });