Skip to content

Commit a485136

Browse files
committed
completing test suite
1 parent 95c0c3c commit a485136

7 files changed

Lines changed: 426 additions & 2 deletions

tests/applicationClass.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ const { assert } = require('./test-utils/deps-node');
22
const { createUserAndPermissions } = require('./test-utils/pryvService');
33
const HDSLib = require('../js');
44
const Application = HDSLib.appTemplates.Application;
5+
const { helperNewAppManaging } = require('./test-utils/helpersAppTemplate');
56

67
describe('[APAX] Application class', function () {
78
this.timeout(5000);
89
const baseStreamId = 'application-class';
910
const appName = 'application-app';
1011
let user;
1112
before(async () => {
13+
await HDSLib.initHDSModel();
1214
const initialStreams = [{ id: 'applications', name: 'Applications' }, { id: baseStreamId, name: appName, parentId: 'applications' }];
1315
const permissionsManager = [{ streamId: baseStreamId, level: 'manage' }];
1416
user = await createUserAndPermissions(null, permissionsManager, initialStreams, appName);
@@ -134,4 +136,68 @@ describe('[APAX] Application class', function () {
134136
}
135137
});
136138
});
139+
140+
describe('[AMGX] AppManagingAccount tests', function () {
141+
it('[AMGA] getCollectorById returns collector when exists', async () => {
142+
const testBaseStreamId = 'amga-test';
143+
const { appManaging } = await helperNewAppManaging(testBaseStreamId, 'test-AMGA');
144+
const collector = await appManaging.createCollector('Test Collector AMGA');
145+
146+
const foundCollector = await appManaging.getCollectorById(collector.id);
147+
assert.ok(foundCollector);
148+
assert.equal(foundCollector.id, collector.id);
149+
});
150+
151+
it('[AMGB] getCollectorById returns undefined when not exists', async () => {
152+
const testBaseStreamId = 'amgb-test';
153+
const { appManaging } = await helperNewAppManaging(testBaseStreamId, 'test-AMGB');
154+
155+
const foundCollector = await appManaging.getCollectorById('non-existent-id');
156+
assert.equal(foundCollector, undefined);
157+
});
158+
159+
it('[AMGC] getCollectors with forceRefresh reloads data', async () => {
160+
const testBaseStreamId = 'amgc-test';
161+
const { appManaging } = await helperNewAppManaging(testBaseStreamId, 'test-AMGC');
162+
163+
const collectors1 = await appManaging.getCollectors();
164+
assert.equal(collectors1.length, 0);
165+
166+
await appManaging.createCollector('Test Collector AMGC');
167+
const collectors2 = await appManaging.getCollectors(true);
168+
assert.equal(collectors2.length, 1);
169+
});
170+
});
171+
172+
describe('[ACSX] Application setCustomSetting tests', function () {
173+
it('[ACSA] setCustomSetting adds a key', async () => {
174+
class Dummy extends Application {
175+
get appSettings () {
176+
return { };
177+
}
178+
}
179+
const appDummy = await Dummy.newFromApiEndpoint(baseStreamId, user.appApiEndpoint, appName);
180+
181+
await appDummy.setCustomSetting('newKey', 'newValue');
182+
const settings = await appDummy.getCustomSettings();
183+
assert.equal(settings.newKey, 'newValue');
184+
});
185+
186+
it('[ACSB] setCustomSetting with null deletes key', async () => {
187+
class Dummy extends Application {
188+
get appSettings () {
189+
return { };
190+
}
191+
}
192+
const appDummy = await Dummy.newFromApiEndpoint(baseStreamId, user.appApiEndpoint, appName);
193+
194+
await appDummy.setCustomSetting('keyToDelete', 'value');
195+
let settings = await appDummy.getCustomSettings();
196+
assert.equal(settings.keyToDelete, 'value');
197+
198+
await appDummy.setCustomSetting('keyToDelete', null);
199+
settings = await appDummy.getCustomSettings();
200+
assert.equal(settings.keyToDelete, undefined);
201+
});
202+
});
137203
});

tests/apptemplatesRequest.test.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,78 @@
11
const { initHDSModel } = require('../js');
22
const { helperNewAppManaging } = require('./test-utils/helpersAppTemplate');
33
const { assert } = require('./test-utils/deps-node');
4+
const { CollectorRequest } = require('../js/appTemplates/CollectorRequest');
45

