@nymphjs/server 1.0.0-beta.8 → 1.0.0-beta.81

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/src/index.test.ts CHANGED
@@ -2,12 +2,15 @@ import express from 'express';
2
2
  import SQLite3Driver from '@nymphjs/driver-sqlite3';
3
3
  import { Nymph as NymphServer } from '@nymphjs/nymph';
4
4
  import { Nymph } from '@nymphjs/client-node';
5
- import { Entity } from '@nymphjs/client';
5
+ import { Entity, HttpError } from '@nymphjs/client';
6
6
 
7
7
  import createServer from './index';
8
8
  import {
9
9
  EmployeeModel as EmployeeModelClass,
10
10
  Employee as EmployeeClass,
11
+ RestrictedModel as RestrictedModelClass,
12
+ Restricted as RestrictedClass,
13
+ EmployeeData,
11
14
  } from './testArtifacts';
12
15
 
13
16
  const sqliteConfig = {
@@ -16,6 +19,7 @@ const sqliteConfig = {
16
19
 
17
20
  const nymphServer = new NymphServer({}, new SQLite3Driver(sqliteConfig));
18
21
  const EmployeeModel = nymphServer.addEntityClass(EmployeeModelClass);
22
+ const RestrictedModel = nymphServer.addEntityClass(RestrictedModelClass);
19
23
 
20
24
  const app = express();
21
25
  app.use('/test', createServer(nymphServer));
@@ -25,6 +29,7 @@ const nymph = new Nymph({
25
29
  restUrl: 'http://localhost:5080/test/',
26
30
  });
27
31
  const Employee = nymph.addEntityClass(EmployeeClass);
32
+ const Restricted = nymph.addEntityClass(RestrictedClass);
28
33
 
29
34
  describe('Nymph REST Server and Client', () => {
30
35
  async function createJane() {
@@ -129,7 +134,7 @@ describe('Nymph REST Server and Client', () => {
129
134
  {
130
135
  type: '&',
131
136
  ref: ['subordinates', jane],
132
- }
137
+ },
133
138
  );
134
139
 
135
140
  expect(checkSteve?.guid).toEqual(steve.guid);
@@ -142,7 +147,7 @@ describe('Nymph REST Server and Client', () => {
142
147
  'subordinates',
143
148
  [{ class: Employee }, { type: '&', guid: jane.guid }],
144
149
  ],
145
- }
150
+ },
146
151
  );
147
152
 
148
153
  expect(checkSteveQref?.guid).toEqual(steve.guid);
@@ -156,7 +161,7 @@ describe('Nymph REST Server and Client', () => {
156
161
  expect(entity.$hasTag('test', 'test2')).toEqual(true);
157
162
  entity.$addTag('test', 'test3', 'test4', 'test5', 'test6');
158
163
  expect(entity.$hasTag('test', 'test3', 'test4', 'test5', 'test6')).toEqual(
159
- true
164
+ true,
160
165
  );
161
166
  entity.$removeTag('test2');
162
167
  expect(!entity.$hasTag('test2')).toEqual(true);
@@ -178,10 +183,10 @@ describe('Nymph REST Server and Client', () => {
178
183
  'nymph_entity_reference',
179
184
  jane.guid,
180
185
  'Employee',
181
- ]);
182
- await entity.$ready();
186
+ ]) as EmployeeClass & EmployeeData;
187
+ await entity.$wake();
183
188
 
184
- expect(jane?.name).toEqual('Jane Doe');
189
+ expect(entity?.name).toEqual('Jane Doe');
185
190
  });
186
191
 
187
192
  it('change an entity', async () => {
@@ -232,7 +237,7 @@ describe('Nymph REST Server and Client', () => {
232
237
  {
233
238
  type: '&',
234
239
  equal: ['name', 'Jane Doe'],
235
- }
240
+ },
236
241
  );
237
242
 
238
243
  expect(jane).not.toBeNull();
@@ -252,7 +257,7 @@ describe('Nymph REST Server and Client', () => {
252
257
  {
253
258
  type: '&',
254
259
  tag: ['employee'],
255
- }
260
+ },
256
261
  );
257
262
 
258
263
  expect(entities.length).toEqual(4);
@@ -278,13 +283,13 @@ describe('Nymph REST Server and Client', () => {
278
283
 
279
284
  const resultSelectors = await nymph.getEntities(
280
285
  { class: Employee },
281
- { type: '&', equal: ['name', 'Jane Doe'] }
286
+ { type: '&', equal: ['name', 'Jane Doe'] },
282
287
  );
283
288
 
284
289
  // Testing count return with selectors...
285
290
  const resultSelectorsCount = await nymph.getEntities(
286
291
  { class: Employee, return: 'count' },
287
- { type: '&', equal: ['name', 'Jane Doe'] }
292
+ { type: '&', equal: ['name', 'Jane Doe'] },
288
293
  );
289
294
  expect(resultSelectorsCount).toBeGreaterThanOrEqual(1);
290
295
  expect(resultSelectorsCount).toEqual(resultSelectors.length);
@@ -307,7 +312,7 @@ describe('Nymph REST Server and Client', () => {
307
312
  // Testing empty count...
308
313
  const resultSelectorsEmpty = await nymph.getEntities(
309
314
  { class: Employee, return: 'count' },
310
- { type: '&', tag: 'pickle' }
315
+ { type: '&', tag: 'pickle' },
311
316
  );
312
317
  expect(resultSelectorsEmpty).toEqual(0);
313
318
  });
@@ -326,7 +331,7 @@ describe('Nymph REST Server and Client', () => {
326
331
  {
327
332
  type: '&',
328
333
  tag: 'employee',
329
- }
334
+ },
330
335
  );
331
336
 
332
337
  expect(entities.length).toEqual(4);
@@ -352,7 +357,7 @@ describe('Nymph REST Server and Client', () => {
352
357
  {
353
358
  type: '&',
354
359
  like: ['name', '%Jane%'],
355
- }
360
+ },
356
361
  );
357
362
 
358
363
  expect(entities.length).toEqual(4);
@@ -378,7 +383,7 @@ describe('Nymph REST Server and Client', () => {
378
383
  type: '|',
379
384
  like: ['name', '%Jane%'],
380
385
  },
381
- }
386
+ },
382
387
  );
383
388
 
384
389
  expect(entities.length).toEqual(4);
@@ -413,7 +418,7 @@ describe('Nymph REST Server and Client', () => {
413
418
  },
414
419
  ],
415
420
  },
416
- }
421
+ },
417
422
  );
