@webex/webex-core 3.0.0-beta.31 → 3.0.0-beta.310
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/dist/lib/batcher.js +1 -1
- package/dist/lib/constants.js +14 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/credentials/credentials.js +61 -22
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/scope.js +21 -6
- package/dist/lib/credentials/scope.js.map +1 -1
- package/dist/lib/credentials/token.js +1 -1
- package/dist/lib/services/interceptors/service.js +4 -2
- package/dist/lib/services/interceptors/service.js.map +1 -1
- package/dist/lib/services/service-catalog.js +2 -1
- package/dist/lib/services/service-catalog.js.map +1 -1
- package/dist/lib/services/services.js +1 -1
- package/dist/plugins/logger.js +1 -1
- package/dist/webex-core.js +7 -2
- package/dist/webex-core.js.map +1 -1
- package/package.json +14 -14
- package/src/lib/constants.js +6 -0
- package/src/lib/credentials/credentials.js +82 -40
- package/src/lib/credentials/scope.js +19 -2
- package/src/lib/services/interceptors/service.js +2 -2
- package/src/lib/services/service-catalog.js +3 -1
- package/src/webex-core.js +13 -1
- package/test/unit/spec/credentials/credentials.js +168 -13
- package/test/unit/spec/credentials/scope.js +55 -0
- package/test/unit/spec/interceptors/auth.js +3 -0
- package/test/unit/spec/services/interceptors/service.js +9 -3
- package/test/unit/spec/webex-core.js +12 -0
|
@@ -11,6 +11,7 @@ import {inBrowser} from '@webex/common';
|
|
|
11
11
|
import FakeTimers from '@sinonjs/fake-timers';
|
|
12
12
|
import {skipInBrowser} from '@webex/test-helper-mocha';
|
|
13
13
|
import Logger from '@webex/plugin-logger';
|
|
14
|
+
import Metrics, {config} from '@webex/internal-plugin-metrics';
|
|
14
15
|
|
|
15
16
|
/* eslint camelcase: [0] */
|
|
16
17
|
|
|
@@ -59,6 +60,34 @@ describe('webex-core', () => {
|
|
|
59
60
|
});
|
|
60
61
|
});
|
|
61
62
|
|
|
63
|
+
describe('#isUnverifiedGuest', () => {
|
|
64
|
+
let credentials;
|
|
65
|
+
let webex;
|
|
66
|
+
beforeEach('generate the webex instance', () => {
|
|
67
|
+
webex = new MockWebex();
|
|
68
|
+
credentials = new Credentials(undefined, {parent: webex});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should have #isUnverifiedGuest', () => {
|
|
72
|
+
assert.exists(credentials.isUnverifiedGuest);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should get the user status and return as a boolean', () => {
|
|
76
|
+
credentials.set('supertoken', 'AT');
|
|
77
|
+
assert.isFalse(credentials.isUnverifiedGuest);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should get guest user ', () => {
|
|
81
|
+
credentials.set('supertoken', 'eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX3R5cGUiOiJndWVzdCJ9');
|
|
82
|
+
assert.isTrue(credentials.isUnverifiedGuest);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should get login user ', () => {
|
|
86
|
+
credentials.set('supertoken', 'dGhpc2lzbm90YXJlYWx1c2VydG9rZW4=');
|
|
87
|
+
assert.isFalse(credentials.isUnverifiedGuest);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
62
91
|
describe('#canAuthorize', () => {
|
|
63
92
|
it('indicates if the current state has enough information to populate an auth header, even if a token refresh or token downscope is required', () => {
|
|
64
93
|
const webex = new MockWebex();
|
|
@@ -417,7 +446,11 @@ describe('webex-core', () => {
|
|
|
417
446
|
});
|
|
418
447
|
|
|
419
448
|
it('schedules a refreshTimer', () => {
|
|
420
|
-
const webex = new MockWebex(
|
|
449
|
+
const webex = new MockWebex({
|
|
450
|
+
children: {
|
|
451
|
+
metrics: Metrics,
|
|
452
|
+
},
|
|
453
|
+
});
|
|
421
454
|
const supertoken = makeToken(webex, {
|
|
422
455
|
access_token: 'ST',
|
|
423
456
|
refresh_token: 'RT',
|
|
@@ -430,6 +463,7 @@ describe('webex-core', () => {
|
|
|
430
463
|
});
|
|
431
464
|
|
|
432
465
|
sinon.stub(supertoken, 'refresh').returns(Promise.resolve(supertoken2));
|
|
466
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
433
467
|
const credentials = new Credentials(supertoken, {parent: webex});
|
|
434
468
|
|
|
435
469
|
webex.trigger('change:config');
|
|
@@ -464,7 +498,19 @@ describe('webex-core', () => {
|
|
|
464
498
|
});
|
|
465
499
|
|
|
466
500
|
describe('#getUserToken()', () => {
|
|
467
|
-
it('resolves with the supertoken if the supertoken matches the requested scopes')
|
|
501
|
+
it('resolves with the supertoken if the supertoken matches the requested scopes', () => {
|
|
502
|
+
const webex = new MockWebex();
|
|
503
|
+
const credentials = new Credentials(undefined, {parent: webex});
|
|
504
|
+
|
|
505
|
+
webex.trigger('change:config');
|
|
506
|
+
const st = makeToken(webex, {access_token: 'ST', scope: 'scope1'});
|
|
507
|
+
|
|
508
|
+
credentials.set({
|
|
509
|
+
supertoken: st,
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
return credentials.getUserToken('scope1').then((result) => assert.deepEqual(result, st));
|
|
513
|
+
});
|
|
468
514
|
|
|
469
515
|
it('resolves with the token identified by the specified scopes', () => {
|
|
470
516
|
const webex = new MockWebex();
|
|
@@ -492,6 +538,25 @@ describe('webex-core', () => {
|
|
|
492
538
|
]);
|
|
493
539
|
});
|
|
494
540
|
|
|
541
|
+
it('uses the supertoken.scope instead of the config.scope for downscope', () => {
|
|
542
|
+
const webex = new MockWebex();
|
|
543
|
+
const credentials = new Credentials(undefined, {parent: webex});
|
|
544
|
+
|
|
545
|
+
webex.trigger('change:config');
|
|
546
|
+
const st = makeToken(webex, {access_token: 'ST', scope: 'scope1 spark:kms'});
|
|
547
|
+
|
|
548
|
+
credentials.set({
|
|
549
|
+
supertoken: st,
|
|
550
|
+
scope: 'invalidScope scope1',
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
sinon.stub(credentials, 'downscope').returns(Promise.resolve());
|
|
554
|
+
|
|
555
|
+
return credentials.getUserToken().then(() => {
|
|
556
|
+
assert.calledWith(credentials.downscope, 'scope1');
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
|
|
495
560
|
describe('when no matching token is found', () => {
|
|
496
561
|
it('downscopes the supertoken', () => {
|
|
497
562
|
const webex = new MockWebex();
|
|
@@ -529,13 +594,13 @@ describe('webex-core', () => {
|
|
|
529
594
|
it('resolves with a token containing all but the kms scopes', () => {
|
|
530
595
|
const webex = new MockWebex();
|
|
531
596
|
|
|
532
|
-
webex.config.credentials.scope = 'scope1 spark:kms';
|
|
533
597
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
534
598
|
|
|
535
599
|
webex.trigger('change:config');
|
|
536
600
|
|
|
537
601
|
credentials.supertoken = makeToken(webex, {
|
|
538
602
|
access_token: 'ST',
|
|
603
|
+
scope: 'scope1 spark:kms',
|
|
539
604
|
});
|
|
540
605
|
|
|
541
606
|
// const t2 = makeToken(webex, {
|
|
@@ -562,9 +627,11 @@ describe('webex-core', () => {
|
|
|
562
627
|
const webex = new MockWebex({
|
|
563
628
|
children: {
|
|
564
629
|
logger: Logger,
|
|
630
|
+
metrics: Metrics,
|
|
565
631
|
},
|
|
566
632
|
});
|
|
567
633
|
|
|
634
|
+
webex.config.metrics = config.metrics;
|
|
568
635
|
webex.config.credentials.scope = 'scope1 spark:kms';
|
|
569
636
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
570
637
|
|
|
@@ -574,9 +641,11 @@ describe('webex-core', () => {
|
|
|
574
641
|
access_token: 'ST',
|
|
575
642
|
});
|
|
576
643
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
644
|
+
const failReason = 'downscope failed';
|
|
645
|
+
sinon.stub(credentials.supertoken, 'downscope').returns(Promise.reject(failReason));
|
|
646
|
+
|
|
647
|
+
sinon.stub(credentials.logger, 'warn').callsFake(() => {});
|
|
648
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
580
649
|
|
|
581
650
|
const t1 = makeToken(webex, {
|
|
582
651
|
access_token: 'AT1',
|
|
@@ -587,14 +656,27 @@ describe('webex-core', () => {
|
|
|
587
656
|
userTokens: [t1],
|
|
588
657
|
});
|
|
589
658
|
|
|
590
|
-
return credentials
|
|
591
|
-
.
|
|
592
|
-
|
|
659
|
+
return credentials.getUserToken('scope2').then((t) => {
|
|
660
|
+
assert.equal(t.access_token, credentials.supertoken.access_token);
|
|
661
|
+
assert.calledWith(
|
|
662
|
+
credentials.logger.warn,
|
|
663
|
+
'credentials: failed to downscope supertoken to "scope2"'
|
|
664
|
+
);
|
|
665
|
+
assert.calledWith(
|
|
666
|
+
webex.internal.metrics.submitClientMetrics,
|
|
667
|
+
'JS_SDK_CREDENTIALS_DOWNSCOPE_FAILED',
|
|
668
|
+
{fields: {failReason, requestedScope: 'scope2'}}
|
|
669
|
+
);
|
|
670
|
+
});
|
|
593
671
|
});
|
|
594
672
|
});
|
|
595
673
|
|
|
596
674
|
it('is blocked while a token refresh is inflight', () => {
|
|
597
|
-
const webex = new MockWebex(
|
|
675
|
+
const webex = new MockWebex({
|
|
676
|
+
children: {
|
|
677
|
+
metrics: Metrics,
|
|
678
|
+
},
|
|
679
|
+
});
|
|
598
680
|
|
|
599
681
|
webex.config.credentials.scope = 'scope1 spark:kms';
|
|
600
682
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
@@ -620,6 +702,7 @@ describe('webex-core', () => {
|
|
|
620
702
|
const at2 = makeToken(webex, {access_token: 'ST2ATD'});
|
|
621
703
|
|
|
622
704
|
sinon.stub(supertoken2, 'downscope').returns(Promise.resolve(at2));
|
|
705
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
623
706
|
|
|
624
707
|
return Promise.all([
|
|
625
708
|
credentials.refresh(),
|
|
@@ -750,18 +833,24 @@ describe('webex-core', () => {
|
|
|
750
833
|
|
|
751
834
|
describe('#refresh()', () => {
|
|
752
835
|
it('refreshes and downscopes the supertoken, and revokes previous tokens', () => {
|
|
753
|
-
const webex = new MockWebex(
|
|
836
|
+
const webex = new MockWebex({
|
|
837
|
+
children: {
|
|
838
|
+
metrics: Metrics,
|
|
839
|
+
},
|
|
840
|
+
});
|
|
754
841
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
755
842
|
|
|
756
843
|
webex.trigger('change:config');
|
|
757
844
|
const st = makeToken(webex, {
|
|
758
845
|
access_token: 'ST',
|
|
759
846
|
refresh_token: 'RT',
|
|
847
|
+
scope: 'scope1 scope2',
|
|
760
848
|
});
|
|
761
849
|
|
|
762
850
|
const st2 = makeToken(webex, {
|
|
763
851
|
access_token: 'ST2',
|
|
764
852
|
refresh_token: 'RT2',
|
|
853
|
+
scope: 'scope1 scope2',
|
|
765
854
|
});
|
|
766
855
|
|
|
767
856
|
const t1 = makeToken(webex, {
|
|
@@ -778,6 +867,7 @@ describe('webex-core', () => {
|
|
|
778
867
|
sinon.stub(st, 'refresh').returns(Promise.resolve(st2));
|
|
779
868
|
sinon.stub(t1, 'revoke').returns(Promise.resolve());
|
|
780
869
|
sinon.spy(credentials, 'scheduleRefresh');
|
|
870
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
781
871
|
|
|
782
872
|
credentials.set({
|
|
783
873
|
supertoken: st,
|
|
@@ -797,7 +887,11 @@ describe('webex-core', () => {
|
|
|
797
887
|
});
|
|
798
888
|
|
|
799
889
|
it('refreshes and downscopes the supertoken even if revocation of previous token fails', () => {
|
|
800
|
-
const webex = new MockWebex(
|
|
890
|
+
const webex = new MockWebex({
|
|
891
|
+
children: {
|
|
892
|
+
metrics: Metrics,
|
|
893
|
+
},
|
|
894
|
+
});
|
|
801
895
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
802
896
|
|
|
803
897
|
webex.trigger('change:config');
|
|
@@ -809,6 +903,7 @@ describe('webex-core', () => {
|
|
|
809
903
|
const st2 = makeToken(webex, {
|
|
810
904
|
access_token: 'ST2',
|
|
811
905
|
refresh_token: 'RT2',
|
|
906
|
+
scope: 'scope1 scope2',
|
|
812
907
|
});
|
|
813
908
|
|
|
814
909
|
const t1 = makeToken(webex, {
|
|
@@ -825,6 +920,7 @@ describe('webex-core', () => {
|
|
|
825
920
|
sinon.stub(st, 'refresh').returns(Promise.resolve(st2));
|
|
826
921
|
sinon.stub(t1, 'revoke').returns(Promise.reject());
|
|
827
922
|
sinon.spy(credentials, 'scheduleRefresh');
|
|
923
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
828
924
|
|
|
829
925
|
credentials.set({
|
|
830
926
|
supertoken: st,
|
|
@@ -847,6 +943,7 @@ describe('webex-core', () => {
|
|
|
847
943
|
const webex = new MockWebex({
|
|
848
944
|
children: {
|
|
849
945
|
logger: Logger,
|
|
946
|
+
metrics: Metrics,
|
|
850
947
|
},
|
|
851
948
|
});
|
|
852
949
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
@@ -855,9 +952,11 @@ describe('webex-core', () => {
|
|
|
855
952
|
const st = makeToken(webex, {
|
|
856
953
|
access_token: 'ST',
|
|
857
954
|
refresh_token: 'RT',
|
|
955
|
+
scope: '',
|
|
858
956
|
});
|
|
859
957
|
|
|
860
958
|
sinon.stub(st, 'refresh').returns(Promise.resolve(makeToken(webex, {access_token: 'ST2'})));
|
|
959
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
861
960
|
|
|
862
961
|
const t1 = makeToken(webex, {
|
|
863
962
|
access_token: 'AT1',
|
|
@@ -873,7 +972,7 @@ describe('webex-core', () => {
|
|
|
873
972
|
});
|
|
874
973
|
|
|
875
974
|
it('allows #getUserToken() to be revoked, but #getUserToken() promises will not resolve until the suport token has been refreshed', () => {
|
|
876
|
-
const webex = new MockWebex();
|
|
975
|
+
const webex = new MockWebex({children: {metrics: Metrics}});
|
|
877
976
|
const credentials = new Credentials(undefined, {parent: webex});
|
|
878
977
|
|
|
879
978
|
webex.trigger('change:config');
|
|
@@ -899,6 +998,7 @@ describe('webex-core', () => {
|
|
|
899
998
|
|
|
900
999
|
sinon.stub(st1, 'refresh').returns(Promise.resolve(st2));
|
|
901
1000
|
sinon.stub(st2, 'downscope').returns(Promise.resolve(t2));
|
|
1001
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
902
1002
|
|
|
903
1003
|
credentials.set({
|
|
904
1004
|
supertoken: st1,
|
|
@@ -955,6 +1055,61 @@ describe('webex-core', () => {
|
|
|
955
1055
|
assert.calledWith(triggerSpy, sinon.match('client:InvalidRequestError'));
|
|
956
1056
|
});
|
|
957
1057
|
});
|
|
1058
|
+
|
|
1059
|
+
it('exclude invalid scopes from user token, log and call metrics when fetched supertoken scope mismatch with the configured scope', () => {
|
|
1060
|
+
const webex = new MockWebex({
|
|
1061
|
+
children: {
|
|
1062
|
+
logger: Logger,
|
|
1063
|
+
metrics: Metrics,
|
|
1064
|
+
},
|
|
1065
|
+
});
|
|
1066
|
+
const credentials = new Credentials(undefined, {parent: webex});
|
|
1067
|
+
|
|
1068
|
+
webex.trigger('change:config');
|
|
1069
|
+
const st = makeToken(webex, {
|
|
1070
|
+
access_token: 'ST',
|
|
1071
|
+
refresh_token: 'RT',
|
|
1072
|
+
});
|
|
1073
|
+
|
|
1074
|
+
const st2 = makeToken(webex, {
|
|
1075
|
+
access_token: 'ST2',
|
|
1076
|
+
refresh_token: 'RT2',
|
|
1077
|
+
scope: 'scope1',
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
const userToken = makeToken(webex, {
|
|
1081
|
+
access_token: 'AT1',
|
|
1082
|
+
scope: 'scope1 invalidScope1',
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
credentials.set({
|
|
1086
|
+
supertoken: st,
|
|
1087
|
+
userTokens: [userToken],
|
|
1088
|
+
});
|
|
1089
|
+
const invalidScopes = 'invalidScope1 invalidScope2';
|
|
1090
|
+
credentials.config.scope = `scope1 ${invalidScopes}`;
|
|
1091
|
+
|
|
1092
|
+
sinon.stub(st2, 'downscope').returns(Promise.resolve());
|
|
1093
|
+
sinon.stub(st, 'refresh').returns(Promise.resolve(st2));
|
|
1094
|
+
sinon.spy(credentials, 'downscope');
|
|
1095
|
+
sinon.spy(credentials, 'scheduleRefresh');
|
|
1096
|
+
|
|
1097
|
+
sinon.stub(credentials.logger, 'warn').callsFake(() => {});
|
|
1098
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
1099
|
+
|
|
1100
|
+
return credentials.refresh().then(() => {
|
|
1101
|
+
assert.calledWith(
|
|
1102
|
+
credentials.logger.warn,
|
|
1103
|
+
`credentials: "${invalidScopes}" scope(s) are invalid because not listed in the supertoken, they will be excluded from user token requests.`
|
|
1104
|
+
);
|
|
1105
|
+
assert.calledWith(
|
|
1106
|
+
webex.internal.metrics.submitClientMetrics,
|
|
1107
|
+
'JS_SDK_CREDENTIALS_TOKEN_REFRESH_SCOPE_MISMATCH',
|
|
1108
|
+
{fields: {invalidScopes}}
|
|
1109
|
+
);
|
|
1110
|
+
assert.calledWith(credentials.downscope, 'scope1');
|
|
1111
|
+
});
|
|
1112
|
+
});
|
|
958
1113
|
});
|
|
959
1114
|
|
|
960
1115
|
describe('#scheduleRefresh()', () => {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {assert} from '@webex/test-helper-chai';
|
|
2
|
+
import {sortScope, filterScope, diffScopes} from '@webex/webex-core/src/lib/credentials/scope';
|
|
3
|
+
|
|
4
|
+
describe('webex-core', () => {
|
|
5
|
+
describe('scope utils', () => {
|
|
6
|
+
describe('sortScope', () => {
|
|
7
|
+
it('should sort scopes alphabetically', () => {
|
|
8
|
+
assert.equal(sortScope(undefined), '');
|
|
9
|
+
assert.equal(sortScope(''), '');
|
|
10
|
+
assert.equal(sortScope('a'), 'a');
|
|
11
|
+
assert.equal(sortScope('b c a'), 'a b c');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('filterScope', () => {
|
|
16
|
+
it('should filter out one scope from the original scope and sort the result', () => {
|
|
17
|
+
assert.equal(filterScope('a', undefined), '');
|
|
18
|
+
assert.equal(filterScope('a', ''), '');
|
|
19
|
+
assert.equal(filterScope('a', 'a'), '');
|
|
20
|
+
assert.equal(filterScope('a', 'a b c'), 'b c');
|
|
21
|
+
assert.equal(filterScope('c', 'a c b'), 'a b');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should filter out a list of scopes from the original scope and sort the result', () => {
|
|
25
|
+
assert.equal(filterScope([], 'a'), 'a');
|
|
26
|
+
assert.equal(filterScope(['a', 'b'], undefined), '');
|
|
27
|
+
assert.equal(filterScope(['a', 'b'], ''), '');
|
|
28
|
+
assert.equal(filterScope(['a', 'b'], 'a'), '');
|
|
29
|
+
assert.equal(filterScope(['a', 'b'], 'a b c'), 'c');
|
|
30
|
+
assert.equal(filterScope(['a', 'd'], 'a c a b'), 'b c');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('diffScopes', () => {
|
|
35
|
+
it('should return an empty string, if all items in the first scope are contained in the second scope', () => {
|
|
36
|
+
assert.deepEqual(diffScopes(undefined, undefined), '');
|
|
37
|
+
assert.deepEqual(diffScopes(undefined, ''), '');
|
|
38
|
+
assert.deepEqual(diffScopes('', undefined), '');
|
|
39
|
+
assert.deepEqual(diffScopes('', ''), '');
|
|
40
|
+
assert.deepEqual(diffScopes('a', 'a'), '');
|
|
41
|
+
assert.deepEqual(diffScopes('a b c', 'a b c'), '');
|
|
42
|
+
assert.deepEqual(diffScopes(undefined, 'a b c'), '');
|
|
43
|
+
assert.deepEqual(diffScopes('a b c', 'a b c d'), '');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should return a string containing all items in the first scope that are not in the second scope', () => {
|
|
47
|
+
assert.deepEqual(diffScopes('a', undefined), 'a');
|
|
48
|
+
assert.deepEqual(diffScopes('a', 'b'), 'a');
|
|
49
|
+
assert.deepEqual(diffScopes('a b c', 'a b'), 'c');
|
|
50
|
+
assert.deepEqual(diffScopes('a b c d', 'a b c'), 'd');
|
|
51
|
+
assert.deepEqual(diffScopes('a b c', undefined), 'a b c');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -12,6 +12,7 @@ import Logger from '@webex/plugin-logger';
|
|
|
12
12
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
13
13
|
import {AuthInterceptor, config, Credentials, WebexHttpError, Token} from '@webex/webex-core';
|
|
14
14
|
import {cloneDeep, merge} from 'lodash';
|
|
15
|
+
import Metrics from '@webex/internal-plugin-metrics';
|
|
15
16
|
|
|
16
17
|
const {assert} = chai;
|
|
17
18
|
|
|
@@ -28,6 +29,7 @@ describe('webex-core', () => {
|
|
|
28
29
|
children: {
|
|
29
30
|
credentials: Credentials,
|
|
30
31
|
logger: Logger,
|
|
32
|
+
metrics: Metrics,
|
|
31
33
|
},
|
|
32
34
|
config: merge(cloneDeep(config), {credentials: {client_secret: 'fake'}}),
|
|
33
35
|
});
|
|
@@ -41,6 +43,7 @@ describe('webex-core', () => {
|
|
|
41
43
|
);
|
|
42
44
|
|
|
43
45
|
interceptor = Reflect.apply(AuthInterceptor.create, webex, []);
|
|
46
|
+
sinon.stub(webex.internal.metrics, 'submitClientMetrics').callsFake(() => {});
|
|
44
47
|
});
|
|
45
48
|
|
|
46
49
|
describe('#onRequest()', () => {
|
|
@@ -5,6 +5,7 @@ import chai from 'chai';
|
|
|
5
5
|
import chaiAsPromised from 'chai-as-promised';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
7
|
import {ServiceInterceptor} from '@webex/webex-core';
|
|
8
|
+
import CONFIG from '../../../../../src/config';
|
|
8
9
|
|
|
9
10
|
const {assert} = chai;
|
|
10
11
|
|
|
@@ -26,6 +27,7 @@ describe('webex-core', () => {
|
|
|
26
27
|
service: 'example',
|
|
27
28
|
serviceUrl: 'https://www.example-service.com/',
|
|
28
29
|
uri: 'https://www.example-uri.com/',
|
|
30
|
+
waitForServiceTimeout: 11,
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
options = {};
|
|
@@ -107,6 +109,7 @@ describe('webex-core', () => {
|
|
|
107
109
|
|
|
108
110
|
options.service = fixture.service;
|
|
109
111
|
options.resource = fixture.resource;
|
|
112
|
+
options.timeout = fixture.waitForServiceTimeout;
|
|
110
113
|
});
|
|
111
114
|
|
|
112
115
|
it('should normalize the options', () =>
|
|
@@ -116,9 +119,12 @@ describe('webex-core', () => {
|
|
|
116
119
|
interceptor.onRequest(options).then(() => assert.called(interceptor.validateOptions)));
|
|
117
120
|
|
|
118
121
|
it('should attempt to collect the service url', () =>
|
|
119
|
-
interceptor
|
|
120
|
-
.
|
|
121
|
-
|
|
122
|
+
interceptor.onRequest(options).then(
|
|
123
|
+
assert.calledWith(waitForService, {
|
|
124
|
+
name: options.service,
|
|
125
|
+
timeout: options.waitForServiceTimeout,
|
|
126
|
+
})
|
|
127
|
+
));
|
|
122
128
|
|
|
123
129
|
describe('when the service url was collected successfully', () => {
|
|
124
130
|
beforeEach('generate additional mocks', () => {});
|
|
@@ -54,6 +54,18 @@ describe('Webex', () => {
|
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
+
describe('#request', () => {
|
|
58
|
+
it('exists', () => {
|
|
59
|
+
assert.property(webex, 'request');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('#prepareFetchOptions', () => {
|
|
64
|
+
it('exists', () => {
|
|
65
|
+
assert.property(webex, 'prepareFetchOptions');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
57
69
|
describe('#initialize()', () => {
|
|
58
70
|
it('initializes without arguments', () => {
|
|
59
71
|
let webex;
|