56
describe('[APRX] appTemplates Requests', function () {
67
this.timeout(8000);
78

89
before(async () => {
910
await initHDSModel();
1011
});
12+
13+
describe('[AREX] CollectorRequest error cases', function () {
14+
it('[AREA] should throw error for unknown features', () => {
15+
const request = new CollectorRequest({});
16+
try {
17+
request.setContent({
18+
features: { unknownFeature: { setting: 'value' } }
19+
});
20+
throw new Error('Should throw error');
21+
} catch (e) {
22+
assert.equal(e.message, 'Found unkown features');
23+
}
24+
});
25+
26+
it('[AREB] should throw error for invalid chat type', () => {
27+
const request = new CollectorRequest({});
28+
try {
29+
request.addChatFeature({ type: 'invalid' });
30+
throw new Error('Should throw error');
31+
} catch (e) {
32+
assert.equal(e.message, 'Invalid chat type');
33+
}
34+
});
35+
36+
it('[AREC] should throw error for duplicate section key', () => {
37+
const request = new CollectorRequest({});
38+
request.createSection('test-section', 'permanent');
39+
try {
40+
request.createSection('test-section', 'recurring');
41+
throw new Error('Should throw error');
42+
} catch (e) {
43+
assert.equal(e.message, 'Section with key: test-section already exists');
44+
}
45+
});
46+
47+
it('[ARED] should throw error for invalid version', () => {
48+
const request = new CollectorRequest({});
49+
try {
50+
request.setContent({ version: 99 });
51+
throw new Error('Should throw error');
52+
} catch (e) {
53+
assert.equal(e.message, 'Invalid CollectorRequest content version: 99');
54+
}
55+
});
56+
57+
it('[AREE] should handle permissionsExtra in content', () => {
58+
const request = new CollectorRequest({});
59+
request.setContent({
60+
permissionsExtra: [
61+
{ streamId: 'test-stream', level: 'read' }
62+
]
63+
});
64+
assert.equal(request.permissionsExtra.length, 1);
65+
assert.equal(request.permissionsExtra[0].streamId, 'test-stream');
66+
});
67+
68+
it('[AREF] addChatFeature with usernames type', () => {
69+
const request = new CollectorRequest({});
70+
request.addChatFeature({ type: 'usernames' });
71+
assert.deepEqual(request.features.chat, { type: 'usernames' });
72+
assert.equal(request.hasChatFeature, true);
73+
});
74+
});
75+
1176
it('[APRC] Compute a simple request', async () => {
1277
const baseStreamId = 'aprc';
1378
const { appManaging } = await helperNewAppManaging(baseStreamId, 'test-APRC');

tests/hdsModel.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ describe('[MODX] Model', () => {
3838
}
3939
});
4040

41+
// ---------- itemDef ------------ //
42+
describe('[MDVX] itemDef methods', function () {
43+
it('[MDVA] eventTemplate() returns event template with streamId and type', async () => {
44+
const itemDef = model.itemsDefs.forKey('body-weight');
45+
const template = itemDef.eventTemplate();
46+
assert.ok(template.streamIds);
47+
assert.ok(template.type);
48+
assert.deepEqual(template.streamIds, ['body-weight']);
49+
assert.equal(template.type, 'mass/kg'); // first eventType
50+
});
51+
52+
it('[MDVB] eventTemplate() returns correct streamId from data', async () => {
53+
const itemDef = model.itemsDefs.forKey('profile-name');
54+
const template = itemDef.eventTemplate();
55+
assert.deepEqual(template.streamIds, ['profile-name']);
56+
});
57+
});
58+
4159
// ---------- items ------------ //
4260
describe('[MOLX] items localization', function () {
4361
afterEach(() => {

tests/localizeText.test.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,56 @@
11
const { assert } = require('./test-utils/deps-node');
2-
const { resetPreferredLocales, getPreferredLocales, getSupportedLocales, localizeText, setPreferredLocales } = require('../js/localizeText');
2+
const { resetPreferredLocales, getPreferredLocales, getSupportedLocales, localizeText, setPreferredLocales, validateLocalizableText } = require('../js/localizeText');
33

44
describe('[LOCX] Localization', () => {
55
afterEach(() => {
66
// make sure locales are set back to default after each test
77
resetPreferredLocales();
88
});
99

10+
describe('[LOVX] validateLocalizableText', () => {
11+
it('[LOVA] should validate correct localizable text', () => {
12+
const text = { en: 'Hello', fr: 'Bonjour' };
13+
const result = validateLocalizableText('testKey', text);
14+
assert.deepEqual(result, text);
15+
});
16+
17+
it('[LOVB] should throw error if en is missing', () => {
18+
try {
19+
validateLocalizableText('testKey', { fr: 'Bonjour' });
20+
throw new Error('Should throw error');
21+
} catch (e) {
22+
assert.equal(e.message, 'Missing or invalid localizable text for testKey');
23+
}
24+
});
25+
26+
it('[LOVC] should throw error if en is not a string', () => {
27+
try {
28+
validateLocalizableText('testKey', { en: 123 });
29+
throw new Error('Should throw error');
30+
} catch (e) {
31+
assert.equal(e.message, 'Missing or invalid localizable text for testKey');
32+
}
33+
});
34+
35+
it('[LOVD] should throw error if optional language is not a string', () => {
36+
try {
37+
validateLocalizableText('testKey', { en: 'Hello', fr: 123 });
38+
throw new Error('Should throw error');
39+
} catch (e) {
40+
assert.equal(e.message, 'Missing or invalid localizable text for testKey languagecode: fr');
41+
}
42+
});
43+
44+
it('[LOVE] should throw error if es is not a string', () => {
45+
try {
46+
validateLocalizableText('testKey', { en: 'Hello', es: { nested: 'object' } });
47+
throw new Error('Should throw error');
48+
} catch (e) {
49+
assert.equal(e.message, 'Missing or invalid localizable text for testKey languagecode: es');
50+
}
51+
});
52+
});
53+
1054
describe('[LOSX] Localization settings', () => {
1155
it('[LOSG] getSupportedLocales', () => {
1256
const defaultLocales = getSupportedLocales();

tests/logger.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const { assert } = require('./test-utils/deps-node');
2+
3+
const logger = require('../js/logger');
4+
5+
describe('[LOGX] Logger', function () {
6+
describe('[LGFX] Logger functions', function () {
7+
it('[LGFA] info() should call logger.info', () => {
8+
let called = false;
9+
let loggedArgs = null;
10+
const customLogger = {
11+
info: (...args) => { called = true; loggedArgs = args; },
12+
error: () => {},
13+
debug: () => {}
14+
};
15+
logger.setLogger(customLogger);
16+
logger.info('test message', { data: 123 });
17+
assert.equal(called, true);
18+
assert.deepEqual(loggedArgs, ['test message', { data: 123 }]);
19+
});
20+
21+
it('[LGFB] error() should call logger.error', () => {
22+
let called = false;
23+
let loggedArgs = null;
24+
const customLogger = {
25+
info: () => {},
26+
error: (...args) => { called = true; loggedArgs = args; },
27+
debug: () => {}
28+
};
29+
logger.setLogger(customLogger);
30+
logger.error('error message', new Error('test'));
31+
assert.equal(called, true);
32+
assert.equal(loggedArgs[0], 'error message');
33+
});
34+
35+
it('[LGFC] warn() should call logger.info (warn uses info internally)', () => {
36+
let called = false;
37+
let loggedArgs = null;
38+
const customLogger = {
39+
info: (...args) => { called = true; loggedArgs = args; },
40+
error: () => {},
41+
debug: () => {}
42+
};
43+
logger.setLogger(customLogger);
44+
logger.warn('warning message');
45+
assert.equal(called, true);
46+
assert.deepEqual(loggedArgs, ['warning message']);
47+
});
48+
49+
it('[LGFD] setLogger() should replace the logger', () => {
50+
const logs = [];
51+
const customLogger = {
52+
info: (...args) => logs.push(['info', ...args]),
53+
error: (...args) => logs.push(['error', ...args]),
54+
debug: (...args) => logs.push(['debug', ...args])
55+
};
56+
logger.setLogger(customLogger);
57+
logger.info('msg1');
58+
logger.error('msg2');
59+
logger.warn('msg3');
60+
assert.equal(logs.length, 3);
61+
assert.deepEqual(logs[0], ['info', 'msg1']);
62+
assert.deepEqual(logs[1], ['error', 'msg2']);
63+
assert.deepEqual(logs[2], ['info', 'msg3']); // warn uses info
64+
});
65+
});
66+
});

tests/toolkitStreamAutoCreate.test.js

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const HDSLib = require('../js');
44
const { createUserAndPermissions } = require('./test-utils/pryvService');
55

66
describe('[TKSX] toolKit Stream Auto Create', function () {
7-
this.timeout(5000);
7+
this.timeout(10000);
88
before(async () => {
99
await HDSLib.initHDSModel();
1010
});
@@ -27,4 +27,75 @@ describe('[TKSX] toolKit Stream Auto Create', function () {
2727
const createdStream2 = await streamsAutoCreate.ensureExistsForItems(itemKeys);
2828
assert.equal(createdStream2.length, 0, 'Should not recreate existing streams');
2929
});
30+
31+
it('[TKSB] attachToConnection reuses existing instance', async () => {
32+
const permissionsManager = [{ streamId: '*', level: 'manage' }];
33+
const user = await createUserAndPermissions(null, permissionsManager, [], 'tk-test TKSB');
34+
const connection = new HDSLib.pryv.Connection(user.appApiEndpoint);
35+
36+
const streamsAutoCreate1 = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
37+
const streamsAutoCreate2 = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
38+
assert.strictEqual(streamsAutoCreate1, streamsAutoCreate2, 'Should reuse existing instance');
39+
});
40+
41+
it('[TKSC] addStreamStructure adds streams to known list', async () => {
42+
const permissionsManager = [{ streamId: '*', level: 'manage' }];
43+
const user = await createUserAndPermissions(null, permissionsManager, [], 'tk-test TKSC');
44+
const connection = new HDSLib.pryv.Connection(user.appApiEndpoint);
45+
const streamsAutoCreate = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
46+
47+
// Add stream structure
48+
const streamStructure = [
49+
{ id: 'existing-parent', name: 'Existing Parent', children: [{ id: 'existing-child', name: 'Existing Child' }] }
50+
];
51+
streamsAutoCreate.addStreamStructure(streamStructure);
52+
53+
const knownIds = streamsAutoCreate.knowStreamIds();
54+
assert.ok(knownIds.includes('existing-parent'));
55+
assert.ok(knownIds.includes('existing-child'));
56+
});
57+
58+
it('[TKSD] addStreamStructure handles null input', async () => {
59+
const permissionsManager = [{ streamId: '*', level: 'manage' }];
60+
const user = await createUserAndPermissions(null, permissionsManager, [], 'tk-test TKSD');
61+
const connection = new HDSLib.pryv.Connection(user.appApiEndpoint);
62+
const streamsAutoCreate = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
63+
64+
// Should not throw
65+
streamsAutoCreate.addStreamStructure(null);
66+
streamsAutoCreate.addStreamStructure(undefined);
67+
});
68+
69+
it('[TKSE] ensureExistsForItems handles Set input', async () => {
70+
const permissionsManager = [{ streamId: '*', level: 'manage' }];
71+
const user = await createUserAndPermissions(null, permissionsManager, [], 'tk-test TKSE');
72+
const connection = new HDSLib.pryv.Connection(user.appApiEndpoint);
73+
const streamsAutoCreate = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
74+
75+
const itemKeys = new Set(['profile-surname']);
76+
77+
const createdStreams = await streamsAutoCreate.ensureExistsForItems(itemKeys);
78+
assert.ok(createdStreams.length > 0);
79+
});
80+
81+
it('[TKSF] ensureExistsForItems with item-already-exists error continues normally', async () => {
82+
const permissionsManager = [{ streamId: '*', level: 'manage' }];
83+
const user = await createUserAndPermissions(null, permissionsManager, [], 'tk-test TKSF');
84+
const connection = new HDSLib.pryv.Connection(user.appApiEndpoint);
85+
const streamsAutoCreate = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
86+
87+
const itemKeys = ['profile-date-of-birth'];
88+
89+
// Create streams first
90+
await streamsAutoCreate.ensureExistsForItems(itemKeys);
91+
92+
// Create a fresh instance that doesn't know about existing streams
93+
delete connection.streamsAutoCreate;
94+
const freshAutoCreate = HDSLib.toolkit.StreamsAutoCreate.attachToConnection(connection);
95+
96+
// Should handle item-already-exists gracefully
97+
const result = await freshAutoCreate.ensureExistsForItems(itemKeys);
98+
// Since streams exist but freshAutoCreate doesn't know, API returns item-already-exists which is handled
99+
assert.ok(Array.isArray(result));
100+
});
30101
});

0 commit comments

Comments
 (0)