418
423
 
419
424
  expect(entities.length).toEqual(4);
@@ -438,7 +443,7 @@ describe('Nymph REST Server and Client', () => {
438
443
  {
439
444
  type: '&',
440
445
  guid,
441
- }
446
+ },
442
447
  );
443
448
 
444
449
  expect(check.length).toEqual(0);
@@ -461,7 +466,7 @@ describe('Nymph REST Server and Client', () => {
461
466
  {
462
467
  type: '|',
463
468
  guid: guids,
464
- }
469
+ },
465
470
  );
466
471
 
467
472
  expect(check.length).toEqual(0);
@@ -478,7 +483,7 @@ describe('Nymph REST Server and Client', () => {
478
483
  error = e;
479
484
  }
480
485
  expect(error.message).toEqual(
481
- "Can't use Entity class directly from the front end."
486
+ "Can't use Entity class directly from the front end.",
482
487
  );
483
488
  });
484
489
 
@@ -493,32 +498,103 @@ describe('Nymph REST Server and Client', () => {
493
498
  });
494
499
 
495
500
  it('handle server side static error', async () => {
496
- let error = { error: { name: '' } };
501
+ let error = { status: 0, error: { name: '' } };
497
502
  try {
498
503
  await Employee.throwErrorStatic();
499
504
  } catch (e: any) {
500
505
  error = e;
501
506
  }
507
+ expect(error.status).toEqual(500);
508
+ expect(error.error.name).toEqual('BadFunctionCallError');
509
+ });
510
+
511
+ it('handle server side static iterator error', async () => {
512
+ let error: any = { status: 0, error: { name: '' } };
513
+ const data = await Employee.throwErrorStaticIterable();
514
+
515
+ let count = 0;
516
+ for await (let value of data) {
517
+ count++;
518
+ if (value instanceof Error) {
519
+ error = value;
520
+ } else {
521
+ expect(value).toEqual(count);
522
+ }
523
+ }
524
+
525
+ expect(count).toEqual(2);
526
+ expect(error.status).toEqual(500);
502
527
  expect(error.error.name).toEqual('BadFunctionCallError');
503
528
  });
504
529
 
505
530
  it('handle server side error', async () => {
506
531
  const jane = await createJane();
507
532
 
508
- let error = { error: { name: '' } };
533
+ let error = { status: 0, error: { name: '' } };
509
534
  try {
510
535
  await jane.$throwError();
511
536
  } catch (e: any) {
512
537
  error = e;
513
538
  }
539
+ expect(error.status).toEqual(500);
514
540
  expect(error.error.name).toEqual('BadFunctionCallError');
515
541
  });
516
542
 
