holosphere 1.1.4 → 1.1.6
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/FEDERATION.md +265 -0
- package/babel.config.js +5 -0
- package/federation.js +723 -0
- package/holosphere.js +905 -1074
- package/package.json +3 -1
- package/services/environmentalApi.js +253 -0
- package/services/environmentalApitest.js +164 -0
- package/test/ai.test.js +268 -76
- package/test/federation.test.js +115 -356
- package/test/holonauth.test.js +241 -0
- package/test/holosphere.test.js +111 -991
- package/test/sea.html +33 -0
- package/test/spacesauth.test.js +0 -335
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import Gun from 'gun';
|
|
2
|
+
import HoloSphere from '../holosphere.js';
|
|
3
|
+
import * as h3 from 'h3-js';
|
|
4
|
+
import { jest } from '@jest/globals';
|
|
5
|
+
|
|
6
|
+
// Increase timeout for all tests
|
|
7
|
+
jest.setTimeout(3000);
|
|
8
|
+
|
|
9
|
+
describe('HoloSphere Authentication and Authorization', () => {
|
|
10
|
+
let holoSphere;
|
|
11
|
+
let strictHoloSphere;
|
|
12
|
+
const testPassword = 'TestPass123!';
|
|
13
|
+
const testHolon = 'test-holon';
|
|
14
|
+
const testLens = 'test-lens';
|
|
15
|
+
|
|
16
|
+
beforeAll(async () => {
|
|
17
|
+
holoSphere = new HoloSphere('test-app', false, null);
|
|
18
|
+
strictHoloSphere = new HoloSphere('test-app-strict', true, null);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(async () => {
|
|
22
|
+
// Clean up test data
|
|
23
|
+
try {
|
|
24
|
+
if (holoSphere) {
|
|
25
|
+
await holoSphere.deleteAll(testHolon, testLens);
|
|
26
|
+
}
|
|
27
|
+
if (strictHoloSphere) {
|
|
28
|
+
await strictHoloSphere.deleteAll(testHolon, testLens);
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('Error in afterEach cleanup:', error);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterAll(async () => {
|
|
36
|
+
// Clean up all test data
|
|
37
|
+
await holoSphere.deleteAll(testHolon, testLens);
|
|
38
|
+
await holoSphere.deleteAllGlobal('testTable');
|
|
39
|
+
|
|
40
|
+
// Close Gun connections
|
|
41
|
+
if (holoSphere.gun) {
|
|
42
|
+
holoSphere.gun.off();
|
|
43
|
+
}
|
|
44
|
+
if (strictHoloSphere.gun) {
|
|
45
|
+
strictHoloSphere.gun.off();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Wait for connections to close
|
|
49
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('Authentication System', () => {
|
|
53
|
+
it('should authenticate with password and store/retrieve data', async () => {
|
|
54
|
+
const testData = { id: 'test1', value: 'private-data' };
|
|
55
|
+
|
|
56
|
+
// Test storing with authentication
|
|
57
|
+
await holoSphere.put(testHolon, testLens, testData, testPassword);
|
|
58
|
+
|
|
59
|
+
// Test retrieving with authentication
|
|
60
|
+
const result = await holoSphere.get(testHolon, testLens, testData.id, testPassword);
|
|
61
|
+
expect(result).toBeDefined();
|
|
62
|
+
expect(result.value).toBe(testData.value);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should handle authentication errors gracefully', async () => {
|
|
66
|
+
const testData = { id: 'test2', value: 'private-data' };
|
|
67
|
+
|
|
68
|
+
// Store data with correct password
|
|
69
|
+
await holoSphere.put(testHolon, testLens, testData, testPassword);
|
|
70
|
+
|
|
71
|
+
// Try to retrieve with wrong password
|
|
72
|
+
const result = await holoSphere.get(testHolon, testLens, testData.id, 'wrong_password');
|
|
73
|
+
expect(result).toBeNull();
|
|
74
|
+
}, 10000);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('Schema Validation', () => {
|
|
78
|
+
it('should only validate schema in strict mode', async () => {
|
|
79
|
+
const schema = {
|
|
80
|
+
type: 'object',
|
|
81
|
+
properties: {
|
|
82
|
+
id: { type: 'string' },
|
|
83
|
+
value: { type: 'number' }
|
|
84
|
+
},
|
|
85
|
+
required: ['id', 'value']
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Set schema for both instances
|
|
89
|
+
await holoSphere.setSchema(testLens, schema);
|
|
90
|
+
await strictHoloSphere.setSchema(testLens, schema);
|
|
91
|
+
|
|
92
|
+
const invalidData = { id: 'invalid' }; // Missing required 'value' field
|
|
93
|
+
|
|
94
|
+
// Should work in non-strict mode
|
|
95
|
+
await expect(holoSphere.put(testHolon, testLens, invalidData)).resolves.toBeTruthy();
|
|
96
|
+
|
|
97
|
+
// Should fail in strict mode
|
|
98
|
+
await expect(strictHoloSphere.put(testHolon, testLens, invalidData))
|
|
99
|
+
.rejects.toThrow('Schema validation failed');
|
|
100
|
+
}, 10000);
|
|
101
|
+
|
|
102
|
+
it('should require schema in strict mode', async () => {
|
|
103
|
+
const testData = { id: 'test', value: 123 };
|
|
104
|
+
|
|
105
|
+
// Should work in non-strict mode without schema
|
|
106
|
+
await expect(holoSphere.put(testHolon, testLens, testData)).resolves.toBeTruthy();
|
|
107
|
+
|
|
108
|
+
// Delete any existing schema
|
|
109
|
+
await strictHoloSphere.putGlobal('schemas', { id: testLens, schema: null });
|
|
110
|
+
|
|
111
|
+
// Should fail in strict mode without schema
|
|
112
|
+
try {
|
|
113
|
+
await strictHoloSphere.put(testHolon, testLens, testData);
|
|
114
|
+
fail('Should have thrown an error');
|
|
115
|
+
} catch (error) {
|
|
116
|
+
expect(error.message).toBe('Schema required in strict mode');
|
|
117
|
+
}
|
|
118
|
+
}, 10000);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('Private Data Operations', () => {
|
|
122
|
+
it('should store and retrieve private data with password', async () => {
|
|
123
|
+
const testData = { id: 'test3', value: 123 };
|
|
124
|
+
|
|
125
|
+
await holoSphere.put(testHolon, testLens, testData, testPassword);
|
|
126
|
+
|
|
127
|
+
const result = await holoSphere.get(testHolon, testLens, testData.id, testPassword);
|
|
128
|
+
expect(result).toEqual(testData);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should handle public data access', async () => {
|
|
132
|
+
const testData = { id: 'public', value: 456 };
|
|
133
|
+
|
|
134
|
+
await holoSphere.put(testHolon, testLens, testData);
|
|
135
|
+
|
|
136
|
+
const result = await holoSphere.get(testHolon, testLens, testData.id);
|
|
137
|
+
expect(result).toEqual(testData);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should prevent unauthorized access to private data', async () => {
|
|
141
|
+
const testData = { id: 'private', value: 789 };
|
|
142
|
+
|
|
143
|
+
// Store with password
|
|
144
|
+
await holoSphere.put(testHolon, testLens, testData, testPassword);
|
|
145
|
+
|
|
146
|
+
// Try to retrieve without password
|
|
147
|
+
const result = await holoSphere.get(testHolon, testLens, testData.id);
|
|
148
|
+
expect(result).toBeNull();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should handle deletion of private data', async () => {
|
|
152
|
+
const testData = { id: 'delete', value: 101 };
|
|
153
|
+
|
|
154
|
+
await holoSphere.put(testHolon, testLens, testData, testPassword);
|
|
155
|
+
await holoSphere.delete(testHolon, testLens, testData.id, testPassword);
|
|
156
|
+
|
|
157
|
+
const result = await holoSphere.get(testHolon, testLens, testData.id, testPassword);
|
|
158
|
+
expect(result).toBeNull();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should handle multiple private data versions', async () => {
|
|
162
|
+
const versions = [
|
|
163
|
+
{ id: 'version1', value: 1 },
|
|
164
|
+
{ id: 'version2', value: 2 },
|
|
165
|
+
{ id: 'version3', value: 3 }
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
// Clean up any existing data first
|
|
169
|
+
await holoSphere.deleteAll(testHolon, testLens, testPassword);
|
|
170
|
+
|
|
171
|
+
// Store each version
|
|
172
|
+
for (const data of versions) {
|
|
173
|
+
await holoSphere.put(testHolon, testLens, data, testPassword);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Wait a bit for data to settle
|
|
177
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
178
|
+
|
|
179
|
+
const results = await holoSphere.getAll(testHolon, testLens, testPassword);
|
|
180
|
+
expect(results.length).toBe(versions.length);
|
|
181
|
+
for (const version of versions) {
|
|
182
|
+
expect(results).toContainEqual(expect.objectContaining(version));
|
|
183
|
+
}
|
|
184
|
+
}, 10000);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('Global Data Operations', () => {
|
|
188
|
+
it('should handle private global data', async () => {
|
|
189
|
+
const testData = { id: 'global', value: 111 };
|
|
190
|
+
|
|
191
|
+
await holoSphere.putGlobal('testTable', testData, testPassword);
|
|
192
|
+
|
|
193
|
+
const result = await holoSphere.getGlobal('testTable', testData.id, testPassword);
|
|
194
|
+
expect(result).toEqual(testData);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should handle public global data', async () => {
|
|
198
|
+
const testData = { id: 'public_global', value: 222 };
|
|
199
|
+
|
|
200
|
+
await holoSphere.putGlobal('testTable', testData);
|
|
201
|
+
|
|
202
|
+
const result = await holoSphere.getGlobal('testTable', testData.id);
|
|
203
|
+
expect(result).toEqual(testData);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should handle getAllGlobal with private data', async () => {
|
|
207
|
+
const testData = [
|
|
208
|
+
{ id: 'global1', value: 1 },
|
|
209
|
+
{ id: 'global2', value: 2 }
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
// Clean up any existing data first
|
|
213
|
+
await holoSphere.deleteAllGlobal('testTable', testPassword);
|
|
214
|
+
|
|
215
|
+
// Store each item
|
|
216
|
+
for (const data of testData) {
|
|
217
|
+
await holoSphere.putGlobal('testTable', data, testPassword);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Wait a bit for data to settle
|
|
221
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
222
|
+
|
|
223
|
+
const results = await holoSphere.getAllGlobal('testTable', testPassword);
|
|
224
|
+
expect(results.length).toBe(testData.length);
|
|
225
|
+
for (const data of testData) {
|
|
226
|
+
expect(results).toContainEqual(expect.objectContaining(data));
|
|
227
|
+
}
|
|
228
|
+
}, 10000);
|
|
229
|
+
|
|
230
|
+
it('should handle deleteGlobal with private data', async () => {
|
|
231
|
+
const testData = { id: 'delete_global', value: 333 };
|
|
232
|
+
|
|
233
|
+
await holoSphere.putGlobal('testTable', testData, testPassword);
|
|
234
|
+
|
|
235
|
+
await holoSphere.deleteGlobal('testTable', testData.id, testPassword);
|
|
236
|
+
|
|
237
|
+
const result = await holoSphere.getGlobal('testTable', testData.id, testPassword);
|
|
238
|
+
expect(result).toBeNull();
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|