543
+ it('handle server side HTTP error', async () => {
544
+ const jane = await createJane();
545
+
546
+ let error = { status: 0, statusText: '', message: '' };
547
+ try {
548
+ await jane.$throwHttpError();
549
+ } catch (e: any) {
550
+ error = e;
551
+ }
552
+ expect(error.status).toEqual(501);
553
+ expect(error.statusText).toEqual('Not Implemented');
554
+ expect(error.message).toEqual('A 501 HTTP error.');
555
+ });
556
+
557
+ it('handle server side custom HTTP error', async () => {
558
+ const jane = await createJane();
559
+
560
+ let error = { status: 0, statusText: '', message: '' };
561
+ try {
562
+ await jane.$throwHttpErrorWithDescription();
563
+ } catch (e: any) {
564
+ error = e;
565
+ }
566
+ expect(error.status).toEqual(512);
567
+ expect(error.statusText).toEqual('Some Error');
568
+ expect(error.message).toEqual('A 512 HTTP error.');
569
+ });
570
+
517
571
  it('call a server side static method', async () => {
518
572
  const data = await Employee.testStatic(5);
519
573
  expect(data).toEqual(10);
520
574
  });
521
575
 
576
+ it('call a server side static iterator method', async () => {
577
+ const data = await Employee.testStaticIterable(5);
578
+
579
+ let count = 0;
580
+ for await (let value of data) {
581
+ count++;
582
+ expect(value).toEqual(5 + count);
583
+ }
584
+
585
+ expect(count).toEqual(3);
586
+ });
587
+
588
+ it('aborts a server side static iterator method', async () => {
589
+ const data = await Employee.testStaticIterableAbort();
590
+ data.abortController.abort();
591
+
592
+ // Wait 1 second to ensure server receives abort signal.
593
+ await new Promise((resolve) => setTimeout(resolve, 1000));
594
+
595
+ expect(true).toBeTruthy();
596
+ });
597
+
522
598
  it('call a stateless server side method', async () => {
523
599
  const jane = await createJane();
524
600
 
@@ -547,7 +623,7 @@ describe('Nymph REST Server and Client', () => {
547
623
  {
548
624
  class: Employee,
549
625
  },
550
- jane1.guid
626
+ jane1.guid,
551
627
  );
552
628
  if (jane1 == null || jane2 == null) {
553
629
  throw new Error('Entity is null.');
@@ -573,7 +649,7 @@ describe('Nymph REST Server and Client', () => {
573
649
  {
574
650
  class: Employee,
575
651
  },
576
- first.guid
652
+ first.guid,
577
653
  );
578
654
 
579
655
  if (second == null || second.guid == null) {
@@ -605,7 +681,7 @@ describe('Nymph REST Server and Client', () => {
605
681
  {
606
682
  class: Employee,
607
683
  },
608
- first.guid
684
+ first.guid,
609
685
  );
610
686
 
611
687
  if (second == null || second.guid == null) {
@@ -628,7 +704,7 @@ describe('Nymph REST Server and Client', () => {
628
704
  {
629
705
  type: '&',
630
706
  '!guid': first.guid,
631
- }
707
+ },
632
708
  );
633
709
 
634
710
  if (third == null || third.guid == null) {
@@ -638,6 +714,66 @@ describe('Nymph REST Server and Client', () => {
638
714
  expect(first.$is(third)).toEqual(false);
639
715
  });
640
716
 
717
+ it("doesn't allow creation of a restricted entity class", async () => {
718
+ const attempt = await Restricted.factory();
719
+ attempt.name = 'Jane Doe';
720
+
721
+ let error = null;
722
+
723
+ try {
724
+ await attempt.$save();
725
+ } catch (e: any) {
726
+ error = e;
727
+ }
728
+
729
+ expect(error).toBeInstanceOf(HttpError);
730
+ expect(error.status).toEqual(403);
731
+ });
732
+
733
+ it("doesn't allow search of a restricted entity class", async () => {
734
+ let error = null;
735
+
736
+ try {
737
+ await nymph.getEntity({
738
+ class: Restricted,
739
+ });
740
+ } catch (e: any) {
741
+ error = e;
742
+ }
743
+
744
+ expect(error).toBeInstanceOf(HttpError);
745
+ expect(error.status).toEqual(403);
746
+ });
747
+
748
+ it("doesn't allow methods of a restricted entity class", async () => {
749
+ const attempt = await Restricted.factory();
750
+ attempt.name = 'Jane Doe';
751
+
752
+ let error = null;
753
+
754
+ try {
755
+ await attempt.$testMethod(1);
756
+ } catch (e: any) {
757
+ error = e;
758
+ }
759
+
760
+ expect(error).toBeInstanceOf(HttpError);
761
+ expect(error.status).toEqual(403);
762
+ });
763
+
764
+ it("doesn't allow static methods of a restricted entity class", async () => {
765
+ let error = null;
766
+
767
+ try {
768
+ await Restricted.testStatic(1);
769
+ } catch (e: any) {
770
+ error = e;
771
+ }
772
+
773
+ expect(error).toBeInstanceOf(HttpError);
774
+ expect(error.status).toEqual(403);
775
+ });
776
+
641
777
  it('get a new UID', async () => {
642
778
  const uidValue = await nymph.newUID('employee');
643
779
  expect(typeof uidValue).toEqual('number');