feat: init
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
# Angular Lib for OpenID Connect & OAuth2
|
# Angular Lib for OpenID Connect & OAuth2
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
 [](https://www.npmjs.com/package/oidc-client-rx) [](https://www.npmjs.com/package/oidc-client-rx) [](https://www.npmjs.com/package/oidc-client-rx) [](https://github.com/prettier/prettier) [](https://coveralls.io/github/damienbod/oidc-client-rx?branch=main)
|
 [](https://www.npmjs.com/package/oidc-client-rx) [](https://www.npmjs.com/package/oidc-client-rx) [](https://www.npmjs.com/package/oidc-client-rx) [](https://github.com/prettier/prettier) [](https://coveralls.io/github/damienbod/oidc-client-rx?branch=main)
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -155,7 +157,7 @@ const token = this.oidcSecurityService.getAccessToken().subscribe(...);
|
|||||||
And then you can use it in the HttpHeaders
|
And then you can use it in the HttpHeaders
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { HttpHeaders } from '@angular/common/http';
|
import { HttpHeaders } from '@ngify/http';
|
||||||
|
|
||||||
const token = this.oidcSecurityServices.getAccessToken().subscribe((token) => {
|
const token = this.oidcSecurityServices.getAccessToken().subscribe((token) => {
|
||||||
const httpOptions = {
|
const httpOptions = {
|
||||||
|
|||||||
@@ -18,8 +18,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"ignore": [
|
"ignore": [".vscode/*.json"]
|
||||||
".vscode/*.json"
|
},
|
||||||
]
|
"overrides": [
|
||||||
}
|
{
|
||||||
|
"include": ["src/**/*.spec.ts", "src/test.ts", "test"],
|
||||||
|
"javascript": {
|
||||||
|
"globals": ["describe", "beforeEach", "it", "expect"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// Karma configuration file, see link for more information
|
|
||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
|
||||||
config.set({
|
|
||||||
basePath: '',
|
|
||||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
|
||||||
plugins: [
|
|
||||||
require('karma-jasmine'),
|
|
||||||
require('karma-chrome-launcher'),
|
|
||||||
require('karma-jasmine-html-reporter'),
|
|
||||||
require('karma-coverage'),
|
|
||||||
require('@angular-devkit/build-angular/plugins/karma'),
|
|
||||||
],
|
|
||||||
client: {
|
|
||||||
jasmine: {
|
|
||||||
// you can add configuration options for Jasmine here
|
|
||||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
|
||||||
// for example, you can disable the random execution with `random: false`
|
|
||||||
// or set a specific seed with `seed: 4321`
|
|
||||||
},
|
|
||||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
|
||||||
},
|
|
||||||
jasmineHtmlReporter: {
|
|
||||||
suppressAll: true, // removes the duplicated traces
|
|
||||||
},
|
|
||||||
coverageReporter: {
|
|
||||||
dir: require('path').join(
|
|
||||||
__dirname,
|
|
||||||
'../../coverage/oidc-client-rx'
|
|
||||||
),
|
|
||||||
subdir: '.',
|
|
||||||
reporters: [{ type: 'html' }, { type: 'text-summary' }, { type: 'lcov' }],
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
customLaunchers: {
|
|
||||||
ChromeHeadlessNoSandbox: {
|
|
||||||
base: 'ChromeHeadless',
|
|
||||||
flags: ['--no-sandbox'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
singleRun: false,
|
|
||||||
restartOnFileChange: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
3006
package-lock.json
generated
Normal file
3006
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@@ -22,9 +22,7 @@
|
|||||||
"main": "./dist/index.cjs",
|
"main": "./dist/index.cjs",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"files": [
|
"files": ["dist"],
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rslib build",
|
"build": "rslib build",
|
||||||
"dev": "rslib build --watch",
|
"dev": "rslib build --watch",
|
||||||
@@ -39,19 +37,24 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ngify/http": "^2.0.4",
|
"@ngify/http": "^2.0.4",
|
||||||
"injection-js": "git+https://github.com/mgechev/injection-js.git#81a10e0",
|
"injection-js": "git+https://github.com/mgechev/injection-js.git#81a10e0",
|
||||||
"rxjs": ">=7.4.0"
|
"reflect-metadata": "^0.2.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rxjs": "^7.4.0||>=8.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@evilmartians/lefthook": "^1.0.3",
|
"@evilmartians/lefthook": "^1.0.3",
|
||||||
"@playwright/test": "^1.49.1",
|
"@playwright/test": "^1.49.1",
|
||||||
"@rslib/core": "^0.3.1",
|
"@rslib/core": "^0.3.1",
|
||||||
"@types/jasmine": "^4.0.0",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.10.1",
|
"@types/node": "^22.10.1",
|
||||||
"@vitest/coverage-v8": "^3.0.1",
|
"@vitest/coverage-v8": "^3.0.1",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"rfc4648": "^1.5.0",
|
"rfc4648": "^1.5.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"ultracite": "^4.1.15",
|
"ultracite": "^4.1.15",
|
||||||
"vitest": "^3.0.1"
|
"vitest": "^3.0.1",
|
||||||
|
"rxjs": "^7.4.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"rxjs",
|
"rxjs",
|
||||||
|
|||||||
41
pnpm-lock.yaml
generated
41
pnpm-lock.yaml
generated
@@ -14,9 +14,9 @@ importers:
|
|||||||
injection-js:
|
injection-js:
|
||||||
specifier: git+https://github.com/mgechev/injection-js.git#81a10e0
|
specifier: git+https://github.com/mgechev/injection-js.git#81a10e0
|
||||||
version: https://codeload.github.com/mgechev/injection-js/tar.gz/81a10e0
|
version: https://codeload.github.com/mgechev/injection-js/tar.gz/81a10e0
|
||||||
rxjs:
|
reflect-metadata:
|
||||||
specifier: '>=7.4.0'
|
specifier: ^0.2.2
|
||||||
version: 7.8.1
|
version: 0.2.2
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@evilmartians/lefthook':
|
'@evilmartians/lefthook':
|
||||||
specifier: ^1.0.3
|
specifier: ^1.0.3
|
||||||
@@ -27,18 +27,24 @@ importers:
|
|||||||
'@rslib/core':
|
'@rslib/core':
|
||||||
specifier: ^0.3.1
|
specifier: ^0.3.1
|
||||||
version: 0.3.1(typescript@5.7.3)
|
version: 0.3.1(typescript@5.7.3)
|
||||||
'@types/jasmine':
|
'@types/lodash-es':
|
||||||
specifier: ^4.0.0
|
specifier: ^4.17.12
|
||||||
version: 4.6.4
|
version: 4.17.12
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.10.1
|
specifier: ^22.10.1
|
||||||
version: 22.10.7
|
version: 22.10.7
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.1(vitest@3.0.1(@types/node@22.10.7))
|
version: 3.0.1(vitest@3.0.1(@types/node@22.10.7))
|
||||||
|
lodash-es:
|
||||||
|
specifier: ^4.17.21
|
||||||
|
version: 4.17.21
|
||||||
rfc4648:
|
rfc4648:
|
||||||
specifier: ^1.5.0
|
specifier: ^1.5.0
|
||||||
version: 1.5.4
|
version: 1.5.4
|
||||||
|
rxjs:
|
||||||
|
specifier: ^7.4.0
|
||||||
|
version: 7.8.1
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.7.3
|
specifier: ^5.7.3
|
||||||
version: 5.7.3
|
version: 5.7.3
|
||||||
@@ -469,8 +475,11 @@ packages:
|
|||||||
'@types/estree@1.0.6':
|
'@types/estree@1.0.6':
|
||||||
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
||||||
|
|
||||||
'@types/jasmine@4.6.4':
|
'@types/lodash-es@4.17.12':
|
||||||
resolution: {integrity: sha512-qCw5sVW+ylTnrEhe5kfX4l6MgU9REXIVDa/lWEcvTOUmd+LqDYwyjovDq+Zk9blElaEHOj1URDQ/djEBVRf+pw==}
|
resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
|
||||||
|
|
||||||
|
'@types/lodash@4.17.15':
|
||||||
|
resolution: {integrity: sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==}
|
||||||
|
|
||||||
'@types/node@22.10.7':
|
'@types/node@22.10.7':
|
||||||
resolution: {integrity: sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==}
|
resolution: {integrity: sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==}
|
||||||
@@ -677,6 +686,9 @@ packages:
|
|||||||
jackspeak@3.4.3:
|
jackspeak@3.4.3:
|
||||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||||
|
|
||||||
|
lodash-es@4.17.21:
|
||||||
|
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||||
|
|
||||||
loupe@3.1.2:
|
loupe@3.1.2:
|
||||||
resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==}
|
resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==}
|
||||||
|
|
||||||
@@ -748,6 +760,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
|
resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
|
|
||||||
|
reflect-metadata@0.2.2:
|
||||||
|
resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
|
||||||
|
|
||||||
rfc4648@1.5.4:
|
rfc4648@1.5.4:
|
||||||
resolution: {integrity: sha512-rRg/6Lb+IGfJqO05HZkN50UtY7K/JhxJag1kP23+zyMfrvoB0B7RWv06MbOzoc79RgCdNTiUaNsTT1AJZ7Z+cg==}
|
resolution: {integrity: sha512-rRg/6Lb+IGfJqO05HZkN50UtY7K/JhxJag1kP23+zyMfrvoB0B7RWv06MbOzoc79RgCdNTiUaNsTT1AJZ7Z+cg==}
|
||||||
|
|
||||||
@@ -1244,7 +1259,11 @@ snapshots:
|
|||||||
|
|
||||||
'@types/estree@1.0.6': {}
|
'@types/estree@1.0.6': {}
|
||||||
|
|
||||||
'@types/jasmine@4.6.4': {}
|
'@types/lodash-es@4.17.12':
|
||||||
|
dependencies:
|
||||||
|
'@types/lodash': 4.17.15
|
||||||
|
|
||||||
|
'@types/lodash@4.17.15': {}
|
||||||
|
|
||||||
'@types/node@22.10.7':
|
'@types/node@22.10.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1469,6 +1488,8 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@pkgjs/parseargs': 0.11.0
|
'@pkgjs/parseargs': 0.11.0
|
||||||
|
|
||||||
|
lodash-es@4.17.21: {}
|
||||||
|
|
||||||
loupe@3.1.2: {}
|
loupe@3.1.2: {}
|
||||||
|
|
||||||
lru-cache@10.4.3: {}
|
lru-cache@10.4.3: {}
|
||||||
@@ -1528,6 +1549,8 @@ snapshots:
|
|||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
|
|
||||||
|
reflect-metadata@0.2.2: {}
|
||||||
|
|
||||||
rfc4648@1.5.4: {}
|
rfc4648@1.5.4: {}
|
||||||
|
|
||||||
rollup@4.30.1:
|
rollup@4.30.1:
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
|
import { TestBed } from '@/testing/testbed';
|
||||||
import {
|
import {
|
||||||
HttpHeaders,
|
HttpHeaders,
|
||||||
provideHttpClient,
|
provideHttpClient,
|
||||||
withInterceptorsFromDi,
|
withInterceptorsFromDi,
|
||||||
} from '@angular/common/http';
|
} from '@ngify/http';
|
||||||
import {
|
import {
|
||||||
HttpTestingController,
|
HttpTestingController,
|
||||||
provideHttpClientTesting,
|
provideHttpClientTesting,
|
||||||
} from '@angular/common/http/testing';
|
} from '@ngify/http/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { lastValueFrom } from 'rxjs';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { DataService } from './data.service';
|
import { DataService } from './data.service';
|
||||||
import { HttpBaseService } from './http-base.service';
|
import { HttpBaseService } from './http-base.service';
|
||||||
|
|
||||||
@@ -25,9 +27,6 @@ describe('Data Service', () => {
|
|||||||
provideHttpClientTesting(),
|
provideHttpClientTesting(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
dataService = TestBed.inject(DataService);
|
dataService = TestBed.inject(DataService);
|
||||||
httpMock = TestBed.inject(HttpTestingController);
|
httpMock = TestBed.inject(HttpTestingController);
|
||||||
});
|
});
|
||||||
@@ -37,7 +36,7 @@ describe('Data Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('get', () => {
|
describe('get', () => {
|
||||||
it('get call sets the accept header', waitForAsync(() => {
|
it('get call sets the accept header', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
|
|
||||||
dataService
|
dataService
|
||||||
@@ -53,9 +52,9 @@ describe('Data Service', () => {
|
|||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('get call with token the accept header and the token', waitForAsync(() => {
|
it('get call with token the accept header and the token', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
const token = 'token';
|
const token = 'token';
|
||||||
|
|
||||||
@@ -68,14 +67,14 @@ describe('Data Service', () => {
|
|||||||
|
|
||||||
expect(req.request.method).toBe('GET');
|
expect(req.request.method).toBe('GET');
|
||||||
expect(req.request.headers.get('Accept')).toBe('application/json');
|
expect(req.request.headers.get('Accept')).toBe('application/json');
|
||||||
expect(req.request.headers.get('Authorization')).toBe('Bearer ' + token);
|
expect(req.request.headers.get('Authorization')).toBe(`Bearer ${token}`);
|
||||||
|
|
||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('call without ngsw-bypass param by default', waitForAsync(() => {
|
it('call without ngsw-bypass param by default', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
|
|
||||||
dataService
|
dataService
|
||||||
@@ -92,9 +91,9 @@ describe('Data Service', () => {
|
|||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('call with ngsw-bypass param', waitForAsync(() => {
|
it('call with ngsw-bypass param', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
|
|
||||||
dataService
|
dataService
|
||||||
@@ -102,7 +101,7 @@ describe('Data Service', () => {
|
|||||||
.subscribe((data: unknown) => {
|
.subscribe((data: unknown) => {
|
||||||
expect(data).toBe('bodyData');
|
expect(data).toBe('bodyData');
|
||||||
});
|
});
|
||||||
const req = httpMock.expectOne(url + '?ngsw-bypass=');
|
const req = httpMock.expectOne(`${url}?ngsw-bypass=`);
|
||||||
|
|
||||||
expect(req.request.method).toBe('GET');
|
expect(req.request.method).toBe('GET');
|
||||||
expect(req.request.headers.get('Accept')).toBe('application/json');
|
expect(req.request.headers.get('Accept')).toBe('application/json');
|
||||||
@@ -111,11 +110,11 @@ describe('Data Service', () => {
|
|||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('post', () => {
|
describe('post', () => {
|
||||||
it('call sets the accept header when no other params given', waitForAsync(() => {
|
it('call sets the accept header when no other params given', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
|
|
||||||
dataService
|
dataService
|
||||||
@@ -128,18 +127,23 @@ describe('Data Service', () => {
|
|||||||
|
|
||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
await httpMock.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('call sets custom headers ONLY (No ACCEPT header) when custom headers are given', waitForAsync(() => {
|
it('call sets custom headers ONLY (No ACCEPT header) when custom headers are given', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
let headers = new HttpHeaders();
|
let headers = new HttpHeaders();
|
||||||
|
|
||||||
headers = headers.set('X-MyHeader', 'Genesis');
|
headers = headers.set('X-MyHeader', 'Genesis');
|
||||||
|
|
||||||
dataService
|
await lastValueFrom(
|
||||||
.post(url, { some: 'thing' }, { configId: 'configId1' }, headers)
|
dataService.post(
|
||||||
.subscribe();
|
url,
|
||||||
|
{ some: 'thing' },
|
||||||
|
{ configId: 'configId1' },
|
||||||
|
headers
|
||||||
|
)
|
||||||
|
);
|
||||||
const req = httpMock.expectOne(url);
|
const req = httpMock.expectOne(url);
|
||||||
|
|
||||||
expect(req.request.method).toBe('POST');
|
expect(req.request.method).toBe('POST');
|
||||||
@@ -149,14 +153,14 @@ describe('Data Service', () => {
|
|||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('call without ngsw-bypass param by default', waitForAsync(() => {
|
it('call without ngsw-bypass param by default', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
|
|
||||||
dataService
|
await lastValueFrom(
|
||||||
.post(url, { some: 'thing' }, { configId: 'configId1' })
|
dataService.post(url, { some: 'thing' }, { configId: 'configId1' })
|
||||||
.subscribe();
|
);
|
||||||
const req = httpMock.expectOne(url);
|
const req = httpMock.expectOne(url);
|
||||||
|
|
||||||
expect(req.request.method).toBe('POST');
|
expect(req.request.method).toBe('POST');
|
||||||
@@ -166,18 +170,19 @@ describe('Data Service', () => {
|
|||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('call with ngsw-bypass param', waitForAsync(() => {
|
it('call with ngsw-bypass param', async () => {
|
||||||
const url = 'testurl';
|
const url = 'testurl';
|
||||||
|
|
||||||
dataService
|
await lastValueFrom(
|
||||||
.post(
|
dataService.post(
|
||||||
url,
|
url,
|
||||||
{ some: 'thing' },
|
{ some: 'thing' },
|
||||||
{ configId: 'configId1', ngswBypass: true }
|
{ configId: 'configId1', ngswBypass: true }
|
||||||
)
|
)
|
||||||
.subscribe();
|
);
|
||||||
|
// biome-ignore lint/style/useTemplate: <explanation>
|
||||||
const req = httpMock.expectOne(url + '?ngsw-bypass=');
|
const req = httpMock.expectOne(url + '?ngsw-bypass=');
|
||||||
|
|
||||||
expect(req.request.method).toBe('POST');
|
expect(req.request.method).toBe('POST');
|
||||||
@@ -187,6 +192,6 @@ describe('Data Service', () => {
|
|||||||
req.flush('bodyData');
|
req.flush('bodyData');
|
||||||
|
|
||||||
httpMock.verify();
|
httpMock.verify();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { PassedInitialConfig, createStaticLoader } from './auth-config';
|
import { type PassedInitialConfig, createStaticLoader } from './auth-config';
|
||||||
|
|
||||||
describe('AuthConfig', () => {
|
describe('AuthConfig', () => {
|
||||||
describe('createStaticLoader', () => {
|
describe('createStaticLoader', () => {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { InjectionToken, Provider } from 'injection-js';
|
import { InjectionToken, type Provider } from 'injection-js';
|
||||||
import {
|
import {
|
||||||
StsConfigLoader,
|
type StsConfigLoader,
|
||||||
StsConfigStaticLoader,
|
StsConfigStaticLoader,
|
||||||
} from './config/loader/config-loader';
|
} from './config/loader/config-loader';
|
||||||
import { OpenIdConfiguration } from './config/openid-configuration';
|
import type { OpenIdConfiguration } from './config/openid-configuration';
|
||||||
|
|
||||||
export interface PassedInitialConfig {
|
export interface PassedInitialConfig {
|
||||||
config?: OpenIdConfiguration | OpenIdConfiguration[];
|
config?: OpenIdConfiguration | OpenIdConfiguration[];
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { EventTypes } from '../public-events/event-types';
|
import { EventTypes } from '../public-events/event-types';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
||||||
import { TokenValidationService } from '../validation/token-validation.service';
|
import { TokenValidationService } from '../validation/token-validation.service';
|
||||||
import { ValidationResult } from '../validation/validation-result';
|
import type { ValidationResult } from '../validation/validation-result';
|
||||||
import { AuthStateService } from './auth-state.service';
|
import { AuthStateService } from './auth-state.service';
|
||||||
|
|
||||||
describe('Auth State Service', () => {
|
describe('Auth State Service', () => {
|
||||||
@@ -27,9 +28,6 @@ describe('Auth State Service', () => {
|
|||||||
mockProvider(StoragePersistenceService),
|
mockProvider(StoragePersistenceService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
authStateService = TestBed.inject(AuthStateService);
|
authStateService = TestBed.inject(AuthStateService);
|
||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
eventsService = TestBed.inject(PublicEventsService);
|
eventsService = TestBed.inject(PublicEventsService);
|
||||||
@@ -41,12 +39,12 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('public authorize$ is observable$', () => {
|
it('public authorize$ is observable$', () => {
|
||||||
expect(authStateService.authenticated$).toEqual(jasmine.any(Observable));
|
expect(authStateService.authenticated$).toBeInstanceOf(Observable);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setAuthorizedAndFireEvent', () => {
|
describe('setAuthorizedAndFireEvent', () => {
|
||||||
it('throws correct event with single config', () => {
|
it('throws correct event with single config', () => {
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
(authStateService as any).authenticatedInternal$,
|
(authStateService as any).authenticatedInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
@@ -55,7 +53,7 @@ describe('Auth State Service', () => {
|
|||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith({
|
expect(spy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: true,
|
isAuthenticated: true,
|
||||||
allConfigsAuthenticated: [
|
allConfigsAuthenticated: [
|
||||||
{ configId: 'configId1', isAuthenticated: true },
|
{ configId: 'configId1', isAuthenticated: true },
|
||||||
@@ -64,7 +62,7 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws correct event with multiple configs', () => {
|
it('throws correct event with multiple configs', () => {
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
(authStateService as any).authenticatedInternal$,
|
(authStateService as any).authenticatedInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
@@ -74,7 +72,7 @@ describe('Auth State Service', () => {
|
|||||||
{ configId: 'configId2' },
|
{ configId: 'configId2' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith({
|
expect(spy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
allConfigsAuthenticated: [
|
allConfigsAuthenticated: [
|
||||||
{ configId: 'configId1', isAuthenticated: false },
|
{ configId: 'configId1', isAuthenticated: false },
|
||||||
@@ -86,26 +84,34 @@ describe('Auth State Service', () => {
|
|||||||
it('throws correct event with multiple configs, one is authenticated', () => {
|
it('throws correct event with multiple configs, one is authenticated', () => {
|
||||||
const allConfigs = [{ configId: 'configId1' }, { configId: 'configId2' }];
|
const allConfigs = [{ configId: 'configId1' }, { configId: 'configId2' }];
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs(allConfigs[0])
|
mockImplementationWhenArgsEqual(
|
||||||
.and.returnValue('someAccessToken')
|
vi.spyOn(storagePersistenceService, 'getAccessToken'),
|
||||||
.withArgs(allConfigs[1])
|
[allConfigs[0]!],
|
||||||
.and.returnValue('');
|
() => 'someAccessToken'
|
||||||
|
),
|
||||||
|
[allConfigs[1]!],
|
||||||
|
() => ''
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getIdToken')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs(allConfigs[0])
|
mockImplementationWhenArgsEqual(
|
||||||
.and.returnValue('someIdToken')
|
vi.spyOn(storagePersistenceService, 'getIdToken'),
|
||||||
.withArgs(allConfigs[1])
|
[allConfigs[0]!],
|
||||||
.and.returnValue('');
|
() => 'someIdToken'
|
||||||
|
),
|
||||||
|
[allConfigs[1]!],
|
||||||
|
() => ''
|
||||||
|
);
|
||||||
|
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
(authStateService as any).authenticatedInternal$,
|
(authStateService as any).authenticatedInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
|
|
||||||
authStateService.setAuthenticatedAndFireEvent(allConfigs);
|
authStateService.setAuthenticatedAndFireEvent(allConfigs);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith({
|
expect(spy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
allConfigsAuthenticated: [
|
allConfigsAuthenticated: [
|
||||||
{ configId: 'configId1', isAuthenticated: true },
|
{ configId: 'configId1', isAuthenticated: true },
|
||||||
@@ -117,17 +123,20 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('setUnauthorizedAndFireEvent', () => {
|
describe('setUnauthorizedAndFireEvent', () => {
|
||||||
it('persist AuthState In Storage', () => {
|
it('persist AuthState In Storage', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'resetAuthStateInStorage');
|
const spy = vi.spyOn(
|
||||||
|
storagePersistenceService,
|
||||||
|
'resetAuthStateInStorage'
|
||||||
|
);
|
||||||
|
|
||||||
authStateService.setUnauthenticatedAndFireEvent(
|
authStateService.setUnauthenticatedAndFireEvent(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
[{ configId: 'configId1' }]
|
[{ configId: 'configId1' }]
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
expect(spy).toHaveBeenCalledExactlyOnceWith({ configId: 'configId1' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws correct event with single config', () => {
|
it('throws correct event with single config', () => {
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
(authStateService as any).authenticatedInternal$,
|
(authStateService as any).authenticatedInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
@@ -137,7 +146,7 @@ describe('Auth State Service', () => {
|
|||||||
[{ configId: 'configId1' }]
|
[{ configId: 'configId1' }]
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith({
|
expect(spy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
allConfigsAuthenticated: [
|
allConfigsAuthenticated: [
|
||||||
{ configId: 'configId1', isAuthenticated: false },
|
{ configId: 'configId1', isAuthenticated: false },
|
||||||
@@ -146,7 +155,7 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws correct event with multiple configs', () => {
|
it('throws correct event with multiple configs', () => {
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
(authStateService as any).authenticatedInternal$,
|
(authStateService as any).authenticatedInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
@@ -156,7 +165,7 @@ describe('Auth State Service', () => {
|
|||||||
[{ configId: 'configId1' }, { configId: 'configId2' }]
|
[{ configId: 'configId1' }, { configId: 'configId2' }]
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith({
|
expect(spy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
allConfigsAuthenticated: [
|
allConfigsAuthenticated: [
|
||||||
{ configId: 'configId1', isAuthenticated: false },
|
{ configId: 'configId1', isAuthenticated: false },
|
||||||
@@ -166,19 +175,27 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws correct event with multiple configs, one is authenticated', () => {
|
it('throws correct event with multiple configs, one is authenticated', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs({ configId: 'configId1' })
|
mockImplementationWhenArgsEqual(
|
||||||
.and.returnValue('someAccessToken')
|
vi.spyOn(storagePersistenceService, 'getAccessToken'),
|
||||||
.withArgs({ configId: 'configId2' })
|
[{ configId: 'configId1' }],
|
||||||
.and.returnValue('');
|
() => 'someAccessToken'
|
||||||
|
),
|
||||||
|
[{ configId: 'configId2' }],
|
||||||
|
() => ''
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getIdToken')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs({ configId: 'configId1' })
|
mockImplementationWhenArgsEqual(
|
||||||
.and.returnValue('someIdToken')
|
vi.spyOn(storagePersistenceService, 'getIdToken'),
|
||||||
.withArgs({ configId: 'configId2' })
|
[{ configId: 'configId1' }],
|
||||||
.and.returnValue('');
|
() => 'someIdToken'
|
||||||
|
),
|
||||||
|
[{ configId: 'configId2' }],
|
||||||
|
() => ''
|
||||||
|
);
|
||||||
|
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
(authStateService as any).authenticatedInternal$,
|
(authStateService as any).authenticatedInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
@@ -188,7 +205,7 @@ describe('Auth State Service', () => {
|
|||||||
[{ configId: 'configId1' }, { configId: 'configId2' }]
|
[{ configId: 'configId1' }, { configId: 'configId2' }]
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith({
|
expect(spy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
allConfigsAuthenticated: [
|
allConfigsAuthenticated: [
|
||||||
{ configId: 'configId1', isAuthenticated: true },
|
{ configId: 'configId1', isAuthenticated: true },
|
||||||
@@ -200,24 +217,27 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('updateAndPublishAuthState', () => {
|
describe('updateAndPublishAuthState', () => {
|
||||||
it('calls eventsService', () => {
|
it('calls eventsService', () => {
|
||||||
spyOn(eventsService, 'fireEvent');
|
vi.spyOn(eventsService, 'fireEvent');
|
||||||
|
|
||||||
authStateService.updateAndPublishAuthState({
|
const arg = {
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
validationResult: {} as ValidationResult,
|
validationResult: {} as ValidationResult,
|
||||||
});
|
};
|
||||||
|
|
||||||
expect(eventsService.fireEvent).toHaveBeenCalledOnceWith(
|
authStateService.updateAndPublishAuthState(arg);
|
||||||
|
|
||||||
|
expect(eventsService.fireEvent).toHaveBeenCalledOnce();
|
||||||
|
expect(eventsService.fireEvent).toHaveBeenCalledExactlyOnceWith(
|
||||||
EventTypes.NewAuthenticationResult,
|
EventTypes.NewAuthenticationResult,
|
||||||
jasmine.any(Object)
|
arg
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setAuthorizationData', () => {
|
describe('setAuthorizationData', () => {
|
||||||
it('stores accessToken', () => {
|
it('stores accessToken', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
const authResult = {
|
const authResult = {
|
||||||
id_token: 'idtoken',
|
id_token: 'idtoken',
|
||||||
access_token: 'accesstoken',
|
access_token: 'accesstoken',
|
||||||
@@ -237,18 +257,18 @@ describe('Auth State Service', () => {
|
|||||||
[{ configId: 'configId1' }]
|
[{ configId: 'configId1' }]
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledTimes(2);
|
expect(spy).toHaveBeenCalledTimes(2);
|
||||||
expect(spy.calls.allArgs()).toEqual([
|
expect(spy).toHaveBeenCalledWith([
|
||||||
['authzData', 'accesstoken', { configId: 'configId1' }],
|
['authzData', 'accesstoken', { configId: 'configId1' }],
|
||||||
[
|
[
|
||||||
'access_token_expires_at',
|
'access_token_expires_at',
|
||||||
jasmine.any(Number),
|
expect.any(Number),
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not crash and store accessToken when authResult is null', () => {
|
it('does not crash and store accessToken when authResult is null', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
const authResult = null;
|
const authResult = null;
|
||||||
|
|
||||||
authStateService.setAuthorizationData(
|
authStateService.setAuthorizationData(
|
||||||
@@ -262,7 +282,7 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('calls setAuthenticatedAndFireEvent() method', () => {
|
it('calls setAuthenticatedAndFireEvent() method', () => {
|
||||||
const spy = spyOn(authStateService, 'setAuthenticatedAndFireEvent');
|
const spy = vi.spyOn(authStateService, 'setAuthenticatedAndFireEvent');
|
||||||
const authResult = {
|
const authResult = {
|
||||||
id_token: 'idtoken',
|
id_token: 'idtoken',
|
||||||
access_token: 'accesstoken',
|
access_token: 'accesstoken',
|
||||||
@@ -288,28 +308,29 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('getAccessToken', () => {
|
describe('getAccessToken', () => {
|
||||||
it('isAuthorized is false returns null', () => {
|
it('isAuthorized is false returns null', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue('');
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue('');
|
||||||
const result = authStateService.getAccessToken({ configId: 'configId1' });
|
const result = authStateService.getAccessToken({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBe('');
|
expect(result).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if storagePersistenceService returns something falsy but authorized', () => {
|
it('returns false if storagePersistenceService returns something falsy but authorized', () => {
|
||||||
spyOn(authStateService, 'isAuthenticated').and.returnValue(true);
|
vi.spyOn(authStateService, 'isAuthenticated').mockReturnValue(true);
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue('');
|
||||||
const result = authStateService.getAccessToken({ configId: 'configId1' });
|
const result = authStateService.getAccessToken({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBe('');
|
expect(result).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true returns decodeURIComponent(token)', () => {
|
it('isAuthorized is true returns decodeURIComponent(token)', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = authStateService.getAccessToken({ configId: 'configId1' });
|
const result = authStateService.getAccessToken({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBe(decodeURIComponent('HenloLegger'));
|
expect(result).toBe(decodeURIComponent('HenloLegger'));
|
||||||
@@ -318,12 +339,14 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('getAuthenticationResult', () => {
|
describe('getAuthenticationResult', () => {
|
||||||
it('isAuthorized is false returns null', () => {
|
it('isAuthorized is false returns null', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue('');
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue('');
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAuthenticationResult')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs({ configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'getAuthenticationResult'),
|
||||||
.and.returnValue({});
|
[{ configId: 'configId1' }],
|
||||||
|
() => ({})
|
||||||
|
);
|
||||||
|
|
||||||
const result = authStateService.getAuthenticationResult({
|
const result = authStateService.getAuthenticationResult({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -333,10 +356,13 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if storagePersistenceService returns something falsy but authorized', () => {
|
it('returns false if storagePersistenceService returns something falsy but authorized', () => {
|
||||||
spyOn(authStateService, 'isAuthenticated').and.returnValue(true);
|
vi.spyOn(authStateService, 'isAuthenticated').mockReturnValue(true);
|
||||||
spyOn(storagePersistenceService, 'getAuthenticationResult')
|
|
||||||
.withArgs({ configId: 'configId1' })
|
mockImplementationWhenArgsEqual(
|
||||||
.and.returnValue({});
|
vi.spyOn(storagePersistenceService, 'getAuthenticationResult'),
|
||||||
|
[{ configId: 'configId1' }],
|
||||||
|
() => ({})
|
||||||
|
);
|
||||||
|
|
||||||
const result = authStateService.getAuthenticationResult({
|
const result = authStateService.getAuthenticationResult({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -346,15 +372,18 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true returns object', () => {
|
it('isAuthorized is true returns object', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getAuthenticationResult')
|
|
||||||
.withArgs({ configId: 'configId1' })
|
mockImplementationWhenArgsEqual(
|
||||||
.and.returnValue({ scope: 'HenloFuriend' });
|
vi.spyOn(storagePersistenceService, 'getAuthenticationResult'),
|
||||||
|
[{ configId: 'configId1' }],
|
||||||
|
() => ({ scope: 'HenloFuriend' })
|
||||||
|
);
|
||||||
|
|
||||||
const result = authStateService.getAuthenticationResult({
|
const result = authStateService.getAuthenticationResult({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -366,18 +395,18 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('getIdToken', () => {
|
describe('getIdToken', () => {
|
||||||
it('isAuthorized is false returns null', () => {
|
it('isAuthorized is false returns null', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue('');
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue('');
|
||||||
const result = authStateService.getIdToken({ configId: 'configId1' });
|
const result = authStateService.getIdToken({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBe('');
|
expect(result).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true returns decodeURIComponent(token)', () => {
|
it('isAuthorized is true returns decodeURIComponent(token)', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
const result = authStateService.getIdToken({ configId: 'configId1' });
|
const result = authStateService.getIdToken({ configId: 'configId1' });
|
||||||
@@ -388,8 +417,8 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('getRefreshToken', () => {
|
describe('getRefreshToken', () => {
|
||||||
it('isAuthorized is false returns null', () => {
|
it('isAuthorized is false returns null', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue('');
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue('');
|
||||||
const result = authStateService.getRefreshToken({
|
const result = authStateService.getRefreshToken({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
@@ -398,13 +427,13 @@ describe('Auth State Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true returns decodeURIComponent(token)', () => {
|
it('isAuthorized is true returns decodeURIComponent(token)', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
'HenloRefreshLegger'
|
'HenloRefreshLegger'
|
||||||
);
|
);
|
||||||
const result = authStateService.getRefreshToken({
|
const result = authStateService.getRefreshToken({
|
||||||
@@ -417,105 +446,105 @@ describe('Auth State Service', () => {
|
|||||||
|
|
||||||
describe('areAuthStorageTokensValid', () => {
|
describe('areAuthStorageTokensValid', () => {
|
||||||
it('isAuthorized is false returns false', () => {
|
it('isAuthorized is false returns false', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue('');
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue('');
|
||||||
const result = authStateService.areAuthStorageTokensValid({
|
const result = authStateService.areAuthStorageTokensValid({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true and id_token is expired returns true', () => {
|
it('isAuthorized is true and id_token is expired returns true', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const result = authStateService.areAuthStorageTokensValid({
|
const result = authStateService.areAuthStorageTokensValid({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true and access_token is expired returns true', () => {
|
it('isAuthorized is true and access_token is expired returns true', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const result = authStateService.areAuthStorageTokensValid({
|
const result = authStateService.areAuthStorageTokensValid({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('isAuthorized is true and id_token is not expired returns true', () => {
|
it('isAuthorized is true and id_token is not expired returns true', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const result = authStateService.areAuthStorageTokensValid({
|
const result = authStateService.areAuthStorageTokensValid({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('authState is AuthorizedState.Authorized and id_token is not expired fires event', () => {
|
it('authState is AuthorizedState.Authorized and id_token is not expired fires event', () => {
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
'HenloLegger'
|
'HenloLegger'
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'HenloFuriend'
|
'HenloFuriend'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService as any,
|
authStateService as any,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const result = authStateService.areAuthStorageTokensValid({
|
const result = authStateService.areAuthStorageTokensValid({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -527,56 +556,65 @@ describe('Auth State Service', () => {
|
|||||||
triggerRefreshWhenIdTokenExpired: true,
|
triggerRefreshWhenIdTokenExpired: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getIdToken')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs(config)
|
vi.spyOn(storagePersistenceService, 'getIdToken'),
|
||||||
.and.returnValue('idToken');
|
[config],
|
||||||
const spy = spyOn(
|
() => 'idToken'
|
||||||
tokenValidationService,
|
);
|
||||||
'hasIdTokenExpired'
|
const spy = vi
|
||||||
).and.callFake((_a, _b) => true);
|
.spyOn(tokenValidationService, 'hasIdTokenExpired')
|
||||||
|
.mockImplementation((_a, _b) => true);
|
||||||
|
|
||||||
authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config);
|
authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('idToken', config, 30);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('idToken', config, 30);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fires event if idToken is expired', () => {
|
it('fires event if idToken is expired', () => {
|
||||||
spyOn(tokenValidationService, 'hasIdTokenExpired').and.callFake(
|
vi.spyOn(tokenValidationService, 'hasIdTokenExpired').mockImplementation(
|
||||||
(_a, _b) => true
|
(_a, _b) => true
|
||||||
);
|
);
|
||||||
|
|
||||||
const spy = spyOn(eventsService, 'fireEvent');
|
const spy = vi.spyOn(eventsService, 'fireEvent');
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
renewTimeBeforeTokenExpiresInSeconds: 30,
|
renewTimeBeforeTokenExpiresInSeconds: 30,
|
||||||
triggerRefreshWhenIdTokenExpired: true,
|
triggerRefreshWhenIdTokenExpired: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authnResult', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue('idToken');
|
['authnResult', config],
|
||||||
|
() => 'idToken'
|
||||||
|
);
|
||||||
|
|
||||||
const result =
|
const result =
|
||||||
authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config);
|
authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config);
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(spy).toHaveBeenCalledOnceWith(EventTypes.IdTokenExpired, true);
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
EventTypes.IdTokenExpired,
|
||||||
|
true
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does NOT fire event if idToken is NOT expired', () => {
|
it('does NOT fire event if idToken is NOT expired', () => {
|
||||||
spyOn(tokenValidationService, 'hasIdTokenExpired').and.callFake(
|
vi.spyOn(tokenValidationService, 'hasIdTokenExpired').mockImplementation(
|
||||||
(_a, _b) => false
|
(_a, _b) => false
|
||||||
);
|
);
|
||||||
|
|
||||||
const spy = spyOn(eventsService, 'fireEvent');
|
const spy = vi.spyOn(eventsService, 'fireEvent');
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
renewTimeBeforeTokenExpiresInSeconds: 30,
|
renewTimeBeforeTokenExpiresInSeconds: 30,
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authnResult', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue('idToken');
|
['authnResult', config],
|
||||||
|
() => 'idToken'
|
||||||
|
);
|
||||||
|
|
||||||
const result =
|
const result =
|
||||||
authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config);
|
authStateService.hasIdTokenExpiredAndRenewCheckIsEnabled(config);
|
||||||
|
|
||||||
@@ -595,41 +633,45 @@ describe('Auth State Service', () => {
|
|||||||
renewTimeBeforeTokenExpiresInSeconds: 5,
|
renewTimeBeforeTokenExpiresInSeconds: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('access_token_expires_at', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(date);
|
['access_token_expires_at', config],
|
||||||
const spy = spyOn(
|
() => date
|
||||||
tokenValidationService,
|
);
|
||||||
'validateAccessTokenNotExpired'
|
const spy = vi
|
||||||
).and.returnValue(validateAccessTokenNotExpiredResult);
|
.spyOn(tokenValidationService, 'validateAccessTokenNotExpired')
|
||||||
|
.mockReturnValue(validateAccessTokenNotExpiredResult);
|
||||||
const result =
|
const result =
|
||||||
authStateService.hasAccessTokenExpiredIfExpiryExists(config);
|
authStateService.hasAccessTokenExpiredIfExpiryExists(config);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith(date, config, 5);
|
expect(spy).toHaveBeenCalledExactlyOnceWith(date, config, 5);
|
||||||
expect(result).toEqual(expectedResult);
|
expect(result).toEqual(expectedResult);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws event when token is expired', () => {
|
it('throws event when token is expired', () => {
|
||||||
const validateAccessTokenNotExpiredResult = false;
|
const validateAccessTokenNotExpiredResult = false;
|
||||||
const expectedResult = !validateAccessTokenNotExpiredResult;
|
const expectedResult = !validateAccessTokenNotExpiredResult;
|
||||||
// spyOn(configurationProvider, 'getOpenIDConfiguration').and.returnValue({ renewTimeBeforeTokenExpiresInSeconds: 5 });
|
// vi.spyOn(configurationProvider, 'getOpenIDConfiguration').mockReturnValue({ renewTimeBeforeTokenExpiresInSeconds: 5 });
|
||||||
const date = new Date(new Date().toUTCString());
|
const date = new Date(new Date().toUTCString());
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
renewTimeBeforeTokenExpiresInSeconds: 5,
|
renewTimeBeforeTokenExpiresInSeconds: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(eventsService, 'fireEvent');
|
vi.spyOn(eventsService, 'fireEvent');
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('access_token_expires_at', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(date);
|
['access_token_expires_at', config],
|
||||||
spyOn(
|
() => date
|
||||||
|
);
|
||||||
|
|
||||||
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateAccessTokenNotExpired'
|
'validateAccessTokenNotExpired'
|
||||||
).and.returnValue(validateAccessTokenNotExpiredResult);
|
).mockReturnValue(validateAccessTokenNotExpiredResult);
|
||||||
authStateService.hasAccessTokenExpiredIfExpiryExists(config);
|
authStateService.hasAccessTokenExpiredIfExpiryExists(config);
|
||||||
expect(eventsService.fireEvent).toHaveBeenCalledOnceWith(
|
expect(eventsService.fireEvent).toHaveBeenCalledExactlyOnceWith(
|
||||||
EventTypes.TokenExpired,
|
EventTypes.TokenExpired,
|
||||||
expectedResult
|
expectedResult
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { Injectable, inject } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { BehaviorSubject, Observable, throwError } from 'rxjs';
|
import { BehaviorSubject, type Observable, throwError } from 'rxjs';
|
||||||
import { distinctUntilChanged } from 'rxjs/operators';
|
import { distinctUntilChanged } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { AuthResult } from '../flows/callback-context';
|
import type { AuthResult } from '../flows/callback-context';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { EventTypes } from '../public-events/event-types';
|
import { EventTypes } from '../public-events/event-types';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
import { TokenValidationService } from '../validation/token-validation.service';
|
import { TokenValidationService } from '../validation/token-validation.service';
|
||||||
import { AuthenticatedResult } from './auth-result';
|
import type { AuthenticatedResult } from './auth-result';
|
||||||
import { AuthStateResult } from './auth-state';
|
import type { AuthStateResult } from './auth-state';
|
||||||
|
|
||||||
const DEFAULT_AUTHRESULT = {
|
const DEFAULT_AUTHRESULT = {
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
@@ -293,7 +293,7 @@ export class AuthStateService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.checkAllConfigsIfTheyAreAuthenticated(allConfigs);
|
return this.checkallConfigsIfTheyAreAuthenticated(allConfigs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private composeUnAuthenticatedResult(
|
private composeUnAuthenticatedResult(
|
||||||
@@ -310,10 +310,10 @@ export class AuthStateService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.checkAllConfigsIfTheyAreAuthenticated(allConfigs);
|
return this.checkallConfigsIfTheyAreAuthenticated(allConfigs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkAllConfigsIfTheyAreAuthenticated(
|
private checkallConfigsIfTheyAreAuthenticated(
|
||||||
allConfigs: OpenIdConfiguration[]
|
allConfigs: OpenIdConfiguration[]
|
||||||
): AuthenticatedResult {
|
): AuthenticatedResult {
|
||||||
const allConfigsAuthenticated = allConfigs.map((config) => ({
|
const allConfigsAuthenticated = allConfigs.map((config) => ({
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { forkJoin, Observable, of, throwError } from 'rxjs';
|
import { type Observable, forkJoin, of, throwError } from 'rxjs';
|
||||||
import { catchError, map, switchMap, tap } from 'rxjs/operators';
|
import { catchError, map, switchMap, tap } from 'rxjs/operators';
|
||||||
import { AutoLoginService } from '../auto-login/auto-login.service';
|
import { AutoLoginService } from '../auto-login/auto-login.service';
|
||||||
import { CallbackService } from '../callback/callback.service';
|
import { CallbackService } from '../callback/callback.service';
|
||||||
import { PeriodicallyTokenCheckService } from '../callback/periodically-token-check.service';
|
import { PeriodicallyTokenCheckService } from '../callback/periodically-token-check.service';
|
||||||
import { RefreshSessionService } from '../callback/refresh-session.service';
|
import { RefreshSessionService } from '../callback/refresh-session.service';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CheckSessionService } from '../iframe/check-session.service';
|
import { CheckSessionService } from '../iframe/check-session.service';
|
||||||
import { SilentRenewService } from '../iframe/silent-renew.service';
|
import { SilentRenewService } from '../iframe/silent-renew.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { LoginResponse } from '../login/login-response';
|
import type { LoginResponse } from '../login/login-response';
|
||||||
import { PopUpService } from '../login/popup/popup.service';
|
import { PopUpService } from '../login/popup/popup.service';
|
||||||
import { EventTypes } from '../public-events/event-types';
|
import { EventTypes } from '../public-events/event-types';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { PASSED_CONFIG } from './auth-config';
|
import { PASSED_CONFIG } from './auth-config';
|
||||||
import { AuthModule } from './auth.module';
|
import { AuthModule } from './auth.module';
|
||||||
import { ConfigurationService } from './config/config.service';
|
import { ConfigurationService } from './config/config.service';
|
||||||
@@ -9,19 +9,20 @@ import {
|
|||||||
StsConfigLoader,
|
StsConfigLoader,
|
||||||
StsConfigStaticLoader,
|
StsConfigStaticLoader,
|
||||||
} from './config/loader/config-loader';
|
} from './config/loader/config-loader';
|
||||||
|
import { mockProvider } from './testing/mock';
|
||||||
|
|
||||||
describe('AuthModule', () => {
|
describe('AuthModule', () => {
|
||||||
describe('APP_CONFIG', () => {
|
describe('APP_CONFIG', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [AuthModule.forRoot({ config: { authority: 'something' } })],
|
imports: [AuthModule.forRoot({ config: { authority: 'something' } })],
|
||||||
providers: [mockProvider(ConfigurationService)],
|
providers: [mockProvider(ConfigurationService)],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
expect(AuthModule).toBeDefined();
|
expect(AuthModule).toBeDefined();
|
||||||
expect(AuthModule.forRoot({})).toBeDefined();
|
expect(new AuthModule()).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should provide config', () => {
|
it('should provide config', () => {
|
||||||
@@ -38,8 +39,8 @@ describe('AuthModule', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('StsConfigHttpLoader', () => {
|
describe('StsConfigHttpLoader', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
AuthModule.forRoot({
|
AuthModule.forRoot({
|
||||||
loader: {
|
loader: {
|
||||||
@@ -50,7 +51,7 @@ describe('AuthModule', () => {
|
|||||||
],
|
],
|
||||||
providers: [mockProvider(ConfigurationService)],
|
providers: [mockProvider(ConfigurationService)],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should create StsConfigStaticLoader if config is passed', () => {
|
it('should create StsConfigStaticLoader if config is passed', () => {
|
||||||
const configLoader = TestBed.inject(StsConfigLoader);
|
const configLoader = TestBed.inject(StsConfigLoader);
|
||||||
|
|||||||
@@ -1,25 +1,41 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
provideHttpClient,
|
type InjectionToken,
|
||||||
withInterceptorsFromDi,
|
Injector,
|
||||||
} from '@ngify/http';
|
ReflectiveInjector,
|
||||||
import { ModuleWithProviders, NgModule } from 'injection-js';
|
type Type,
|
||||||
import { PassedInitialConfig } from './auth-config';
|
} from 'injection-js';
|
||||||
|
import type { PassedInitialConfig } from './auth-config';
|
||||||
|
import type { Module } from './injection';
|
||||||
import { _provideAuth } from './provide-auth';
|
import { _provideAuth } from './provide-auth';
|
||||||
|
|
||||||
@NgModule({
|
export interface AuthModuleOptions {
|
||||||
declarations: [],
|
passedConfig: PassedInitialConfig;
|
||||||
exports: [],
|
parentInjector?: ReflectiveInjector;
|
||||||
imports: [CommonModule],
|
}
|
||||||
providers: [provideHttpClient(withInterceptorsFromDi())],
|
|
||||||
})
|
export class AuthModule extends Injector {
|
||||||
export class AuthModule {
|
passedConfig: PassedInitialConfig;
|
||||||
static forRoot(
|
injector: ReflectiveInjector;
|
||||||
passedConfig: PassedInitialConfig
|
parentInjector?: Injector;
|
||||||
): ModuleWithProviders<AuthModule> {
|
|
||||||
return {
|
constructor(passedConfig?: PassedInitialConfig, parentInjector?: Injector) {
|
||||||
ngModule: AuthModule,
|
super();
|
||||||
providers: [..._provideAuth(passedConfig)],
|
this.passedConfig = passedConfig ?? {};
|
||||||
};
|
this.parentInjector = parentInjector;
|
||||||
|
this.injector = ReflectiveInjector.resolveAndCreate(
|
||||||
|
[..._provideAuth(this.passedConfig)],
|
||||||
|
this.parentInjector
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static forRoot(passedConfig?: PassedInitialConfig): Module {
|
||||||
|
return (parentInjector?: Injector) =>
|
||||||
|
new AuthModule(passedConfig, parentInjector);
|
||||||
|
}
|
||||||
|
|
||||||
|
get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T): T;
|
||||||
|
get(token: any, notFoundValue?: any);
|
||||||
|
get(token: unknown, notFoundValue?: unknown): any {
|
||||||
|
return this.injector.get(token, notFoundValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, mockRouterProvider } from '@/testing';
|
||||||
import {
|
import {
|
||||||
ActivatedRouteSnapshot,
|
AbstractRouter,
|
||||||
Router,
|
type ActivatedRouteSnapshot,
|
||||||
RouterStateSnapshot,
|
type RouterStateSnapshot,
|
||||||
} from '@angular/router';
|
} from 'oidc-client-rx';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { CheckAuthService } from '../auth-state/check-auth.service';
|
import { CheckAuthService } from '../auth-state/check-auth.service';
|
||||||
import { ConfigurationService } from '../config/config.service';
|
import { ConfigurationService } from '../config/config.service';
|
||||||
import { LoginService } from '../login/login.service';
|
import { LoginService } from '../login/login.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import {
|
import {
|
||||||
AutoLoginPartialRoutesGuard,
|
AutoLoginPartialRoutesGuard,
|
||||||
autoLoginPartialRoutesGuard,
|
autoLoginPartialRoutesGuard,
|
||||||
@@ -19,11 +19,12 @@ import {
|
|||||||
} from './auto-login-partial-routes.guard';
|
} from './auto-login-partial-routes.guard';
|
||||||
import { AutoLoginService } from './auto-login.service';
|
import { AutoLoginService } from './auto-login.service';
|
||||||
|
|
||||||
describe(`AutoLoginPartialRoutesGuard`, () => {
|
describe('AutoLoginPartialRoutesGuard', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [RouterTestingModule],
|
imports: [],
|
||||||
providers: [
|
providers: [
|
||||||
|
mockRouterProvider(),
|
||||||
AutoLoginService,
|
AutoLoginService,
|
||||||
mockProvider(AuthStateService),
|
mockProvider(AuthStateService),
|
||||||
mockProvider(LoginService),
|
mockProvider(LoginService),
|
||||||
@@ -41,7 +42,7 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
let storagePersistenceService: StoragePersistenceService;
|
let storagePersistenceService: StoragePersistenceService;
|
||||||
let configurationService: ConfigurationService;
|
let configurationService: ConfigurationService;
|
||||||
let autoLoginService: AutoLoginService;
|
let autoLoginService: AutoLoginService;
|
||||||
let router: Router;
|
let router: AbstractRouter;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
authStateService = TestBed.inject(AuthStateService);
|
authStateService = TestBed.inject(AuthStateService);
|
||||||
@@ -49,15 +50,16 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
configurationService = TestBed.inject(ConfigurationService);
|
configurationService = TestBed.inject(ConfigurationService);
|
||||||
|
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
|
vi.spyOn(configurationService, 'getOpenIDConfiguration').mockReturnValue(
|
||||||
of({ configId: 'configId1' })
|
of({ configId: 'configId1' })
|
||||||
);
|
);
|
||||||
|
|
||||||
guard = TestBed.inject(AutoLoginPartialRoutesGuard);
|
guard = TestBed.inject(AutoLoginPartialRoutesGuard);
|
||||||
autoLoginService = TestBed.inject(AutoLoginService);
|
autoLoginService = TestBed.inject(AutoLoginService);
|
||||||
router = TestBed.inject(Router);
|
router = TestBed.inject(AbstractRouter);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
storagePersistenceService.clear({});
|
storagePersistenceService.clear({});
|
||||||
});
|
});
|
||||||
@@ -67,19 +69,19 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('canActivate', () => {
|
describe('canActivate', () => {
|
||||||
it('should save current route and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route and call `login` if not authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard
|
guard
|
||||||
.canActivate(
|
.canActivate(
|
||||||
@@ -87,32 +89,32 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
{ url: 'some-url1' } as RouterStateSnapshot
|
{ url: 'some-url1' } as RouterStateSnapshot
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-url1'
|
'some-url1'
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
expect(
|
expect(
|
||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).not.toHaveBeenCalled();
|
).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should save current route and call `login` if not authenticated already and add custom params', waitForAsync(() => {
|
it('should save current route and call `login` if not authenticated already and add custom params', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard
|
guard
|
||||||
.canActivate(
|
.canActivate(
|
||||||
@@ -120,11 +122,11 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
{ url: 'some-url1' } as RouterStateSnapshot
|
{ url: 'some-url1' } as RouterStateSnapshot
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-url1'
|
'some-url1'
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith(
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
{ customParams: { custom: 'param' } }
|
{ customParams: { custom: 'param' } }
|
||||||
);
|
);
|
||||||
@@ -132,21 +134,21 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).not.toHaveBeenCalled();
|
).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
|
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard
|
guard
|
||||||
.canActivate(
|
.canActivate(
|
||||||
@@ -158,25 +160,25 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
expect(loginSpy).not.toHaveBeenCalled();
|
expect(loginSpy).not.toHaveBeenCalled();
|
||||||
expect(
|
expect(
|
||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
).toHaveBeenCalledExactlyOnceWith({ configId: 'configId1' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('canActivateChild', () => {
|
describe('canActivateChild', () => {
|
||||||
it('should save current route and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route and call `login` if not authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard
|
guard
|
||||||
.canActivateChild(
|
.canActivateChild(
|
||||||
@@ -184,32 +186,32 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
{ url: 'some-url1' } as RouterStateSnapshot
|
{ url: 'some-url1' } as RouterStateSnapshot
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-url1'
|
'some-url1'
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
expect(
|
expect(
|
||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).not.toHaveBeenCalled();
|
).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should save current route and call `login` if not authenticated already with custom params', waitForAsync(() => {
|
it('should save current route and call `login` if not authenticated already with custom params', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard
|
guard
|
||||||
.canActivateChild(
|
.canActivateChild(
|
||||||
@@ -217,11 +219,11 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
{ url: 'some-url1' } as RouterStateSnapshot
|
{ url: 'some-url1' } as RouterStateSnapshot
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-url1'
|
'some-url1'
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith(
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
{ customParams: { custom: 'param' } }
|
{ customParams: { custom: 'param' } }
|
||||||
);
|
);
|
||||||
@@ -229,21 +231,21 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).not.toHaveBeenCalled();
|
).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
|
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard
|
guard
|
||||||
.canActivateChild(
|
.canActivateChild(
|
||||||
@@ -255,51 +257,53 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
expect(loginSpy).not.toHaveBeenCalled();
|
expect(loginSpy).not.toHaveBeenCalled();
|
||||||
expect(
|
expect(
|
||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
).toHaveBeenCalledExactlyOnceWith({ configId: 'configId1' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('canLoad', () => {
|
describe('canLoad', () => {
|
||||||
it('should save current route (empty) and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route (empty) and call `login` if not authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard.canLoad().subscribe(() => {
|
guard.canLoad().subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
|
configId: 'configId1',
|
||||||
|
});
|
||||||
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should save current route (with router extractedUrl) and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route (with router extractedUrl) and call `login` if not authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
spyOn(router, 'getCurrentNavigation').and.returnValue({
|
vi.spyOn(router, 'getCurrentNavigation').mockReturnValue({
|
||||||
extractedUrl: router.parseUrl(
|
extractedUrl: router.parseUrl(
|
||||||
'some-url12/with/some-param?queryParam=true'
|
'some-url12/with/some-param?queryParam=true'
|
||||||
),
|
),
|
||||||
@@ -311,37 +315,39 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
guard.canLoad().subscribe(() => {
|
guard.canLoad().subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-url12/with/some-param?queryParam=true'
|
'some-url12/with/some-param?queryParam=true'
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
|
configId: 'configId1',
|
||||||
|
});
|
||||||
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
|
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
guard.canLoad().subscribe(() => {
|
guard.canLoad().subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
|
expect(saveRedirectRouteSpy).not.toHaveBeenCalled();
|
||||||
expect(loginSpy).not.toHaveBeenCalled();
|
expect(loginSpy).not.toHaveBeenCalled();
|
||||||
expect(
|
expect(
|
||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
).toHaveBeenCalledExactlyOnceWith({ configId: 'configId1' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -352,7 +358,7 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
let storagePersistenceService: StoragePersistenceService;
|
let storagePersistenceService: StoragePersistenceService;
|
||||||
let configurationService: ConfigurationService;
|
let configurationService: ConfigurationService;
|
||||||
let autoLoginService: AutoLoginService;
|
let autoLoginService: AutoLoginService;
|
||||||
let router: Router;
|
let router: AbstractRouter;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
authStateService = TestBed.inject(AuthStateService);
|
authStateService = TestBed.inject(AuthStateService);
|
||||||
@@ -360,48 +366,52 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
configurationService = TestBed.inject(ConfigurationService);
|
configurationService = TestBed.inject(ConfigurationService);
|
||||||
|
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
|
vi.spyOn(
|
||||||
of({ configId: 'configId1' })
|
configurationService,
|
||||||
);
|
'getOpenIDConfiguration'
|
||||||
|
).mockReturnValue(of({ configId: 'configId1' }));
|
||||||
|
|
||||||
autoLoginService = TestBed.inject(AutoLoginService);
|
autoLoginService = TestBed.inject(AutoLoginService);
|
||||||
router = TestBed.inject(Router);
|
router = TestBed.inject(AbstractRouter);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
storagePersistenceService.clear({});
|
storagePersistenceService.clear({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save current route (empty) and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route (empty) and call `login` if not authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
const guard$ = TestBed.runInInjectionContext(
|
const guard$ = TestBed.runInInjectionContext(
|
||||||
autoLoginPartialRoutesGuard
|
autoLoginPartialRoutesGuard
|
||||||
);
|
);
|
||||||
|
|
||||||
guard$.subscribe(() => {
|
guard$.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
|
configId: 'configId1',
|
||||||
|
});
|
||||||
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should save current route (with router extractedUrl) and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route (with router extractedUrl) and call `login` if not authenticated already', async () => {
|
||||||
spyOn(router, 'getCurrentNavigation').and.returnValue({
|
vi.spyOn(router, 'getCurrentNavigation').mockReturnValue({
|
||||||
extractedUrl: router.parseUrl(
|
extractedUrl: router.parseUrl(
|
||||||
'some-url12/with/some-param?queryParam=true'
|
'some-url12/with/some-param?queryParam=true'
|
||||||
),
|
),
|
||||||
@@ -412,46 +422,48 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
trigger: 'imperative',
|
trigger: 'imperative',
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
const guard$ = TestBed.runInInjectionContext(
|
const guard$ = TestBed.runInInjectionContext(
|
||||||
autoLoginPartialRoutesGuard
|
autoLoginPartialRoutesGuard
|
||||||
);
|
);
|
||||||
|
|
||||||
guard$.subscribe(() => {
|
guard$.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-url12/with/some-param?queryParam=true'
|
'some-url12/with/some-param?queryParam=true'
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
|
configId: 'configId1',
|
||||||
|
});
|
||||||
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should save current route and call `login` if not authenticated already and add custom params', waitForAsync(() => {
|
it('should save current route and call `login` if not authenticated already and add custom params', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
const guard$ = TestBed.runInInjectionContext(() =>
|
const guard$ = TestBed.runInInjectionContext(() =>
|
||||||
autoLoginPartialRoutesGuard({
|
autoLoginPartialRoutesGuard({
|
||||||
@@ -460,31 +472,31 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
guard$.subscribe(() => {
|
guard$.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith(
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
{ customParams: { custom: 'param' } }
|
{ customParams: { custom: 'param' } }
|
||||||
);
|
);
|
||||||
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', waitForAsync(() => {
|
it('should call `checkSavedRedirectRouteAndNavigate` if authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
const guard$ = TestBed.runInInjectionContext(
|
const guard$ = TestBed.runInInjectionContext(
|
||||||
autoLoginPartialRoutesGuard
|
autoLoginPartialRoutesGuard
|
||||||
@@ -495,9 +507,9 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
expect(loginSpy).not.toHaveBeenCalled();
|
expect(loginSpy).not.toHaveBeenCalled();
|
||||||
expect(
|
expect(
|
||||||
checkSavedRedirectRouteAndNavigateSpy
|
checkSavedRedirectRouteAndNavigateSpy
|
||||||
).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
).toHaveBeenCalledExactlyOnceWith({ configId: 'configId1' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('autoLoginPartialRoutesGuardWithConfig', () => {
|
describe('autoLoginPartialRoutesGuardWithConfig', () => {
|
||||||
@@ -513,44 +525,48 @@ describe(`AutoLoginPartialRoutesGuard`, () => {
|
|||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
configurationService = TestBed.inject(ConfigurationService);
|
configurationService = TestBed.inject(ConfigurationService);
|
||||||
|
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.callFake(
|
vi.spyOn(
|
||||||
(configId) => of({ configId })
|
configurationService,
|
||||||
);
|
'getOpenIDConfiguration'
|
||||||
|
).mockImplementation((configId) => of({ configId }));
|
||||||
|
|
||||||
autoLoginService = TestBed.inject(AutoLoginService);
|
autoLoginService = TestBed.inject(AutoLoginService);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
storagePersistenceService.clear({});
|
storagePersistenceService.clear({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save current route (empty) and call `login` if not authenticated already', waitForAsync(() => {
|
it('should save current route (empty) and call `login` if not authenticated already', async () => {
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const checkSavedRedirectRouteAndNavigateSpy = spyOn(
|
const checkSavedRedirectRouteAndNavigateSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'checkSavedRedirectRouteAndNavigate'
|
'checkSavedRedirectRouteAndNavigate'
|
||||||
);
|
);
|
||||||
const saveRedirectRouteSpy = spyOn(
|
const saveRedirectRouteSpy = vi.spyOn(
|
||||||
autoLoginService,
|
autoLoginService,
|
||||||
'saveRedirectRoute'
|
'saveRedirectRoute'
|
||||||
);
|
);
|
||||||
const loginSpy = spyOn(loginService, 'login');
|
const loginSpy = vi.spyOn(loginService, 'login');
|
||||||
|
|
||||||
const guard$ = TestBed.runInInjectionContext(
|
const guard$ = TestBed.runInInjectionContext(
|
||||||
autoLoginPartialRoutesGuardWithConfig('configId1')
|
autoLoginPartialRoutesGuardWithConfig('configId1')
|
||||||
);
|
);
|
||||||
|
|
||||||
guard$.subscribe(() => {
|
guard$.subscribe(() => {
|
||||||
expect(saveRedirectRouteSpy).toHaveBeenCalledOnceWith(
|
expect(saveRedirectRouteSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
expect(loginSpy).toHaveBeenCalledOnceWith({ configId: 'configId1' });
|
expect(loginSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
|
configId: 'configId1',
|
||||||
|
});
|
||||||
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
expect(checkSavedRedirectRouteAndNavigateSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import {
|
import type { Observable } from 'rxjs';
|
||||||
ActivatedRouteSnapshot,
|
|
||||||
Router,
|
|
||||||
RouterStateSnapshot,
|
|
||||||
} from '@angular/router';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { AuthOptions } from '../auth-options';
|
import type { AuthOptions } from '../auth-options';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { ConfigurationService } from '../config/config.service';
|
import { ConfigurationService } from '../config/config.service';
|
||||||
|
import { injectAbstractType } from '../injection';
|
||||||
import { LoginService } from '../login/login.service';
|
import { LoginService } from '../login/login.service';
|
||||||
|
import {
|
||||||
|
AbstractRouter,
|
||||||
|
type ActivatedRouteSnapshot,
|
||||||
|
type RouterStateSnapshot,
|
||||||
|
} from '../router';
|
||||||
import { AutoLoginService } from './auto-login.service';
|
import { AutoLoginService } from './auto-login.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -22,7 +23,7 @@ export class AutoLoginPartialRoutesGuard {
|
|||||||
|
|
||||||
private readonly configurationService = inject(ConfigurationService);
|
private readonly configurationService = inject(ConfigurationService);
|
||||||
|
|
||||||
private readonly router = inject(Router);
|
private readonly router = injectAbstractType(AbstractRouter);
|
||||||
|
|
||||||
canLoad(): Observable<boolean> {
|
canLoad(): Observable<boolean> {
|
||||||
const url =
|
const url =
|
||||||
@@ -79,14 +80,14 @@ export class AutoLoginPartialRoutesGuard {
|
|||||||
|
|
||||||
export function autoLoginPartialRoutesGuard(
|
export function autoLoginPartialRoutesGuard(
|
||||||
route?: ActivatedRouteSnapshot,
|
route?: ActivatedRouteSnapshot,
|
||||||
state?: RouterStateSnapshot,
|
_state?: RouterStateSnapshot,
|
||||||
configId?: string
|
configId?: string
|
||||||
): Observable<boolean> {
|
): Observable<boolean> {
|
||||||
const configurationService = inject(ConfigurationService);
|
const configurationService = inject(ConfigurationService);
|
||||||
const authStateService = inject(AuthStateService);
|
const authStateService = inject(AuthStateService);
|
||||||
const loginService = inject(LoginService);
|
const loginService = inject(LoginService);
|
||||||
const autoLoginService = inject(AutoLoginService);
|
const autoLoginService = inject(AutoLoginService);
|
||||||
const router = inject(Router);
|
const router = injectAbstractType(AbstractRouter);
|
||||||
const authOptions: AuthOptions | undefined = route?.data
|
const authOptions: AuthOptions | undefined = route?.data
|
||||||
? { customParams: route.data }
|
? { customParams: route.data }
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { AutoLoginService } from './auto-login.service';
|
import { AutoLoginService } from './auto-login.service';
|
||||||
|
|
||||||
describe('AutoLoginService ', () => {
|
describe('AutoLoginService ', () => {
|
||||||
@@ -29,11 +30,11 @@ describe('AutoLoginService ', () => {
|
|||||||
|
|
||||||
describe('checkSavedRedirectRouteAndNavigate', () => {
|
describe('checkSavedRedirectRouteAndNavigate', () => {
|
||||||
it('if not route is saved, router and delete are not called', () => {
|
it('if not route is saved, router and delete are not called', () => {
|
||||||
const deleteSpy = spyOn(storagePersistenceService, 'remove');
|
const deleteSpy = vi.spyOn(storagePersistenceService, 'remove');
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const readSpy = spyOn(storagePersistenceService, 'read').and.returnValue(
|
const readSpy = vi
|
||||||
null
|
.spyOn(storagePersistenceService, 'read')
|
||||||
);
|
.mockReturnValue(null);
|
||||||
|
|
||||||
autoLoginService.checkSavedRedirectRouteAndNavigate({
|
autoLoginService.checkSavedRedirectRouteAndNavigate({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -41,27 +42,27 @@ describe('AutoLoginService ', () => {
|
|||||||
|
|
||||||
expect(deleteSpy).not.toHaveBeenCalled();
|
expect(deleteSpy).not.toHaveBeenCalled();
|
||||||
expect(routerSpy).not.toHaveBeenCalled();
|
expect(routerSpy).not.toHaveBeenCalled();
|
||||||
expect(readSpy).toHaveBeenCalledOnceWith('redirect', {
|
expect(readSpy).toHaveBeenCalledExactlyOnceWith('redirect', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if route is saved, router and delete are called', () => {
|
it('if route is saved, router and delete are called', () => {
|
||||||
const deleteSpy = spyOn(storagePersistenceService, 'remove');
|
const deleteSpy = vi.spyOn(storagePersistenceService, 'remove');
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const readSpy = spyOn(storagePersistenceService, 'read').and.returnValue(
|
const readSpy = vi
|
||||||
'saved-route'
|
.spyOn(storagePersistenceService, 'read')
|
||||||
);
|
.mockReturnValue('saved-route');
|
||||||
|
|
||||||
autoLoginService.checkSavedRedirectRouteAndNavigate({
|
autoLoginService.checkSavedRedirectRouteAndNavigate({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(deleteSpy).toHaveBeenCalledOnceWith('redirect', {
|
expect(deleteSpy).toHaveBeenCalledExactlyOnceWith('redirect', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
expect(routerSpy).toHaveBeenCalledOnceWith('saved-route');
|
expect(routerSpy).toHaveBeenCalledExactlyOnceWith('saved-route');
|
||||||
expect(readSpy).toHaveBeenCalledOnceWith('redirect', {
|
expect(readSpy).toHaveBeenCalledExactlyOnceWith('redirect', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -69,16 +70,20 @@ describe('AutoLoginService ', () => {
|
|||||||
|
|
||||||
describe('saveRedirectRoute', () => {
|
describe('saveRedirectRoute', () => {
|
||||||
it('calls storageService with correct params', () => {
|
it('calls storageService with correct params', () => {
|
||||||
const writeSpy = spyOn(storagePersistenceService, 'write');
|
const writeSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
autoLoginService.saveRedirectRoute(
|
autoLoginService.saveRedirectRoute(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'some-route'
|
'some-route'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith('redirect', 'some-route', {
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
'redirect',
|
||||||
});
|
'some-route',
|
||||||
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, lastValueFrom, of } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
||||||
import { UrlService } from '../utils/url/url.service';
|
import { UrlService } from '../utils/url/url.service';
|
||||||
import { CallbackService } from './callback.service';
|
import { CallbackService } from './callback.service';
|
||||||
@@ -26,9 +27,6 @@ describe('CallbackService ', () => {
|
|||||||
mockProvider(CodeFlowCallbackService),
|
mockProvider(CodeFlowCallbackService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
callbackService = TestBed.inject(CallbackService);
|
callbackService = TestBed.inject(CallbackService);
|
||||||
flowHelper = TestBed.inject(FlowHelper);
|
flowHelper = TestBed.inject(FlowHelper);
|
||||||
implicitFlowCallbackService = TestBed.inject(ImplicitFlowCallbackService);
|
implicitFlowCallbackService = TestBed.inject(ImplicitFlowCallbackService);
|
||||||
@@ -38,10 +36,13 @@ describe('CallbackService ', () => {
|
|||||||
|
|
||||||
describe('isCallback', () => {
|
describe('isCallback', () => {
|
||||||
it('calls urlService.isCallbackFromSts with passed url', () => {
|
it('calls urlService.isCallbackFromSts with passed url', () => {
|
||||||
const urlServiceSpy = spyOn(urlService, 'isCallbackFromSts');
|
const urlServiceSpy = vi.spyOn(urlService, 'isCallbackFromSts');
|
||||||
|
|
||||||
callbackService.isCallback('anyUrl');
|
callbackService.isCallback('anyUrl');
|
||||||
expect(urlServiceSpy).toHaveBeenCalledOnceWith('anyUrl', undefined);
|
expect(urlServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'anyUrl',
|
||||||
|
undefined
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,93 +53,98 @@ describe('CallbackService ', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('handleCallbackAndFireEvents', () => {
|
describe('handleCallbackAndFireEvents', () => {
|
||||||
it('calls authorizedCallbackWithCode if current flow is code flow', waitForAsync(() => {
|
it('calls authorizedCallbackWithCode if current flow is code flow', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
const authorizedCallbackWithCodeSpy = spyOn(
|
const authorizedCallbackWithCodeSpy = vi
|
||||||
codeFlowCallbackService,
|
.spyOn(codeFlowCallbackService, 'authenticatedCallbackWithCode')
|
||||||
'authenticatedCallbackWithCode'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
|
|
||||||
callbackService
|
await lastValueFrom(
|
||||||
.handleCallbackAndFireEvents('anyUrl', { configId: 'configId1' }, [
|
callbackService.handleCallbackAndFireEvents(
|
||||||
|
'anyUrl',
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
])
|
[{ configId: 'configId1' }]
|
||||||
.subscribe(() => {
|
)
|
||||||
expect(authorizedCallbackWithCodeSpy).toHaveBeenCalledOnceWith(
|
);
|
||||||
'anyUrl',
|
|
||||||
{ configId: 'configId1' },
|
|
||||||
[{ configId: 'configId1' }]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('calls authorizedImplicitFlowCallback without hash if current flow is implicit flow and callbackurl does not include a hash', waitForAsync(() => {
|
expect(authorizedCallbackWithCodeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(false);
|
'anyUrl',
|
||||||
spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').and.returnValue(true);
|
{ configId: 'configId1' },
|
||||||
const authorizedCallbackWithCodeSpy = spyOn(
|
[{ configId: 'configId1' }]
|
||||||
implicitFlowCallbackService,
|
);
|
||||||
'authenticatedImplicitFlowCallback'
|
});
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
|
|
||||||
callbackService
|
it('calls authorizedImplicitFlowCallback without hash if current flow is implicit flow and callbackurl does not include a hash', async () => {
|
||||||
.handleCallbackAndFireEvents('anyUrl', { configId: 'configId1' }, [
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(false);
|
||||||
|
vi.spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const authorizedCallbackWithCodeSpy = vi
|
||||||
|
.spyOn(implicitFlowCallbackService, 'authenticatedImplicitFlowCallback')
|
||||||
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
|
await lastValueFrom(
|
||||||
|
callbackService.handleCallbackAndFireEvents(
|
||||||
|
'anyUrl',
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
])
|
[{ configId: 'configId1' }]
|
||||||
.subscribe(() => {
|
)
|
||||||
expect(authorizedCallbackWithCodeSpy).toHaveBeenCalledWith(
|
);
|
||||||
{ configId: 'configId1' },
|
expect(authorizedCallbackWithCodeSpy).toHaveBeenCalledWith(
|
||||||
[{ configId: 'configId1' }]
|
{ configId: 'configId1' },
|
||||||
);
|
[{ configId: 'configId1' }]
|
||||||
});
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authorizedImplicitFlowCallback with hash if current flow is implicit flow and callbackurl does include a hash', waitForAsync(() => {
|
it('calls authorizedImplicitFlowCallback with hash if current flow is implicit flow and callbackurl does include a hash', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(false);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(false);
|
||||||
spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').mockReturnValue(
|
||||||
const authorizedCallbackWithCodeSpy = spyOn(
|
true
|
||||||
implicitFlowCallbackService,
|
);
|
||||||
'authenticatedImplicitFlowCallback'
|
const authorizedCallbackWithCodeSpy = vi
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.spyOn(implicitFlowCallbackService, 'authenticatedImplicitFlowCallback')
|
||||||
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
callbackService
|
await lastValueFrom(
|
||||||
.handleCallbackAndFireEvents(
|
callbackService.handleCallbackAndFireEvents(
|
||||||
'anyUrlWithAHash#some-string',
|
'anyUrlWithAHash#some-string',
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
[{ configId: 'configId1' }]
|
[{ configId: 'configId1' }]
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
);
|
||||||
expect(authorizedCallbackWithCodeSpy).toHaveBeenCalledWith(
|
|
||||||
{ configId: 'configId1' },
|
|
||||||
[{ configId: 'configId1' }],
|
|
||||||
'some-string'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('emits callbackinternal no matter which flow it is', waitForAsync(() => {
|
expect(authorizedCallbackWithCodeSpy).toHaveBeenCalledWith(
|
||||||
const callbackSpy = spyOn(
|
{ configId: 'configId1' },
|
||||||
|
[{ configId: 'configId1' }],
|
||||||
|
'some-string'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('emits callbackinternal no matter which flow it is', async () => {
|
||||||
|
const callbackSpy = vi.spyOn(
|
||||||
(callbackService as any).stsCallbackInternal$,
|
(callbackService as any).stsCallbackInternal$,
|
||||||
'next'
|
'next'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
const authenticatedCallbackWithCodeSpy = spyOn(
|
const authenticatedCallbackWithCodeSpy = vi
|
||||||
codeFlowCallbackService,
|
.spyOn(codeFlowCallbackService, 'authenticatedCallbackWithCode')
|
||||||
'authenticatedCallbackWithCode'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
|
|
||||||
callbackService
|
await lastValueFrom(
|
||||||
.handleCallbackAndFireEvents('anyUrl', { configId: 'configId1' }, [
|
callbackService.handleCallbackAndFireEvents(
|
||||||
|
'anyUrl',
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
])
|
[{ configId: 'configId1' }]
|
||||||
.subscribe(() => {
|
)
|
||||||
expect(authenticatedCallbackWithCodeSpy).toHaveBeenCalledOnceWith(
|
);
|
||||||
'anyUrl',
|
|
||||||
{ configId: 'configId1' },
|
expect(authenticatedCallbackWithCodeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
[{ configId: 'configId1' }]
|
'anyUrl',
|
||||||
);
|
{ configId: 'configId1' },
|
||||||
expect(callbackSpy).toHaveBeenCalled();
|
[{ configId: 'configId1' }]
|
||||||
});
|
);
|
||||||
}));
|
expect(callbackSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
||||||
import { UrlService } from '../utils/url/url.service';
|
import { UrlService } from '../utils/url/url.service';
|
||||||
import { CodeFlowCallbackService } from './code-flow-callback.service';
|
import { CodeFlowCallbackService } from './code-flow-callback.service';
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, mockRouterProvider } from '@/testing';
|
||||||
import { Router } from '@angular/router';
|
import { AbstractRouter } from 'oidc-client-rx';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { CodeFlowCallbackService } from './code-flow-callback.service';
|
import { CodeFlowCallbackService } from './code-flow-callback.service';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
|
|
||||||
@@ -14,26 +14,24 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
let intervalService: IntervalService;
|
let intervalService: IntervalService;
|
||||||
let flowsService: FlowsService;
|
let flowsService: FlowsService;
|
||||||
let flowsDataService: FlowsDataService;
|
let flowsDataService: FlowsDataService;
|
||||||
let router: Router;
|
let router: AbstractRouter;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [RouterTestingModule],
|
imports: [],
|
||||||
providers: [
|
providers: [
|
||||||
|
mockRouterProvider(),
|
||||||
CodeFlowCallbackService,
|
CodeFlowCallbackService,
|
||||||
mockProvider(FlowsService),
|
mockProvider(FlowsService),
|
||||||
mockProvider(FlowsDataService),
|
mockProvider(FlowsDataService),
|
||||||
mockProvider(IntervalService),
|
mockProvider(IntervalService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
codeFlowCallbackService = TestBed.inject(CodeFlowCallbackService);
|
codeFlowCallbackService = TestBed.inject(CodeFlowCallbackService);
|
||||||
intervalService = TestBed.inject(IntervalService);
|
intervalService = TestBed.inject(IntervalService);
|
||||||
flowsDataService = TestBed.inject(FlowsDataService);
|
flowsDataService = TestBed.inject(FlowsDataService);
|
||||||
flowsService = TestBed.inject(FlowsService);
|
flowsService = TestBed.inject(FlowsService);
|
||||||
router = TestBed.inject(Router);
|
router = TestBed.inject(AbstractRouter);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
@@ -42,11 +40,10 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
|
|
||||||
describe('authenticatedCallbackWithCode', () => {
|
describe('authenticatedCallbackWithCode', () => {
|
||||||
it('calls flowsService.processCodeFlowCallback with correct url', () => {
|
it('calls flowsService.processCodeFlowCallback with correct url', () => {
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processCodeFlowCallback')
|
||||||
'processCodeFlowCallback'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
//spyOn(configurationProvider, 'getOpenIDConfiguration').mockReturnValue({ triggerAuthorizationResultEvent: true });
|
||||||
//spyOn(configurationProvider, 'getOpenIDConfiguration').and.returnValue({ triggerAuthorizationResultEvent: true });
|
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -58,10 +55,12 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
config,
|
config,
|
||||||
[config]
|
[config]
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('some-url1', config, [config]);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('some-url1', config, [
|
||||||
|
config,
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does only call resetCodeFlowInProgress if triggerAuthorizationResultEvent is true and isRenewProcess is true', waitForAsync(() => {
|
it('does only call resetCodeFlowInProgress if triggerAuthorizationResultEvent is true and isRenewProcess is true', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -73,12 +72,14 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
validationResult: null,
|
validationResult: null,
|
||||||
existingIdToken: '',
|
existingIdToken: '',
|
||||||
};
|
};
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processCodeFlowCallback')
|
||||||
'processCodeFlowCallback'
|
.mockReturnValue(of(callbackContext));
|
||||||
).and.returnValue(of(callbackContext));
|
const flowsDataSpy = vi.spyOn(
|
||||||
const flowsDataSpy = spyOn(flowsDataService, 'resetCodeFlowInProgress');
|
flowsDataService,
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
'resetCodeFlowInProgress'
|
||||||
|
);
|
||||||
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
triggerAuthorizationResultEvent: true,
|
triggerAuthorizationResultEvent: true,
|
||||||
@@ -87,13 +88,15 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
codeFlowCallbackService
|
codeFlowCallbackService
|
||||||
.authenticatedCallbackWithCode('some-url2', config, [config])
|
.authenticatedCallbackWithCode('some-url2', config, [config])
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith('some-url2', config, [config]);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('some-url2', config, [
|
||||||
|
config,
|
||||||
|
]);
|
||||||
expect(routerSpy).not.toHaveBeenCalled();
|
expect(routerSpy).not.toHaveBeenCalled();
|
||||||
expect(flowsDataSpy).toHaveBeenCalled();
|
expect(flowsDataSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls router and resetCodeFlowInProgress if triggerAuthorizationResultEvent is false and isRenewProcess is false', waitForAsync(() => {
|
it('calls router and resetCodeFlowInProgress if triggerAuthorizationResultEvent is false and isRenewProcess is false', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -105,12 +108,14 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
validationResult: null,
|
validationResult: null,
|
||||||
existingIdToken: '',
|
existingIdToken: '',
|
||||||
};
|
};
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processCodeFlowCallback')
|
||||||
'processCodeFlowCallback'
|
.mockReturnValue(of(callbackContext));
|
||||||
).and.returnValue(of(callbackContext));
|
const flowsDataSpy = vi.spyOn(
|
||||||
const flowsDataSpy = spyOn(flowsDataService, 'resetCodeFlowInProgress');
|
flowsDataService,
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
'resetCodeFlowInProgress'
|
||||||
|
);
|
||||||
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
triggerAuthorizationResultEvent: false,
|
triggerAuthorizationResultEvent: false,
|
||||||
@@ -120,25 +125,27 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
codeFlowCallbackService
|
codeFlowCallbackService
|
||||||
.authenticatedCallbackWithCode('some-url3', config, [config])
|
.authenticatedCallbackWithCode('some-url3', config, [config])
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith('some-url3', config, [config]);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('some-url3', config, [
|
||||||
expect(routerSpy).toHaveBeenCalledOnceWith('postLoginRoute');
|
config,
|
||||||
|
]);
|
||||||
|
expect(routerSpy).toHaveBeenCalledExactlyOnceWith('postLoginRoute');
|
||||||
expect(flowsDataSpy).toHaveBeenCalled();
|
expect(flowsDataSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('resetSilentRenewRunning, resetCodeFlowInProgress and stopPeriodicallTokenCheck in case of error', waitForAsync(() => {
|
it('resetSilentRenewRunning, resetCodeFlowInProgress and stopPeriodicallTokenCheck in case of error', async () => {
|
||||||
spyOn(flowsService, 'processCodeFlowCallback').and.returnValue(
|
vi.spyOn(flowsService, 'processCodeFlowCallback').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
const resetCodeFlowInProgressSpy = spyOn(
|
const resetCodeFlowInProgressSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetCodeFlowInProgress'
|
'resetCodeFlowInProgress'
|
||||||
);
|
);
|
||||||
const stopPeriodicallTokenCheckSpy = spyOn(
|
const stopPeriodicallTokenCheckSpy = vi.spyOn(
|
||||||
intervalService,
|
intervalService,
|
||||||
'stopPeriodicTokenCheck'
|
'stopPeriodicTokenCheck'
|
||||||
);
|
);
|
||||||
@@ -159,23 +166,23 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`navigates to unauthorizedRoute in case of error and in case of error and
|
it(`navigates to unauthorizedRoute in case of error and in case of error and
|
||||||
triggerAuthorizationResultEvent is false`, waitForAsync(() => {
|
triggerAuthorizationResultEvent is false`, async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(flowsService, 'processCodeFlowCallback').and.returnValue(
|
vi.spyOn(flowsService, 'processCodeFlowCallback').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
const stopPeriodicallTokenCheckSpy = spyOn(
|
const stopPeriodicallTokenCheckSpy = vi.spyOn(
|
||||||
intervalService,
|
intervalService,
|
||||||
'stopPeriodicTokenCheck'
|
'stopPeriodicTokenCheck'
|
||||||
);
|
);
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -190,9 +197,11 @@ describe('CodeFlowCallbackService ', () => {
|
|||||||
expect(resetSilentRenewRunningSpy).toHaveBeenCalled();
|
expect(resetSilentRenewRunningSpy).toHaveBeenCalled();
|
||||||
expect(stopPeriodicallTokenCheckSpy).toHaveBeenCalled();
|
expect(stopPeriodicallTokenCheckSpy).toHaveBeenCalled();
|
||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
expect(routerSpy).toHaveBeenCalledOnceWith('unauthorizedRoute');
|
expect(routerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'unauthorizedRoute'
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Injectable, inject } from 'injection-js';
|
||||||
|
import { type Observable, throwError } from 'rxjs';
|
||||||
import { catchError, tap } from 'rxjs/operators';
|
import { catchError, tap } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, mockRouterProvider } from '@/testing';
|
||||||
import { Router } from '@angular/router';
|
import { AbstractRouter } from 'oidc-client-rx';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { ImplicitFlowCallbackService } from './implicit-flow-callback.service';
|
import { ImplicitFlowCallbackService } from './implicit-flow-callback.service';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
|
|
||||||
@@ -14,25 +14,23 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
let intervalService: IntervalService;
|
let intervalService: IntervalService;
|
||||||
let flowsService: FlowsService;
|
let flowsService: FlowsService;
|
||||||
let flowsDataService: FlowsDataService;
|
let flowsDataService: FlowsDataService;
|
||||||
let router: Router;
|
let router: AbstractRouter;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [RouterTestingModule],
|
imports: [],
|
||||||
providers: [
|
providers: [
|
||||||
|
mockRouterProvider(),
|
||||||
mockProvider(FlowsService),
|
mockProvider(FlowsService),
|
||||||
mockProvider(FlowsDataService),
|
mockProvider(FlowsDataService),
|
||||||
mockProvider(IntervalService),
|
mockProvider(IntervalService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
implicitFlowCallbackService = TestBed.inject(ImplicitFlowCallbackService);
|
implicitFlowCallbackService = TestBed.inject(ImplicitFlowCallbackService);
|
||||||
intervalService = TestBed.inject(IntervalService);
|
intervalService = TestBed.inject(IntervalService);
|
||||||
flowsDataService = TestBed.inject(FlowsDataService);
|
flowsDataService = TestBed.inject(FlowsDataService);
|
||||||
flowsService = TestBed.inject(FlowsService);
|
flowsService = TestBed.inject(FlowsService);
|
||||||
router = TestBed.inject(Router);
|
router = TestBed.inject(AbstractRouter);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
@@ -41,10 +39,9 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
|
|
||||||
describe('authorizedImplicitFlowCallback', () => {
|
describe('authorizedImplicitFlowCallback', () => {
|
||||||
it('calls flowsService.processImplicitFlowCallback with hash if given', () => {
|
it('calls flowsService.processImplicitFlowCallback with hash if given', () => {
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processImplicitFlowCallback')
|
||||||
'processImplicitFlowCallback'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
triggerAuthorizationResultEvent: true,
|
triggerAuthorizationResultEvent: true,
|
||||||
@@ -56,10 +53,14 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
'some-hash'
|
'some-hash'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith(config, [config], 'some-hash');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
config,
|
||||||
|
[config],
|
||||||
|
'some-hash'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does nothing if triggerAuthorizationResultEvent is true and isRenewProcess is true', waitForAsync(() => {
|
it('does nothing if triggerAuthorizationResultEvent is true and isRenewProcess is true', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -71,11 +72,10 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
validationResult: null,
|
validationResult: null,
|
||||||
existingIdToken: '',
|
existingIdToken: '',
|
||||||
};
|
};
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processImplicitFlowCallback')
|
||||||
'processImplicitFlowCallback'
|
.mockReturnValue(of(callbackContext));
|
||||||
).and.returnValue(of(callbackContext));
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
triggerAuthorizationResultEvent: true,
|
triggerAuthorizationResultEvent: true,
|
||||||
@@ -84,12 +84,16 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
implicitFlowCallbackService
|
implicitFlowCallbackService
|
||||||
.authenticatedImplicitFlowCallback(config, [config], 'some-hash')
|
.authenticatedImplicitFlowCallback(config, [config], 'some-hash')
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith(config, [config], 'some-hash');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
config,
|
||||||
|
[config],
|
||||||
|
'some-hash'
|
||||||
|
);
|
||||||
expect(routerSpy).not.toHaveBeenCalled();
|
expect(routerSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls router if triggerAuthorizationResultEvent is false and isRenewProcess is false', waitForAsync(() => {
|
it('calls router if triggerAuthorizationResultEvent is false and isRenewProcess is false', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -101,11 +105,10 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
validationResult: null,
|
validationResult: null,
|
||||||
existingIdToken: '',
|
existingIdToken: '',
|
||||||
};
|
};
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processImplicitFlowCallback')
|
||||||
'processImplicitFlowCallback'
|
.mockReturnValue(of(callbackContext));
|
||||||
).and.returnValue(of(callbackContext));
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
triggerAuthorizationResultEvent: false,
|
triggerAuthorizationResultEvent: false,
|
||||||
@@ -115,20 +118,24 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
implicitFlowCallbackService
|
implicitFlowCallbackService
|
||||||
.authenticatedImplicitFlowCallback(config, [config], 'some-hash')
|
.authenticatedImplicitFlowCallback(config, [config], 'some-hash')
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith(config, [config], 'some-hash');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
expect(routerSpy).toHaveBeenCalledOnceWith('postLoginRoute');
|
config,
|
||||||
|
[config],
|
||||||
|
'some-hash'
|
||||||
|
);
|
||||||
|
expect(routerSpy).toHaveBeenCalledExactlyOnceWith('postLoginRoute');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('resetSilentRenewRunning and stopPeriodicallyTokenCheck in case of error', waitForAsync(() => {
|
it('resetSilentRenewRunning and stopPeriodicallyTokenCheck in case of error', async () => {
|
||||||
spyOn(flowsService, 'processImplicitFlowCallback').and.returnValue(
|
vi.spyOn(flowsService, 'processImplicitFlowCallback').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
const stopPeriodicallyTokenCheckSpy = spyOn(
|
const stopPeriodicallyTokenCheckSpy = vi.spyOn(
|
||||||
intervalService,
|
intervalService,
|
||||||
'stopPeriodicTokenCheck'
|
'stopPeriodicTokenCheck'
|
||||||
);
|
);
|
||||||
@@ -147,23 +154,23 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`navigates to unauthorizedRoute in case of error and in case of error and
|
it(`navigates to unauthorizedRoute in case of error and in case of error and
|
||||||
triggerAuthorizationResultEvent is false`, waitForAsync(() => {
|
triggerAuthorizationResultEvent is false`, async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(flowsService, 'processImplicitFlowCallback').and.returnValue(
|
vi.spyOn(flowsService, 'processImplicitFlowCallback').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
const stopPeriodicallTokenCheckSpy = spyOn(
|
const stopPeriodicallTokenCheckSpy = vi.spyOn(
|
||||||
intervalService,
|
intervalService,
|
||||||
'stopPeriodicTokenCheck'
|
'stopPeriodicTokenCheck'
|
||||||
);
|
);
|
||||||
const routerSpy = spyOn(router, 'navigateByUrl');
|
const routerSpy = vi.spyOn(router, 'navigateByUrl');
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
triggerAuthorizationResultEvent: false,
|
triggerAuthorizationResultEvent: false,
|
||||||
@@ -177,9 +184,11 @@ describe('ImplicitFlowCallbackService ', () => {
|
|||||||
expect(resetSilentRenewRunningSpy).toHaveBeenCalled();
|
expect(resetSilentRenewRunningSpy).toHaveBeenCalled();
|
||||||
expect(stopPeriodicallTokenCheckSpy).toHaveBeenCalled();
|
expect(stopPeriodicallTokenCheckSpy).toHaveBeenCalled();
|
||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
expect(routerSpy).toHaveBeenCalledOnceWith('unauthorizedRoute');
|
expect(routerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'unauthorizedRoute'
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Injectable, inject } from 'injection-js';
|
||||||
|
import { type Observable, throwError } from 'rxjs';
|
||||||
import { catchError, tap } from 'rxjs/operators';
|
import { catchError, tap } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { TestBed, fakeAsync, tick } from '@/testing';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
|
|
||||||
describe('IntervalService', () => {
|
describe('IntervalService', () => {
|
||||||
@@ -31,7 +32,7 @@ describe('IntervalService', () => {
|
|||||||
describe('stopPeriodicTokenCheck', () => {
|
describe('stopPeriodicTokenCheck', () => {
|
||||||
it('calls unsubscribe and sets to null', () => {
|
it('calls unsubscribe and sets to null', () => {
|
||||||
intervalService.runTokenValidationRunning = new Subscription();
|
intervalService.runTokenValidationRunning = new Subscription();
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
intervalService.runTokenValidationRunning,
|
intervalService.runTokenValidationRunning,
|
||||||
'unsubscribe'
|
'unsubscribe'
|
||||||
);
|
);
|
||||||
@@ -44,7 +45,7 @@ describe('IntervalService', () => {
|
|||||||
|
|
||||||
it('does nothing if `runTokenValidationRunning` is null', () => {
|
it('does nothing if `runTokenValidationRunning` is null', () => {
|
||||||
intervalService.runTokenValidationRunning = new Subscription();
|
intervalService.runTokenValidationRunning = new Subscription();
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
intervalService.runTokenValidationRunning,
|
intervalService.runTokenValidationRunning,
|
||||||
'unsubscribe'
|
'unsubscribe'
|
||||||
);
|
);
|
||||||
@@ -57,7 +58,7 @@ describe('IntervalService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('startPeriodicTokenCheck', () => {
|
describe('startPeriodicTokenCheck', () => {
|
||||||
it('starts check after correct milliseconds', fakeAsync(() => {
|
it('starts check after correct milliseconds', async () => {
|
||||||
const periodicCheck = intervalService.startPeriodicTokenCheck(0.5);
|
const periodicCheck = intervalService.startPeriodicTokenCheck(0.5);
|
||||||
const spy = jasmine.createSpy();
|
const spy = jasmine.createSpy();
|
||||||
const sub = periodicCheck.subscribe(() => {
|
const sub = periodicCheck.subscribe(() => {
|
||||||
@@ -71,6 +72,6 @@ describe('IntervalService', () => {
|
|||||||
expect(spy).toHaveBeenCalledTimes(2);
|
expect(spy).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
sub.unsubscribe();
|
sub.unsubscribe();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { Injectable, NgZone, inject } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { type Observable, type Subscription, interval } from 'rxjs';
|
||||||
import { DOCUMENT } from '../../dom';
|
import { DOCUMENT } from '../dom';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class IntervalService {
|
export class IntervalService {
|
||||||
private readonly zone = inject(NgZone);
|
|
||||||
|
|
||||||
private readonly document = inject(DOCUMENT);
|
private readonly document = inject(DOCUMENT);
|
||||||
|
|
||||||
runTokenValidationRunning: Subscription | null = null;
|
runTokenValidationRunning: Subscription | null = null;
|
||||||
@@ -24,19 +22,6 @@ export class IntervalService {
|
|||||||
startPeriodicTokenCheck(repeatAfterSeconds: number): Observable<unknown> {
|
startPeriodicTokenCheck(repeatAfterSeconds: number): Observable<unknown> {
|
||||||
const millisecondsDelayBetweenTokenCheck = repeatAfterSeconds * 1000;
|
const millisecondsDelayBetweenTokenCheck = repeatAfterSeconds * 1000;
|
||||||
|
|
||||||
return new Observable((subscriber) => {
|
return interval(millisecondsDelayBetweenTokenCheck);
|
||||||
let intervalId: number | undefined;
|
|
||||||
|
|
||||||
this.zone.runOutsideAngular(() => {
|
|
||||||
intervalId = this.document?.defaultView?.setInterval(
|
|
||||||
() => this.zone.run(() => subscriber.next()),
|
|
||||||
millisecondsDelayBetweenTokenCheck
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (): void => {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { lastValueFrom, of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { ConfigurationService } from '../config/config.service';
|
import { ConfigurationService } from '../config/config.service';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
||||||
@@ -12,6 +12,7 @@ import { LoggerService } from '../logging/logger.service';
|
|||||||
import { EventTypes } from '../public-events/event-types';
|
import { EventTypes } from '../public-events/event-types';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { UserService } from '../user-data/user.service';
|
import { UserService } from '../user-data/user.service';
|
||||||
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
@@ -49,9 +50,6 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
mockProvider(ConfigurationService),
|
mockProvider(ConfigurationService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
periodicallyTokenCheckService = TestBed.inject(
|
periodicallyTokenCheckService = TestBed.inject(
|
||||||
PeriodicallyTokenCheckService
|
PeriodicallyTokenCheckService
|
||||||
);
|
);
|
||||||
@@ -68,11 +66,14 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
publicEventsService = TestBed.inject(PublicEventsService);
|
publicEventsService = TestBed.inject(PublicEventsService);
|
||||||
configurationService = TestBed.inject(ConfigurationService);
|
configurationService = TestBed.inject(ConfigurationService);
|
||||||
|
|
||||||
spyOn(intervalService, 'startPeriodicTokenCheck').and.returnValue(of(null));
|
vi.spyOn(intervalService, 'startPeriodicTokenCheck').mockReturnValue(
|
||||||
|
of(null)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// biome-ignore lint/correctness/noUndeclaredVariables: <explanation>
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
if (!!intervalService.runTokenValidationRunning?.unsubscribe) {
|
if (intervalService.runTokenValidationRunning?.unsubscribe) {
|
||||||
intervalService.runTokenValidationRunning.unsubscribe();
|
intervalService.runTokenValidationRunning.unsubscribe();
|
||||||
intervalService.runTokenValidationRunning = null;
|
intervalService.runTokenValidationRunning = null;
|
||||||
}
|
}
|
||||||
@@ -83,164 +84,172 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('startTokenValidationPeriodically', () => {
|
describe('startTokenValidationPeriodically', () => {
|
||||||
it('returns if no config has silentrenew enabled', waitForAsync(() => {
|
it('returns if no config has silentrenew enabled', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{ silentRenew: false, configId: 'configId1' },
|
{ silentRenew: false, configId: 'configId1' },
|
||||||
{ silentRenew: false, configId: 'configId2' },
|
{ silentRenew: false, configId: 'configId2' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const result =
|
const result = await lastValueFrom(
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns if runTokenValidationRunning', waitForAsync(() => {
|
it('returns if runTokenValidationRunning', async () => {
|
||||||
const configs = [{ silentRenew: true, configId: 'configId1' }];
|
const configs = [{ silentRenew: true, configId: 'configId1' }];
|
||||||
|
|
||||||
spyOn(intervalService, 'isTokenValidationRunning').and.returnValue(true);
|
vi.spyOn(intervalService, 'isTokenValidationRunning').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
const result =
|
const result = await lastValueFrom(
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('interval calls resetSilentRenewRunning when current flow is CodeFlowWithRefreshTokens', fakeAsync(() => {
|
it('interval calls resetSilentRenewRunning when current flow is CodeFlowWithRefreshTokens', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
periodicallyTokenCheckService as any,
|
periodicallyTokenCheckService as any,
|
||||||
'shouldStartPeriodicallyCheckForConfig'
|
'shouldStartPeriodicallyCheckForConfig'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const isCurrentFlowCodeFlowWithRefreshTokensSpy = spyOn(
|
const isCurrentFlowCodeFlowWithRefreshTokensSpy = vi
|
||||||
flowHelper,
|
.spyOn(flowHelper, 'isCurrentFlowCodeFlowWithRefreshTokens')
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
.mockReturnValue(true);
|
||||||
).and.returnValue(true);
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionRefreshTokenService,
|
refreshSessionRefreshTokenService,
|
||||||
'refreshSessionWithRefreshTokens'
|
'refreshSessionWithRefreshTokens'
|
||||||
).and.returnValue(of({} as CallbackContext));
|
).mockReturnValue(of({} as CallbackContext));
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
|
vi.spyOn(configurationService, 'getOpenIDConfiguration').mockReturnValue(
|
||||||
of(configs[0])
|
of(configs[0]!)
|
||||||
);
|
);
|
||||||
|
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
);
|
||||||
|
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
|
||||||
intervalService.runTokenValidationRunning?.unsubscribe();
|
intervalService.runTokenValidationRunning?.unsubscribe();
|
||||||
intervalService.runTokenValidationRunning = null;
|
intervalService.runTokenValidationRunning = null;
|
||||||
expect(isCurrentFlowCodeFlowWithRefreshTokensSpy).toHaveBeenCalled();
|
expect(isCurrentFlowCodeFlowWithRefreshTokensSpy).toHaveBeenCalled();
|
||||||
expect(resetSilentRenewRunningSpy).toHaveBeenCalled();
|
expect(resetSilentRenewRunningSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('interval calls resetSilentRenewRunning in case of error when current flow is CodeFlowWithRefreshTokens', fakeAsync(() => {
|
it('interval calls resetSilentRenewRunning in case of error when current flow is CodeFlowWithRefreshTokens', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
periodicallyTokenCheckService as any,
|
periodicallyTokenCheckService as any,
|
||||||
'shouldStartPeriodicallyCheckForConfig'
|
'shouldStartPeriodicallyCheckForConfig'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const resetSilentRenewRunning = spyOn(
|
const resetSilentRenewRunning = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionRefreshTokenService,
|
refreshSessionRefreshTokenService,
|
||||||
'refreshSessionWithRefreshTokens'
|
'refreshSessionWithRefreshTokens'
|
||||||
).and.returnValue(throwError(() => new Error('error')));
|
).mockReturnValue(throwError(() => new Error('error')));
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
|
vi.spyOn(configurationService, 'getOpenIDConfiguration').mockReturnValue(
|
||||||
of(configs[0])
|
of(configs[0]!)
|
||||||
);
|
);
|
||||||
|
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
);
|
||||||
|
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically
|
periodicallyTokenCheckService.startTokenValidationPeriodically
|
||||||
).toThrowError();
|
).toThrowError();
|
||||||
expect(resetSilentRenewRunning).toHaveBeenCalledOnceWith(configs[0]);
|
expect(resetSilentRenewRunning).toHaveBeenCalledExactlyOnceWith(
|
||||||
}));
|
configs[0]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('interval throws silent renew failed event with data in case of an error', fakeAsync(() => {
|
it('interval throws silent renew failed event with data in case of an error', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
periodicallyTokenCheckService as any,
|
periodicallyTokenCheckService as any,
|
||||||
'shouldStartPeriodicallyCheckForConfig'
|
'shouldStartPeriodicallyCheckForConfig'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(flowsDataService, 'resetSilentRenewRunning');
|
vi.spyOn(flowsDataService, 'resetSilentRenewRunning');
|
||||||
const publicEventsServiceSpy = spyOn(publicEventsService, 'fireEvent');
|
const publicEventsServiceSpy = vi.spyOn(publicEventsService, 'fireEvent');
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionRefreshTokenService,
|
refreshSessionRefreshTokenService,
|
||||||
'refreshSessionWithRefreshTokens'
|
'refreshSessionWithRefreshTokens'
|
||||||
).and.returnValue(throwError(() => new Error('error')));
|
).mockReturnValue(throwError(() => new Error('error')));
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
|
vi.spyOn(configurationService, 'getOpenIDConfiguration').mockReturnValue(
|
||||||
of(configs[0])
|
of(configs[0]!)
|
||||||
);
|
);
|
||||||
|
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
);
|
||||||
|
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically
|
periodicallyTokenCheckService.startTokenValidationPeriodically
|
||||||
).toThrowError();
|
).toThrowError();
|
||||||
expect(publicEventsServiceSpy.calls.allArgs()).toEqual([
|
expect(publicEventsServiceSpy).toBeCalledWith([
|
||||||
[EventTypes.SilentRenewStarted],
|
[EventTypes.SilentRenewStarted],
|
||||||
[EventTypes.SilentRenewFailed, new Error('error')],
|
[EventTypes.SilentRenewFailed, new Error('error')],
|
||||||
]);
|
]);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls resetAuthorizationData and returns if no silent renew is configured', fakeAsync(() => {
|
it('calls resetAuthorizationData and returns if no silent renew is configured', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
{ silentRenew: true, configId: 'configId1', tokenRefreshInSeconds: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
periodicallyTokenCheckService as any,
|
periodicallyTokenCheckService as any,
|
||||||
'shouldStartPeriodicallyCheckForConfig'
|
'shouldStartPeriodicallyCheckForConfig'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
const configSpy = spyOn(configurationService, 'getOpenIDConfiguration');
|
const configSpy = vi.spyOn(
|
||||||
|
configurationService,
|
||||||
|
'getOpenIDConfiguration'
|
||||||
|
);
|
||||||
const configWithoutSilentRenew = {
|
const configWithoutSilentRenew = {
|
||||||
silentRenew: false,
|
silentRenew: false,
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -248,68 +257,70 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
};
|
};
|
||||||
const configWithoutSilentRenew$ = of(configWithoutSilentRenew);
|
const configWithoutSilentRenew$ = of(configWithoutSilentRenew);
|
||||||
|
|
||||||
configSpy.and.returnValue(configWithoutSilentRenew$);
|
configSpy.mockReturnValue(configWithoutSilentRenew$);
|
||||||
|
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
|
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
intervalService.runTokenValidationRunning?.unsubscribe();
|
intervalService.runTokenValidationRunning?.unsubscribe();
|
||||||
intervalService.runTokenValidationRunning = null;
|
intervalService.runTokenValidationRunning = null;
|
||||||
|
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledOnceWith(
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configWithoutSilentRenew,
|
configWithoutSilentRenew,
|
||||||
configs
|
configs
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls refreshSessionWithRefreshTokens if current flow is Code flow with refresh tokens', fakeAsync(() => {
|
it('calls refreshSessionWithRefreshTokens if current flow is Code flow with refresh tokens', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
periodicallyTokenCheckService as any,
|
periodicallyTokenCheckService as any,
|
||||||
'shouldStartPeriodicallyCheckForConfig'
|
'shouldStartPeriodicallyCheckForConfig'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue({});
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue({});
|
||||||
const configs = [
|
const configs = [
|
||||||
{ configId: 'configId1', silentRenew: true, tokenRefreshInSeconds: 1 },
|
{ configId: 'configId1', silentRenew: true, tokenRefreshInSeconds: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(configurationService, 'getOpenIDConfiguration').and.returnValue(
|
vi.spyOn(configurationService, 'getOpenIDConfiguration').mockReturnValue(
|
||||||
of(configs[0] as OpenIdConfiguration)
|
of(configs[0] as OpenIdConfiguration)
|
||||||
);
|
);
|
||||||
const refreshSessionWithRefreshTokensSpy = spyOn(
|
const refreshSessionWithRefreshTokensSpy = vi
|
||||||
refreshSessionRefreshTokenService,
|
.spyOn(
|
||||||
'refreshSessionWithRefreshTokens'
|
refreshSessionRefreshTokenService,
|
||||||
).and.returnValue(of({} as CallbackContext));
|
'refreshSessionWithRefreshTokens'
|
||||||
|
)
|
||||||
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
periodicallyTokenCheckService.startTokenValidationPeriodically(
|
||||||
configs,
|
configs,
|
||||||
configs[0]
|
configs[0]!
|
||||||
);
|
);
|
||||||
|
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
|
||||||
intervalService.runTokenValidationRunning?.unsubscribe();
|
intervalService.runTokenValidationRunning?.unsubscribe();
|
||||||
intervalService.runTokenValidationRunning = null;
|
intervalService.runTokenValidationRunning = null;
|
||||||
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('shouldStartPeriodicallyCheckForConfig', () => {
|
describe('shouldStartPeriodicallyCheckForConfig', () => {
|
||||||
it('returns false when there is no IdToken', () => {
|
it('returns false when there is no IdToken', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(
|
||||||
'some-userdata'
|
'some-userdata'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -317,13 +328,13 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false when silent renew is running', () => {
|
it('returns false when silent renew is running', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('idToken');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('idToken');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(
|
||||||
'some-userdata'
|
'some-userdata'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -331,14 +342,14 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false when code flow is in progress', () => {
|
it('returns false when code flow is in progress', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('idToken');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('idToken');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(flowsDataService, 'isCodeFlowInProgress').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isCodeFlowInProgress').mockReturnValue(true);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(
|
||||||
'some-userdata'
|
'some-userdata'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -346,87 +357,87 @@ describe('PeriodicallyTokenCheckService', () => {
|
|||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false when there is no userdata from the store', () => {
|
it('returns false when there is no userdata from the store', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('idToken');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('idToken');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(null);
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(null);
|
||||||
|
|
||||||
const result = (
|
const result = (
|
||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true when there is userDataFromStore, silentrenew is not running and there is an idtoken', () => {
|
it('returns true when there is userDataFromStore, silentrenew is not running and there is an idtoken', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('idToken');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('idToken');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(
|
||||||
'some-userdata'
|
'some-userdata'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
const result = (
|
const result = (
|
||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if tokens are not expired', () => {
|
it('returns false if tokens are not expired', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('idToken');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('idToken');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(
|
||||||
'some-userdata'
|
'some-userdata'
|
||||||
);
|
);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
|
|
||||||
const result = (
|
const result = (
|
||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if tokens are expired', () => {
|
it('returns true if tokens are expired', () => {
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('idToken');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('idToken');
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(userService, 'getUserDataFromStore').and.returnValue(
|
vi.spyOn(userService, 'getUserDataFromStore').mockReturnValue(
|
||||||
'some-userdata'
|
'some-userdata'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
'hasIdTokenExpiredAndRenewCheckIsEnabled'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'hasAccessTokenExpiredIfExpiryExists'
|
'hasAccessTokenExpiredIfExpiryExists'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
const result = (
|
const result = (
|
||||||
periodicallyTokenCheckService as any
|
periodicallyTokenCheckService as any
|
||||||
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
).shouldStartPeriodicallyCheckForConfig({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { forkJoin, Observable, of, throwError } from 'rxjs';
|
import { type Observable, forkJoin, of, throwError } from 'rxjs';
|
||||||
import { catchError, switchMap } from 'rxjs/operators';
|
import { catchError, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { ConfigurationService } from '../config/config.service';
|
import { ConfigurationService } from '../config/config.service';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
||||||
@@ -52,7 +52,7 @@ export class PeriodicallyTokenCheckService {
|
|||||||
startTokenValidationPeriodically(
|
startTokenValidationPeriodically(
|
||||||
allConfigs: OpenIdConfiguration[],
|
allConfigs: OpenIdConfiguration[],
|
||||||
currentConfig: OpenIdConfiguration
|
currentConfig: OpenIdConfiguration
|
||||||
): void {
|
): Observable<void> {
|
||||||
const configsWithSilentRenewEnabled =
|
const configsWithSilentRenewEnabled =
|
||||||
this.getConfigsWithSilentRenewEnabled(allConfigs);
|
this.getConfigsWithSilentRenewEnabled(allConfigs);
|
||||||
|
|
||||||
@@ -75,46 +75,51 @@ export class PeriodicallyTokenCheckService {
|
|||||||
[id: string]: Observable<boolean | CallbackContext | null>;
|
[id: string]: Observable<boolean | CallbackContext | null>;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
configsWithSilentRenewEnabled.forEach((config) => {
|
for (const config of configsWithSilentRenewEnabled) {
|
||||||
const identifier = config.configId as string;
|
const identifier = config.configId as string;
|
||||||
const refreshEvent = this.getRefreshEvent(config, allConfigs);
|
const refreshEvent = this.getRefreshEvent(config, allConfigs);
|
||||||
|
|
||||||
objectWithConfigIdsAndRefreshEvent[identifier] = refreshEvent;
|
objectWithConfigIdsAndRefreshEvent[identifier] = refreshEvent;
|
||||||
});
|
}
|
||||||
|
|
||||||
return forkJoin(objectWithConfigIdsAndRefreshEvent);
|
return forkJoin(objectWithConfigIdsAndRefreshEvent);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.intervalService.runTokenValidationRunning = periodicallyCheck$
|
const o$ = periodicallyCheck$.pipe(
|
||||||
.pipe(catchError((error) => throwError(() => new Error(error))))
|
catchError((error) => throwError(() => new Error(error))),
|
||||||
.subscribe({
|
map((objectWithConfigIds) => {
|
||||||
next: (objectWithConfigIds) => {
|
for (const [configId, _] of Object.entries(objectWithConfigIds)) {
|
||||||
for (const [configId, _] of Object.entries(objectWithConfigIds)) {
|
this.configurationService
|
||||||
this.configurationService
|
.getOpenIDConfiguration(configId)
|
||||||
.getOpenIDConfiguration(configId)
|
.subscribe((config) => {
|
||||||
.subscribe((config) => {
|
this.loggerService.logDebug(
|
||||||
this.loggerService.logDebug(
|
config,
|
||||||
config,
|
'silent renew, periodic check finished!'
|
||||||
'silent renew, periodic check finished!'
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.flowHelper.isCurrentFlowCodeFlowWithRefreshTokens(config)
|
this.flowHelper.isCurrentFlowCodeFlowWithRefreshTokens(config)
|
||||||
) {
|
) {
|
||||||
this.flowsDataService.resetSilentRenewRunning(config);
|
this.flowsDataService.resetSilentRenewRunning(config);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
error: (error) => {
|
catchError((error) => {
|
||||||
this.loggerService.logError(
|
this.loggerService.logError(
|
||||||
currentConfig,
|
currentConfig,
|
||||||
'silent renew failed!',
|
'silent renew failed!',
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
},
|
return throwError(() => error);
|
||||||
});
|
}),
|
||||||
|
shareReplay(1)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.intervalService.runTokenValidationRunning = o$.subscribe();
|
||||||
|
|
||||||
|
return o$;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRefreshEvent(
|
private getRefreshEvent(
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { IntervalService } from './interval.service';
|
import { IntervalService } from './interval.service';
|
||||||
import { RefreshSessionRefreshTokenService } from './refresh-session-refresh-token.service';
|
import { RefreshSessionRefreshTokenService } from './refresh-session-refresh-token.service';
|
||||||
|
|
||||||
@@ -25,9 +26,6 @@ describe('RefreshSessionRefreshTokenService', () => {
|
|||||||
mockProvider(IntervalService),
|
mockProvider(IntervalService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
flowsService = TestBed.inject(FlowsService);
|
flowsService = TestBed.inject(FlowsService);
|
||||||
refreshSessionRefreshTokenService = TestBed.inject(
|
refreshSessionRefreshTokenService = TestBed.inject(
|
||||||
RefreshSessionRefreshTokenService
|
RefreshSessionRefreshTokenService
|
||||||
@@ -41,10 +39,10 @@ describe('RefreshSessionRefreshTokenService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('refreshSessionWithRefreshTokens', () => {
|
describe('refreshSessionWithRefreshTokens', () => {
|
||||||
it('calls flowsService.processRefreshToken()', waitForAsync(() => {
|
it('calls flowsService.processRefreshToken()', async () => {
|
||||||
const spy = spyOn(flowsService, 'processRefreshToken').and.returnValue(
|
const spy = vi
|
||||||
of({} as CallbackContext)
|
.spyOn(flowsService, 'processRefreshToken')
|
||||||
);
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
refreshSessionRefreshTokenService
|
refreshSessionRefreshTokenService
|
||||||
.refreshSessionWithRefreshTokens({ configId: 'configId1' }, [
|
.refreshSessionWithRefreshTokens({ configId: 'configId1' }, [
|
||||||
@@ -53,13 +51,13 @@ describe('RefreshSessionRefreshTokenService', () => {
|
|||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('resetAuthorizationData in case of error', waitForAsync(() => {
|
it('resetAuthorizationData in case of error', async () => {
|
||||||
spyOn(flowsService, 'processRefreshToken').and.returnValue(
|
vi.spyOn(flowsService, 'processRefreshToken').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
@@ -74,13 +72,13 @@ describe('RefreshSessionRefreshTokenService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('finalize with stopPeriodicTokenCheck in case of error', fakeAsync(() => {
|
it('finalize with stopPeriodicTokenCheck in case of error', async () => {
|
||||||
spyOn(flowsService, 'processRefreshToken').and.returnValue(
|
vi.spyOn(flowsService, 'processRefreshToken').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const stopPeriodicallyTokenCheckSpy = spyOn(
|
const stopPeriodicallyTokenCheckSpy = vi.spyOn(
|
||||||
intervalService,
|
intervalService,
|
||||||
'stopPeriodicTokenCheck'
|
'stopPeriodicTokenCheck'
|
||||||
);
|
);
|
||||||
@@ -94,8 +92,8 @@ describe('RefreshSessionRefreshTokenService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
tick();
|
await vi.advanceTimersByTimeAsync(0);
|
||||||
expect(stopPeriodicallyTokenCheckSpy).toHaveBeenCalled();
|
expect(stopPeriodicallyTokenCheckSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { type Observable, throwError } from 'rxjs';
|
||||||
import { catchError, finalize } from 'rxjs/operators';
|
import { catchError, finalize } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed, fakeAsync, tick } from '@/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { delay } from 'rxjs/operators';
|
import { delay } from 'rxjs/operators';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { AuthWellKnownService } from '../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../config/auth-well-known/auth-well-known.service';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
||||||
import { SilentRenewService } from '../iframe/silent-renew.service';
|
import { SilentRenewService } from '../iframe/silent-renew.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { LoginResponse } from '../login/login-response';
|
import type { LoginResponse } from '../login/login-response';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { UserService } from '../user-data/user.service';
|
import { UserService } from '../user-data/user.service';
|
||||||
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
||||||
import { RefreshSessionRefreshTokenService } from './refresh-session-refresh-token.service';
|
import { RefreshSessionRefreshTokenService } from './refresh-session-refresh-token.service';
|
||||||
@@ -70,19 +71,19 @@ describe('RefreshSessionService ', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('userForceRefreshSession', () => {
|
describe('userForceRefreshSession', () => {
|
||||||
it('should persist params refresh when extra custom params given and useRefreshToken is true', waitForAsync(() => {
|
it('should persist params refresh when extra custom params given and useRefreshToken is true', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const writeSpy = spyOn(storagePersistenceService, 'write');
|
const writeSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -94,26 +95,26 @@ describe('RefreshSessionService ', () => {
|
|||||||
const extraCustomParams = { extra: 'custom' };
|
const extraCustomParams = { extra: 'custom' };
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.userForceRefreshSession(allConfigs[0], allConfigs, extraCustomParams)
|
.userForceRefreshSession(allConfigs[0]!, allConfigs, extraCustomParams)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith(
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'storageCustomParamsRefresh',
|
'storageCustomParamsRefresh',
|
||||||
extraCustomParams,
|
extraCustomParams,
|
||||||
allConfigs[0]
|
allConfigs[0]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should persist storageCustomParamsAuthRequest when extra custom params given and useRefreshToken is false', waitForAsync(() => {
|
it('should persist storageCustomParamsAuthRequest when extra custom params given and useRefreshToken is false', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
@@ -123,31 +124,31 @@ describe('RefreshSessionService ', () => {
|
|||||||
silentRenewTimeoutInSeconds: 10,
|
silentRenewTimeoutInSeconds: 10,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const writeSpy = spyOn(storagePersistenceService, 'write');
|
const writeSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const extraCustomParams = { extra: 'custom' };
|
const extraCustomParams = { extra: 'custom' };
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.userForceRefreshSession(allConfigs[0], allConfigs, extraCustomParams)
|
.userForceRefreshSession(allConfigs[0]!, allConfigs, extraCustomParams)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith(
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'storageCustomParamsAuthRequest',
|
'storageCustomParamsAuthRequest',
|
||||||
extraCustomParams,
|
extraCustomParams,
|
||||||
allConfigs[0]
|
allConfigs[0]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should NOT persist customparams if no customparams are given', waitForAsync(() => {
|
it('should NOT persist customparams if no customparams are given', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
@@ -157,20 +158,20 @@ describe('RefreshSessionService ', () => {
|
|||||||
silentRenewTimeoutInSeconds: 10,
|
silentRenewTimeoutInSeconds: 10,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const writeSpy = spyOn(storagePersistenceService, 'write');
|
const writeSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.userForceRefreshSession(allConfigs[0], allConfigs)
|
.userForceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(writeSpy).not.toHaveBeenCalled();
|
expect(writeSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call resetSilentRenewRunning in case of an error', waitForAsync(() => {
|
it('should call resetSilentRenewRunning in case of an error', async () => {
|
||||||
spyOn(refreshSessionService, 'forceRefreshSession').and.returnValue(
|
vi.spyOn(refreshSessionService, 'forceRefreshSession').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
spyOn(flowsDataService, 'resetSilentRenewRunning');
|
vi.spyOn(flowsDataService, 'resetSilentRenewRunning');
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -180,7 +181,7 @@ describe('RefreshSessionService ', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.userForceRefreshSession(allConfigs[0], allConfigs)
|
.userForceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
fail('It should not return any result.');
|
fail('It should not return any result.');
|
||||||
@@ -191,16 +192,16 @@ describe('RefreshSessionService ', () => {
|
|||||||
complete: () => {
|
complete: () => {
|
||||||
expect(
|
expect(
|
||||||
flowsDataService.resetSilentRenewRunning
|
flowsDataService.resetSilentRenewRunning
|
||||||
).toHaveBeenCalledOnceWith(allConfigs[0]);
|
).toHaveBeenCalledExactlyOnceWith(allConfigs[0]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should call resetSilentRenewRunning in case of no error', waitForAsync(() => {
|
it('should call resetSilentRenewRunning in case of no error', async () => {
|
||||||
spyOn(refreshSessionService, 'forceRefreshSession').and.returnValue(
|
vi.spyOn(refreshSessionService, 'forceRefreshSession').mockReturnValue(
|
||||||
of({} as LoginResponse)
|
of({} as LoginResponse)
|
||||||
);
|
);
|
||||||
spyOn(flowsDataService, 'resetSilentRenewRunning');
|
vi.spyOn(flowsDataService, 'resetSilentRenewRunning');
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -210,7 +211,7 @@ describe('RefreshSessionService ', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.userForceRefreshSession(allConfigs[0], allConfigs)
|
.userForceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
fail('It should not return any error.');
|
fail('It should not return any error.');
|
||||||
@@ -218,27 +219,29 @@ describe('RefreshSessionService ', () => {
|
|||||||
complete: () => {
|
complete: () => {
|
||||||
expect(
|
expect(
|
||||||
flowsDataService.resetSilentRenewRunning
|
flowsDataService.resetSilentRenewRunning
|
||||||
).toHaveBeenCalledOnceWith(allConfigs[0]);
|
).toHaveBeenCalledExactlyOnceWith(allConfigs[0]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('forceRefreshSession', () => {
|
describe('forceRefreshSession', () => {
|
||||||
it('only calls start refresh session and returns idToken and accessToken if auth is true', waitForAsync(() => {
|
it('only calls start refresh session and returns idToken and accessToken if auth is true', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('id-token');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('id-token');
|
||||||
spyOn(authStateService, 'getAccessToken').and.returnValue('access-token');
|
vi.spyOn(authStateService, 'getAccessToken').mockReturnValue(
|
||||||
|
'access-token'
|
||||||
|
);
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -247,23 +250,23 @@ describe('RefreshSessionService ', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result.idToken).toEqual('id-token');
|
expect(result.idToken).toEqual('id-token');
|
||||||
expect(result.accessToken).toEqual('access-token');
|
expect(result.accessToken).toEqual('access-token');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('only calls start refresh session and returns null if auth is false', waitForAsync(() => {
|
it('only calls start refresh session and returns null if auth is false', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
@@ -274,7 +277,7 @@ describe('RefreshSessionService ', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
@@ -285,24 +288,24 @@ describe('RefreshSessionService ', () => {
|
|||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls start refresh session and waits for completed, returns idtoken and accesstoken if auth is true', waitForAsync(() => {
|
it('calls start refresh session and waits for completed, returns idtoken and accesstoken if auth is true', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
spyOnProperty(
|
vi.spyOnProperty(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'refreshSessionWithIFrameCompleted$'
|
'refreshSessionWithIFrameCompleted$'
|
||||||
).and.returnValue(
|
).mockReturnValue(
|
||||||
of({
|
of({
|
||||||
authResult: {
|
authResult: {
|
||||||
id_token: 'some-id_token',
|
id_token: 'some-id_token',
|
||||||
@@ -318,29 +321,29 @@ describe('RefreshSessionService ', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result.idToken).toBeDefined();
|
expect(result.idToken).toBeDefined();
|
||||||
expect(result.accessToken).toBeDefined();
|
expect(result.accessToken).toBeDefined();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls start refresh session and waits for completed, returns LoginResponse if auth is false', waitForAsync(() => {
|
it('calls start refresh session and waits for completed, returns LoginResponse if auth is false', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
spyOnProperty(
|
vi.spyOnProperty(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'refreshSessionWithIFrameCompleted$'
|
'refreshSessionWithIFrameCompleted$'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -349,7 +352,7 @@ describe('RefreshSessionService ', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
@@ -360,23 +363,23 @@ describe('RefreshSessionService ', () => {
|
|||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('occurs timeout error and retry mechanism exhausted max retry count throws error', fakeAsync(() => {
|
it('occurs timeout error and retry mechanism exhausted max retry count throws error', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOnProperty(
|
vi.spyOnProperty(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'refreshSessionWithIFrameCompleted$'
|
'refreshSessionWithIFrameCompleted$'
|
||||||
).and.returnValue(of(null).pipe(delay(11000)));
|
).mockReturnValue(of(null).pipe(delay(11000)));
|
||||||
|
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
@@ -386,14 +389,14 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
const expectedInvokeCount = MAX_RETRY_ATTEMPTS;
|
const expectedInvokeCount = MAX_RETRY_ATTEMPTS;
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
fail('It should not return any result.');
|
fail('It should not return any result.');
|
||||||
@@ -407,9 +410,9 @@ describe('RefreshSessionService ', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tick(allConfigs[0].silentRenewTimeoutInSeconds * 10000);
|
tick(allConfigs[0].silentRenewTimeoutInSeconds * 10000);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('occurs unknown error throws it to subscriber', fakeAsync(() => {
|
it('occurs unknown error throws it to subscriber', async () => {
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -419,29 +422,29 @@ describe('RefreshSessionService ', () => {
|
|||||||
|
|
||||||
const expectedErrorMessage = 'Test error message';
|
const expectedErrorMessage = 'Test error message';
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOnProperty(
|
vi.spyOnProperty(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'refreshSessionWithIFrameCompleted$'
|
'refreshSessionWithIFrameCompleted$'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(throwError(() => new Error(expectedErrorMessage)));
|
).mockReturnValue(throwError(() => new Error(expectedErrorMessage)));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
fail('It should not return any result.');
|
fail('It should not return any result.');
|
||||||
@@ -452,10 +455,10 @@ describe('RefreshSessionService ', () => {
|
|||||||
expect(resetSilentRenewRunningSpy).not.toHaveBeenCalled();
|
expect(resetSilentRenewRunningSpy).not.toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
describe('NOT isCurrentFlowCodeFlowWithRefreshTokens', () => {
|
describe('NOT isCurrentFlowCodeFlowWithRefreshTokens', () => {
|
||||||
it('does return null when not authenticated', waitForAsync(() => {
|
it('does return null when not authenticated', async () => {
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -463,24 +466,24 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(
|
vi.spyOn(authStateService, 'areAuthStorageTokensValid').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
spyOnProperty(
|
vi.spyOnProperty(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'refreshSessionWithIFrameCompleted$'
|
'refreshSessionWithIFrameCompleted$'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
@@ -491,9 +494,9 @@ describe('RefreshSessionService ', () => {
|
|||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('return value only returns once', waitForAsync(() => {
|
it('return value only returns once', async () => {
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -501,18 +504,18 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionService as any,
|
refreshSessionService as any,
|
||||||
'startRefreshSession'
|
'startRefreshSession'
|
||||||
).and.returnValue(of(null));
|
).mockReturnValue(of(null));
|
||||||
spyOnProperty(
|
vi.spyOnProperty(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'refreshSessionWithIFrameCompleted$'
|
'refreshSessionWithIFrameCompleted$'
|
||||||
).and.returnValue(
|
).mockReturnValue(
|
||||||
of({
|
of({
|
||||||
authResult: {
|
authResult: {
|
||||||
id_token: 'some-id_token',
|
id_token: 'some-id_token',
|
||||||
@@ -520,13 +523,12 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
} as CallbackContext)
|
} as CallbackContext)
|
||||||
);
|
);
|
||||||
const spyInsideMap = spyOn(
|
const spyInsideMap = vi
|
||||||
authStateService,
|
.spyOn(authStateService, 'areAuthStorageTokensValid')
|
||||||
'areAuthStorageTokensValid'
|
.mockReturnValue(true);
|
||||||
).and.returnValue(true);
|
|
||||||
|
|
||||||
refreshSessionService
|
refreshSessionService
|
||||||
.forceRefreshSession(allConfigs[0], allConfigs)
|
.forceRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
idToken: 'some-id_token',
|
idToken: 'some-id_token',
|
||||||
@@ -537,33 +539,33 @@ describe('RefreshSessionService ', () => {
|
|||||||
});
|
});
|
||||||
expect(spyInsideMap).toHaveBeenCalledTimes(1);
|
expect(spyInsideMap).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('startRefreshSession', () => {
|
describe('startRefreshSession', () => {
|
||||||
it('returns null if no auth well known endpoint defined', waitForAsync(() => {
|
it('returns null if no auth well known endpoint defined', async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
|
|
||||||
(refreshSessionService as any)
|
(refreshSessionService as any)
|
||||||
.startRefreshSession()
|
.startRefreshSession()
|
||||||
.subscribe((result: any) => {
|
.subscribe((result: any) => {
|
||||||
expect(result).toBe(null);
|
expect(result).toBe(null);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns null if silent renew Is running', waitForAsync(() => {
|
it('returns null if silent renew Is running', async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
|
|
||||||
(refreshSessionService as any)
|
(refreshSessionService as any)
|
||||||
.startRefreshSession()
|
.startRefreshSession()
|
||||||
.subscribe((result: any) => {
|
.subscribe((result: any) => {
|
||||||
expect(result).toBe(null);
|
expect(result).toBe(null);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls `setSilentRenewRunning` when should be executed', waitForAsync(() => {
|
it('calls `setSilentRenewRunning` when should be executed', async () => {
|
||||||
const setSilentRenewRunningSpy = spyOn(
|
const setSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'setSilentRenewRunning'
|
'setSilentRenewRunning'
|
||||||
);
|
);
|
||||||
@@ -574,30 +576,30 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
refreshSessionRefreshTokenService,
|
refreshSessionRefreshTokenService,
|
||||||
'refreshSessionWithRefreshTokens'
|
'refreshSessionWithRefreshTokens'
|
||||||
).and.returnValue(of({} as CallbackContext));
|
).mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
(refreshSessionService as any)
|
(refreshSessionService as any)
|
||||||
.startRefreshSession(allConfigs[0], allConfigs)
|
.startRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(setSilentRenewRunningSpy).toHaveBeenCalled();
|
expect(setSilentRenewRunningSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls refreshSessionWithRefreshTokens when current flow is codeflow with refresh tokens', waitForAsync(() => {
|
it('calls refreshSessionWithRefreshTokens when current flow is codeflow with refresh tokens', async () => {
|
||||||
spyOn(flowsDataService, 'setSilentRenewRunning');
|
vi.spyOn(flowsDataService, 'setSilentRenewRunning');
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -605,30 +607,32 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const refreshSessionWithRefreshTokensSpy = spyOn(
|
const refreshSessionWithRefreshTokensSpy = vi
|
||||||
refreshSessionRefreshTokenService,
|
.spyOn(
|
||||||
'refreshSessionWithRefreshTokens'
|
refreshSessionRefreshTokenService,
|
||||||
).and.returnValue(of({} as CallbackContext));
|
'refreshSessionWithRefreshTokens'
|
||||||
|
)
|
||||||
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
(refreshSessionService as any)
|
(refreshSessionService as any)
|
||||||
.startRefreshSession(allConfigs[0], allConfigs)
|
.startRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls refreshSessionWithIframe when current flow is NOT codeflow with refresh tokens', waitForAsync(() => {
|
it('calls refreshSessionWithIframe when current flow is NOT codeflow with refresh tokens', async () => {
|
||||||
spyOn(flowsDataService, 'setSilentRenewRunning');
|
vi.spyOn(flowsDataService, 'setSilentRenewRunning');
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -636,32 +640,33 @@ describe('RefreshSessionService ', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowHelper,
|
flowHelper,
|
||||||
'isCurrentFlowCodeFlowWithRefreshTokens'
|
'isCurrentFlowCodeFlowWithRefreshTokens'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const refreshSessionWithRefreshTokensSpy = spyOn(
|
const refreshSessionWithRefreshTokensSpy = vi
|
||||||
refreshSessionRefreshTokenService,
|
.spyOn(
|
||||||
'refreshSessionWithRefreshTokens'
|
refreshSessionRefreshTokenService,
|
||||||
).and.returnValue(of({} as CallbackContext));
|
'refreshSessionWithRefreshTokens'
|
||||||
|
)
|
||||||
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
|
|
||||||
const refreshSessionWithIframeSpy = spyOn(
|
const refreshSessionWithIframeSpy = vi
|
||||||
refreshSessionIframeService,
|
.spyOn(refreshSessionIframeService, 'refreshSessionWithIframe')
|
||||||
'refreshSessionWithIframe'
|
.mockReturnValue(of(false));
|
||||||
).and.returnValue(of(false));
|
|
||||||
|
|
||||||
(refreshSessionService as any)
|
(refreshSessionService as any)
|
||||||
.startRefreshSession(allConfigs[0], allConfigs)
|
.startRefreshSession(allConfigs[0]!, allConfigs)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(refreshSessionWithRefreshTokensSpy).not.toHaveBeenCalled();
|
expect(refreshSessionWithRefreshTokensSpy).not.toHaveBeenCalled();
|
||||||
expect(refreshSessionWithIframeSpy).toHaveBeenCalled();
|
expect(refreshSessionWithIframeSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import {
|
import {
|
||||||
|
type Observable,
|
||||||
|
TimeoutError,
|
||||||
forkJoin,
|
forkJoin,
|
||||||
Observable,
|
|
||||||
of,
|
of,
|
||||||
throwError,
|
throwError,
|
||||||
TimeoutError,
|
|
||||||
timer,
|
timer,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import {
|
import {
|
||||||
@@ -18,13 +18,13 @@ import {
|
|||||||
} from 'rxjs/operators';
|
} from 'rxjs/operators';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { AuthWellKnownService } from '../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../config/auth-well-known/auth-well-known.service';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
import { RefreshSessionIframeService } from '../iframe/refresh-session-iframe.service';
|
||||||
import { SilentRenewService } from '../iframe/silent-renew.service';
|
import { SilentRenewService } from '../iframe/silent-renew.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { LoginResponse } from '../login/login-response';
|
import type { LoginResponse } from '../login/login-response';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
import { UserService } from '../user-data/user.service';
|
import { UserService } from '../user-data/user.service';
|
||||||
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { createRetriableStream } from '../../../test/create-retriable-stream.helper';
|
|
||||||
import { DataService } from '../../api/data.service';
|
import { DataService } from '../../api/data.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { createRetriableStream } from '../../testing/create-retriable-stream.helper';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { AuthWellKnownDataService } from './auth-well-known-data.service';
|
import { AuthWellKnownDataService } from './auth-well-known-data.service';
|
||||||
import { AuthWellKnownEndpoints } from './auth-well-known-endpoints';
|
import type { AuthWellKnownEndpoints } from './auth-well-known-endpoints';
|
||||||
|
|
||||||
const DUMMY_WELL_KNOWN_DOCUMENT = {
|
const DUMMY_WELL_KNOWN_DOCUMENT = {
|
||||||
issuer: 'https://identity-server.test/realms/main',
|
issuer: 'https://identity-server.test/realms/main',
|
||||||
@@ -51,56 +52,65 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getWellKnownDocument', () => {
|
describe('getWellKnownDocument', () => {
|
||||||
it('should add suffix if it does not exist on current URL', waitForAsync(() => {
|
it('should add suffix if it does not exist on current URL', async () => {
|
||||||
const dataServiceSpy = spyOn(dataService, 'get').and.returnValue(
|
const dataServiceSpy = vi
|
||||||
of(null)
|
.spyOn(dataService, 'get')
|
||||||
);
|
.mockReturnValue(of(null));
|
||||||
const urlWithoutSuffix = 'myUrl';
|
const urlWithoutSuffix = 'myUrl';
|
||||||
const urlWithSuffix = `${urlWithoutSuffix}/.well-known/openid-configuration`;
|
const urlWithSuffix = `${urlWithoutSuffix}/.well-known/openid-configuration`;
|
||||||
|
|
||||||
(service as any)
|
(service as any)
|
||||||
.getWellKnownDocument(urlWithoutSuffix, { configId: 'configId1' })
|
.getWellKnownDocument(urlWithoutSuffix, { configId: 'configId1' })
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(dataServiceSpy).toHaveBeenCalledOnceWith(urlWithSuffix, {
|
expect(dataServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
urlWithSuffix,
|
||||||
});
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add suffix if it does exist on current url', waitForAsync(() => {
|
it('should not add suffix if it does exist on current url', async () => {
|
||||||
const dataServiceSpy = spyOn(dataService, 'get').and.returnValue(
|
const dataServiceSpy = vi
|
||||||
of(null)
|
.spyOn(dataService, 'get')
|
||||||
);
|
.mockReturnValue(of(null));
|
||||||
const urlWithSuffix = `myUrl/.well-known/openid-configuration`;
|
const urlWithSuffix = `myUrl/.well-known/openid-configuration`;
|
||||||
|
|
||||||
(service as any)
|
(service as any)
|
||||||
.getWellKnownDocument(urlWithSuffix, { configId: 'configId1' })
|
.getWellKnownDocument(urlWithSuffix, { configId: 'configId1' })
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(dataServiceSpy).toHaveBeenCalledOnceWith(urlWithSuffix, {
|
expect(dataServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
urlWithSuffix,
|
||||||
});
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add suffix if it does exist in the middle of current url', waitForAsync(() => {
|
it('should not add suffix if it does exist in the middle of current url', async () => {
|
||||||
const dataServiceSpy = spyOn(dataService, 'get').and.returnValue(
|
const dataServiceSpy = vi
|
||||||
of(null)
|
.spyOn(dataService, 'get')
|
||||||
);
|
.mockReturnValue(of(null));
|
||||||
const urlWithSuffix = `myUrl/.well-known/openid-configuration/and/some/more/stuff`;
|
const urlWithSuffix = `myUrl/.well-known/openid-configuration/and/some/more/stuff`;
|
||||||
|
|
||||||
(service as any)
|
(service as any)
|
||||||
.getWellKnownDocument(urlWithSuffix, { configId: 'configId1' })
|
.getWellKnownDocument(urlWithSuffix, { configId: 'configId1' })
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(dataServiceSpy).toHaveBeenCalledOnceWith(urlWithSuffix, {
|
expect(dataServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
urlWithSuffix,
|
||||||
});
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should use the custom suffix provided in the config', waitForAsync(() => {
|
it('should use the custom suffix provided in the config', async () => {
|
||||||
const dataServiceSpy = spyOn(dataService, 'get').and.returnValue(
|
const dataServiceSpy = vi
|
||||||
of(null)
|
.spyOn(dataService, 'get')
|
||||||
);
|
.mockReturnValue(of(null));
|
||||||
const urlWithoutSuffix = `myUrl`;
|
const urlWithoutSuffix = `myUrl`;
|
||||||
const urlWithSuffix = `${urlWithoutSuffix}/.well-known/test-openid-configuration`;
|
const urlWithSuffix = `${urlWithoutSuffix}/.well-known/test-openid-configuration`;
|
||||||
|
|
||||||
@@ -110,15 +120,18 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
authWellknownUrlSuffix: '/.well-known/test-openid-configuration',
|
authWellknownUrlSuffix: '/.well-known/test-openid-configuration',
|
||||||
})
|
})
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(dataServiceSpy).toHaveBeenCalledOnceWith(urlWithSuffix, {
|
expect(dataServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
urlWithSuffix,
|
||||||
authWellknownUrlSuffix: '/.well-known/test-openid-configuration',
|
{
|
||||||
});
|
configId: 'configId1',
|
||||||
|
authWellknownUrlSuffix: '/.well-known/test-openid-configuration',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry once', waitForAsync(() => {
|
it('should retry once', async () => {
|
||||||
spyOn(dataService, 'get').and.returnValue(
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('one')),
|
throwError(() => new Error('one')),
|
||||||
of(DUMMY_WELL_KNOWN_DOCUMENT)
|
of(DUMMY_WELL_KNOWN_DOCUMENT)
|
||||||
@@ -133,10 +146,10 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
expect(res).toEqual(DUMMY_WELL_KNOWN_DOCUMENT);
|
expect(res).toEqual(DUMMY_WELL_KNOWN_DOCUMENT);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry twice', waitForAsync(() => {
|
it('should retry twice', async () => {
|
||||||
spyOn(dataService, 'get').and.returnValue(
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('one')),
|
throwError(() => new Error('one')),
|
||||||
throwError(() => new Error('two')),
|
throwError(() => new Error('two')),
|
||||||
@@ -152,10 +165,10 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
expect(res).toEqual(DUMMY_WELL_KNOWN_DOCUMENT);
|
expect(res).toEqual(DUMMY_WELL_KNOWN_DOCUMENT);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should fail after three tries', waitForAsync(() => {
|
it('should fail after three tries', async () => {
|
||||||
spyOn(dataService, 'get').and.returnValue(
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('one')),
|
throwError(() => new Error('one')),
|
||||||
throwError(() => new Error('two')),
|
throwError(() => new Error('two')),
|
||||||
@@ -169,17 +182,16 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getWellKnownEndPointsForConfig', () => {
|
describe('getWellKnownEndPointsForConfig', () => {
|
||||||
it('calling internal getWellKnownDocument and maps', waitForAsync(() => {
|
it('calling internal getWellKnownDocument and maps', async () => {
|
||||||
spyOn(dataService, 'get').and.returnValue(of({ jwks_uri: 'jwks_uri' }));
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
|
of({ jwks_uri: 'jwks_uri' })
|
||||||
|
);
|
||||||
|
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(service as any, 'getWellKnownDocument')();
|
||||||
service as any,
|
|
||||||
'getWellKnownDocument'
|
|
||||||
).and.callThrough();
|
|
||||||
|
|
||||||
service
|
service
|
||||||
.getWellKnownEndPointsForConfig({
|
.getWellKnownEndPointsForConfig({
|
||||||
@@ -191,10 +203,10 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
expect((result as any).jwks_uri).toBeUndefined();
|
expect((result as any).jwks_uri).toBeUndefined();
|
||||||
expect(result.jwksUri).toBe('jwks_uri');
|
expect(result.jwksUri).toBe('jwks_uri');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error and logs if no authwellknownUrl is given', waitForAsync(() => {
|
it('throws error and logs if no authwellknownUrl is given', async () => {
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
authWellknownEndpointUrl: undefined,
|
authWellknownEndpointUrl: undefined,
|
||||||
@@ -202,17 +214,19 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
|
|
||||||
service.getWellKnownEndPointsForConfig(config).subscribe({
|
service.getWellKnownEndPointsForConfig(config).subscribe({
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
expect(loggerSpy).toHaveBeenCalledOnceWith(
|
expect(loggerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
'no authWellknownEndpoint given!'
|
'no authWellknownEndpoint given!'
|
||||||
);
|
);
|
||||||
expect(error.message).toEqual('no authWellknownEndpoint given!');
|
expect(error.message).toEqual('no authWellknownEndpoint given!');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should merge the mapped endpoints with the provided endpoints', waitForAsync(() => {
|
it('should merge the mapped endpoints with the provided endpoints', async () => {
|
||||||
spyOn(dataService, 'get').and.returnValue(of(DUMMY_WELL_KNOWN_DOCUMENT));
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
|
of(DUMMY_WELL_KNOWN_DOCUMENT)
|
||||||
|
);
|
||||||
|
|
||||||
const expected: AuthWellKnownEndpoints = {
|
const expected: AuthWellKnownEndpoints = {
|
||||||
endSessionEndpoint: 'config-endSessionEndpoint',
|
endSessionEndpoint: 'config-endSessionEndpoint',
|
||||||
@@ -232,6 +246,6 @@ describe('AuthWellKnownDataService', () => {
|
|||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result).toEqual(jasmine.objectContaining(expected));
|
expect(result).toEqual(jasmine.objectContaining(expected));
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { EventTypes } from '../../public-events/event-types';
|
import { EventTypes } from '../../public-events/event-types';
|
||||||
import { PublicEventsService } from '../../public-events/public-events.service';
|
import { PublicEventsService } from '../../public-events/public-events.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { AuthWellKnownDataService } from './auth-well-known-data.service';
|
import { AuthWellKnownDataService } from './auth-well-known-data.service';
|
||||||
import { AuthWellKnownService } from './auth-well-known.service';
|
import { AuthWellKnownService } from './auth-well-known.service';
|
||||||
|
|
||||||
@@ -22,9 +23,6 @@ describe('AuthWellKnownService', () => {
|
|||||||
mockProvider(StoragePersistenceService),
|
mockProvider(StoragePersistenceService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = TestBed.inject(AuthWellKnownService);
|
service = TestBed.inject(AuthWellKnownService);
|
||||||
dataService = TestBed.inject(AuthWellKnownDataService);
|
dataService = TestBed.inject(AuthWellKnownDataService);
|
||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
@@ -36,7 +34,7 @@ describe('AuthWellKnownService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getAuthWellKnownEndPoints', () => {
|
describe('getAuthWellKnownEndPoints', () => {
|
||||||
it('getAuthWellKnownEndPoints throws an error if not config provided', waitForAsync(() => {
|
it('getAuthWellKnownEndPoints throws an error if not config provided', async () => {
|
||||||
service.queryAndStoreAuthWellKnownEndPoints(null).subscribe({
|
service.queryAndStoreAuthWellKnownEndPoints(null).subscribe({
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
expect(error).toEqual(
|
expect(error).toEqual(
|
||||||
@@ -46,17 +44,18 @@ describe('AuthWellKnownService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('getAuthWellKnownEndPoints calls always dataservice', waitForAsync(() => {
|
it('getAuthWellKnownEndPoints calls always dataservice', async () => {
|
||||||
const dataServiceSpy = spyOn(
|
const dataServiceSpy = vi
|
||||||
dataService,
|
.spyOn(dataService, 'getWellKnownEndPointsForConfig')
|
||||||
'getWellKnownEndPointsForConfig'
|
.mockReturnValue(of({ issuer: 'anything' }));
|
||||||
).and.returnValue(of({ issuer: 'anything' }));
|
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ issuer: 'anything' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ issuer: 'anything' })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.queryAndStoreAuthWellKnownEndPoints({ configId: 'configId1' })
|
.queryAndStoreAuthWellKnownEndPoints({ configId: 'configId1' })
|
||||||
@@ -65,18 +64,19 @@ describe('AuthWellKnownService', () => {
|
|||||||
expect(dataServiceSpy).toHaveBeenCalled();
|
expect(dataServiceSpy).toHaveBeenCalled();
|
||||||
expect(result).toEqual({ issuer: 'anything' });
|
expect(result).toEqual({ issuer: 'anything' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('getAuthWellKnownEndPoints stored the result if http call is made', waitForAsync(() => {
|
it('getAuthWellKnownEndPoints stored the result if http call is made', async () => {
|
||||||
const dataServiceSpy = spyOn(
|
const dataServiceSpy = vi
|
||||||
dataService,
|
.spyOn(dataService, 'getWellKnownEndPointsForConfig')
|
||||||
'getWellKnownEndPointsForConfig'
|
.mockReturnValue(of({ issuer: 'anything' }));
|
||||||
).and.returnValue(of({ issuer: 'anything' }));
|
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
const storeSpy = spyOn(service, 'storeWellKnownEndpoints');
|
() => null
|
||||||
|
);
|
||||||
|
const storeSpy = vi.spyOn(service, 'storeWellKnownEndpoints');
|
||||||
|
|
||||||
service
|
service
|
||||||
.queryAndStoreAuthWellKnownEndPoints({ configId: 'configId1' })
|
.queryAndStoreAuthWellKnownEndPoints({ configId: 'configId1' })
|
||||||
@@ -85,13 +85,13 @@ describe('AuthWellKnownService', () => {
|
|||||||
expect(storeSpy).toHaveBeenCalled();
|
expect(storeSpy).toHaveBeenCalled();
|
||||||
expect(result).toEqual({ issuer: 'anything' });
|
expect(result).toEqual({ issuer: 'anything' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws `ConfigLoadingFailed` event when error happens from http', waitForAsync(() => {
|
it('throws `ConfigLoadingFailed` event when error happens from http', async () => {
|
||||||
spyOn(dataService, 'getWellKnownEndPointsForConfig').and.returnValue(
|
vi.spyOn(dataService, 'getWellKnownEndPointsForConfig').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
const publicEventsServiceSpy = spyOn(publicEventsService, 'fireEvent');
|
const publicEventsServiceSpy = vi.spyOn(publicEventsService, 'fireEvent');
|
||||||
|
|
||||||
service
|
service
|
||||||
.queryAndStoreAuthWellKnownEndPoints({ configId: 'configId1' })
|
.queryAndStoreAuthWellKnownEndPoints({ configId: 'configId1' })
|
||||||
@@ -99,12 +99,12 @@ describe('AuthWellKnownService', () => {
|
|||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
expect(publicEventsServiceSpy).toHaveBeenCalledTimes(1);
|
expect(publicEventsServiceSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(publicEventsServiceSpy).toHaveBeenCalledOnceWith(
|
expect(publicEventsServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
EventTypes.ConfigLoadingFailed,
|
EventTypes.ConfigLoadingFailed,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockAbstractProvider, mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { EventTypes } from '../public-events/event-types';
|
import { EventTypes } from '../public-events/event-types';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockAbstractProvider, mockProvider } from '../testing/mock';
|
||||||
import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
||||||
import { AuthWellKnownService } from './auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from './auth-well-known/auth-well-known.service';
|
||||||
import { ConfigurationService } from './config.service';
|
import { ConfigurationService } from './config.service';
|
||||||
import { StsConfigLoader, StsConfigStaticLoader } from './loader/config-loader';
|
import { StsConfigLoader, StsConfigStaticLoader } from './loader/config-loader';
|
||||||
import { OpenIdConfiguration } from './openid-configuration';
|
import type { OpenIdConfiguration } from './openid-configuration';
|
||||||
import { ConfigValidationService } from './validation/config-validation.service';
|
import { ConfigValidationService } from './validation/config-validation.service';
|
||||||
|
|
||||||
describe('Configuration Service', () => {
|
describe('Configuration Service', () => {
|
||||||
@@ -34,9 +35,6 @@ describe('Configuration Service', () => {
|
|||||||
mockAbstractProvider(StsConfigLoader, StsConfigStaticLoader),
|
mockAbstractProvider(StsConfigLoader, StsConfigStaticLoader),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
configService = TestBed.inject(ConfigurationService);
|
configService = TestBed.inject(ConfigurationService);
|
||||||
publicEventsService = TestBed.inject(PublicEventsService);
|
publicEventsService = TestBed.inject(PublicEventsService);
|
||||||
authWellKnownService = TestBed.inject(AuthWellKnownService);
|
authWellKnownService = TestBed.inject(AuthWellKnownService);
|
||||||
@@ -88,47 +86,53 @@ describe('Configuration Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getOpenIDConfiguration', () => {
|
describe('getOpenIDConfiguration', () => {
|
||||||
it(`if config is already saved 'loadConfigs' is not called`, waitForAsync(() => {
|
it(`if config is already saved 'loadConfigs' is not called`, async () => {
|
||||||
(configService as any).configsInternal = {
|
(configService as any).configsInternal = {
|
||||||
configId1: { configId: 'configId1' },
|
configId1: { configId: 'configId1' },
|
||||||
configId2: { configId: 'configId2' },
|
configId2: { configId: 'configId2' },
|
||||||
};
|
};
|
||||||
const spy = spyOn(configService as any, 'loadConfigs');
|
const spy = vi.spyOn(configService as any, 'loadConfigs');
|
||||||
|
|
||||||
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
||||||
expect(config).toBeTruthy();
|
expect(config).toBeTruthy();
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`if config is NOT already saved 'loadConfigs' is called`, waitForAsync(() => {
|
it(`if config is NOT already saved 'loadConfigs' is called`, async () => {
|
||||||
const configs = [{ configId: 'configId1' }, { configId: 'configId2' }];
|
const configs = [{ configId: 'configId1' }, { configId: 'configId2' }];
|
||||||
const spy = spyOn(configService as any, 'loadConfigs').and.returnValue(
|
const spy = vi
|
||||||
of(configs)
|
.spyOn(configService as any, 'loadConfigs')
|
||||||
);
|
.mockReturnValue(of(configs));
|
||||||
|
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(true);
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(true);
|
||||||
|
|
||||||
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
||||||
expect(config).toBeTruthy();
|
expect(config).toBeTruthy();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`returns null if config is not valid`, waitForAsync(() => {
|
it('returns null if config is not valid', async () => {
|
||||||
const configs = [{ configId: 'configId1' }];
|
const configs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
spyOn(configService as any, 'loadConfigs').and.returnValue(of(configs));
|
vi.spyOn(configService as any, 'loadConfigs').mockReturnValue(
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(false);
|
of(configs)
|
||||||
const consoleSpy = spyOn(console, 'warn');
|
);
|
||||||
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
const consoleSpy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
||||||
expect(config).toBeNull();
|
expect(config).toBeNull();
|
||||||
expect(consoleSpy).toHaveBeenCalledOnceWith(`[oidc-client-rx] No configuration found for config id 'configId1'.`)
|
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
`[oidc-client-rx] No configuration found for config id 'configId1'.`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`returns null if configs are stored but not existing ID is passed`, waitForAsync(() => {
|
it('returns null if configs are stored but not existing ID is passed', async () => {
|
||||||
(configService as any).configsInternal = {
|
(configService as any).configsInternal = {
|
||||||
configId1: { configId: 'configId1' },
|
configId1: { configId: 'configId1' },
|
||||||
configId2: { configId: 'configId2' },
|
configId2: { configId: 'configId2' },
|
||||||
@@ -139,16 +143,18 @@ describe('Configuration Service', () => {
|
|||||||
.subscribe((config) => {
|
.subscribe((config) => {
|
||||||
expect(config).toBeNull();
|
expect(config).toBeNull();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`sets authWellKnownEndPoints on config if authWellKnownEndPoints is stored`, waitForAsync(() => {
|
it('sets authWellKnownEndPoints on config if authWellKnownEndPoints is stored', async () => {
|
||||||
const configs = [{ configId: 'configId1' }];
|
const configs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
spyOn(configService as any, 'loadConfigs').and.returnValue(of(configs));
|
vi.spyOn(configService as any, 'loadConfigs').mockReturnValue(
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(true);
|
of(configs)
|
||||||
const consoleSpy = spyOn(console, 'warn');
|
);
|
||||||
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(true);
|
||||||
|
const consoleSpy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue({
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue({
|
||||||
issuer: 'auth-well-known',
|
issuer: 'auth-well-known',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -156,30 +162,32 @@ describe('Configuration Service', () => {
|
|||||||
expect(config?.authWellknownEndpoints).toEqual({
|
expect(config?.authWellknownEndpoints).toEqual({
|
||||||
issuer: 'auth-well-known',
|
issuer: 'auth-well-known',
|
||||||
});
|
});
|
||||||
expect(consoleSpy).not.toHaveBeenCalled()
|
expect(consoleSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`fires ConfigLoaded if authWellKnownEndPoints is stored`, waitForAsync(() => {
|
it('fires ConfigLoaded if authWellKnownEndPoints is stored', async () => {
|
||||||
const configs = [{ configId: 'configId1' }];
|
const configs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
spyOn(configService as any, 'loadConfigs').and.returnValue(of(configs));
|
vi.spyOn(configService as any, 'loadConfigs').mockReturnValue(
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(true);
|
of(configs)
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue({
|
);
|
||||||
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(true);
|
||||||
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue({
|
||||||
issuer: 'auth-well-known',
|
issuer: 'auth-well-known',
|
||||||
});
|
});
|
||||||
|
|
||||||
const spy = spyOn(publicEventsService, 'fireEvent');
|
const spy = vi.spyOn(publicEventsService, 'fireEvent');
|
||||||
|
|
||||||
configService.getOpenIDConfiguration('configId1').subscribe(() => {
|
configService.getOpenIDConfiguration('configId1').subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
EventTypes.ConfigLoaded,
|
EventTypes.ConfigLoaded,
|
||||||
jasmine.anything()
|
expect.anything()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`stores, uses and fires event when authwellknownendpoints are passed`, waitForAsync(() => {
|
it('stores, uses and fires event when authwellknownendpoints are passed', async () => {
|
||||||
const configs = [
|
const configs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -187,58 +195,60 @@ describe('Configuration Service', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(configService as any, 'loadConfigs').and.returnValue(of(configs));
|
vi.spyOn(configService as any, 'loadConfigs').mockReturnValue(
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(true);
|
of(configs)
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue(null);
|
);
|
||||||
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(true);
|
||||||
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue(null);
|
||||||
|
|
||||||
const fireEventSpy = spyOn(publicEventsService, 'fireEvent');
|
const fireEventSpy = vi.spyOn(publicEventsService, 'fireEvent');
|
||||||
const storeWellKnownEndpointsSpy = spyOn(
|
const storeWellKnownEndpointsSpy = vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'storeWellKnownEndpoints'
|
'storeWellKnownEndpoints'
|
||||||
);
|
);
|
||||||
|
|
||||||
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
configService.getOpenIDConfiguration('configId1').subscribe((config) => {
|
||||||
expect(config).toBeTruthy();
|
expect(config).toBeTruthy();
|
||||||
expect(fireEventSpy).toHaveBeenCalledOnceWith(
|
expect(fireEventSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
EventTypes.ConfigLoaded,
|
EventTypes.ConfigLoaded,
|
||||||
jasmine.anything()
|
expect.anything()
|
||||||
);
|
);
|
||||||
expect(storeWellKnownEndpointsSpy).toHaveBeenCalledOnceWith(
|
expect(storeWellKnownEndpointsSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
config as OpenIdConfiguration,
|
config as OpenIdConfiguration,
|
||||||
{
|
{
|
||||||
issuer: 'auth-well-known',
|
issuer: 'auth-well-known',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getOpenIDConfigurations', () => {
|
describe('getOpenIDConfigurations', () => {
|
||||||
it(`returns correct result`, waitForAsync(() => {
|
it('returns correct result', async () => {
|
||||||
spyOn(stsConfigLoader, 'loadConfigs').and.returnValue(
|
vi.spyOn(stsConfigLoader, 'loadConfigs').mockReturnValue(
|
||||||
of([
|
of([
|
||||||
{ configId: 'configId1' } as OpenIdConfiguration,
|
{ configId: 'configId1' } as OpenIdConfiguration,
|
||||||
{ configId: 'configId2' } as OpenIdConfiguration,
|
{ configId: 'configId2' } as OpenIdConfiguration,
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(true);
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(true);
|
||||||
|
|
||||||
configService.getOpenIDConfigurations('configId1').subscribe((result) => {
|
configService.getOpenIDConfigurations('configId1').subscribe((result) => {
|
||||||
expect(result.allConfigs.length).toEqual(2);
|
expect(result.allConfigs.length).toEqual(2);
|
||||||
expect(result.currentConfig).toBeTruthy();
|
expect(result.currentConfig).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`created configId when configId is not set`, waitForAsync(() => {
|
it('created configId when configId is not set', async () => {
|
||||||
spyOn(stsConfigLoader, 'loadConfigs').and.returnValue(
|
vi.spyOn(stsConfigLoader, 'loadConfigs').mockReturnValue(
|
||||||
of([
|
of([
|
||||||
{ clientId: 'clientId1' } as OpenIdConfiguration,
|
{ clientId: 'clientId1' } as OpenIdConfiguration,
|
||||||
{ clientId: 'clientId2' } as OpenIdConfiguration,
|
{ clientId: 'clientId2' } as OpenIdConfiguration,
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(configValidationService, 'validateConfig').and.returnValue(true);
|
vi.spyOn(configValidationService, 'validateConfig').mockReturnValue(true);
|
||||||
|
|
||||||
configService.getOpenIDConfigurations().subscribe((result) => {
|
configService.getOpenIDConfigurations().subscribe((result) => {
|
||||||
expect(result.allConfigs.length).toEqual(2);
|
expect(result.allConfigs.length).toEqual(2);
|
||||||
@@ -249,17 +259,19 @@ describe('Configuration Service', () => {
|
|||||||
expect(result.currentConfig).toBeTruthy();
|
expect(result.currentConfig).toBeTruthy();
|
||||||
expect(result.currentConfig?.configId).toBeTruthy();
|
expect(result.currentConfig?.configId).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it(`returns empty array if config is not valid`, waitForAsync(() => {
|
it('returns empty array if config is not valid', async () => {
|
||||||
spyOn(stsConfigLoader, 'loadConfigs').and.returnValue(
|
vi.spyOn(stsConfigLoader, 'loadConfigs').mockReturnValue(
|
||||||
of([
|
of([
|
||||||
{ configId: 'configId1' } as OpenIdConfiguration,
|
{ configId: 'configId1' } as OpenIdConfiguration,
|
||||||
{ configId: 'configId2' } as OpenIdConfiguration,
|
{ configId: 'configId2' } as OpenIdConfiguration,
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(configValidationService, 'validateConfigs').and.returnValue(false);
|
vi.spyOn(configValidationService, 'validateConfigs').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
configService
|
configService
|
||||||
.getOpenIDConfigurations()
|
.getOpenIDConfigurations()
|
||||||
@@ -267,12 +279,12 @@ describe('Configuration Service', () => {
|
|||||||
expect(allConfigs).toEqual([]);
|
expect(allConfigs).toEqual([]);
|
||||||
expect(currentConfig).toBeNull();
|
expect(currentConfig).toBeNull();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setSpecialCases', () => {
|
describe('setSpecialCases', () => {
|
||||||
it(`should set special cases when current platform is browser`, () => {
|
it('should set special cases when current platform is browser', () => {
|
||||||
spyOn(platformProvider, 'isBrowser').and.returnValue(false);
|
vi.spyOn(platformProvider, 'isBrowser').mockReturnValue(false);
|
||||||
|
|
||||||
const config = { configId: 'configId1' } as OpenIdConfiguration;
|
const config = { configId: 'configId1' } as OpenIdConfiguration;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {inject, Injectable, isDevMode} from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { forkJoin, Observable, of } from 'rxjs';
|
import { type Observable, forkJoin, of } from 'rxjs';
|
||||||
import { concatMap, map } from 'rxjs/operators';
|
import { concatMap, map } from 'rxjs/operators';
|
||||||
|
import { injectAbstractType } from '../injection/inject';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { EventTypes } from '../public-events/event-types';
|
import { EventTypes } from '../public-events/event-types';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
@@ -9,7 +10,7 @@ import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
|||||||
import { AuthWellKnownService } from './auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from './auth-well-known/auth-well-known.service';
|
||||||
import { DEFAULT_CONFIG } from './default-config';
|
import { DEFAULT_CONFIG } from './default-config';
|
||||||
import { StsConfigLoader } from './loader/config-loader';
|
import { StsConfigLoader } from './loader/config-loader';
|
||||||
import { OpenIdConfiguration } from './openid-configuration';
|
import type { OpenIdConfiguration } from './openid-configuration';
|
||||||
import { ConfigValidationService } from './validation/config-validation.service';
|
import { ConfigValidationService } from './validation/config-validation.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -26,7 +27,7 @@ export class ConfigurationService {
|
|||||||
|
|
||||||
private readonly authWellKnownService = inject(AuthWellKnownService);
|
private readonly authWellKnownService = inject(AuthWellKnownService);
|
||||||
|
|
||||||
private readonly loader = inject(StsConfigLoader);
|
private readonly loader = injectAbstractType(StsConfigLoader);
|
||||||
|
|
||||||
private readonly configValidationService = inject(ConfigValidationService);
|
private readonly configValidationService = inject(ConfigValidationService);
|
||||||
|
|
||||||
@@ -84,11 +85,14 @@ export class ConfigurationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getConfig(configId?: string): OpenIdConfiguration | null {
|
private getConfig(configId?: string): OpenIdConfiguration | null {
|
||||||
if (Boolean(configId)) {
|
if (configId) {
|
||||||
const config = this.configsInternal[configId!];
|
const config = this.configsInternal[configId!];
|
||||||
|
|
||||||
if(!config && isDevMode()) {
|
if (!config) {
|
||||||
console.warn(`[oidc-client-rx] No configuration found for config id '${configId}'.`);
|
// biome-ignore lint/suspicious/noConsole: <explanation>
|
||||||
|
console.warn(
|
||||||
|
`[oidc-client-rx] No configuration found for config id '${configId}'.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return config || null;
|
return config || null;
|
||||||
@@ -165,7 +169,7 @@ export class ConfigurationService {
|
|||||||
configuration
|
configuration
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!!alreadyExistingAuthWellKnownEndpoints) {
|
if (alreadyExistingAuthWellKnownEndpoints) {
|
||||||
configuration.authWellknownEndpoints =
|
configuration.authWellknownEndpoints =
|
||||||
alreadyExistingAuthWellKnownEndpoints;
|
alreadyExistingAuthWellKnownEndpoints;
|
||||||
|
|
||||||
@@ -174,7 +178,7 @@ export class ConfigurationService {
|
|||||||
|
|
||||||
const passedAuthWellKnownEndpoints = configuration.authWellknownEndpoints;
|
const passedAuthWellKnownEndpoints = configuration.authWellknownEndpoints;
|
||||||
|
|
||||||
if (!!passedAuthWellKnownEndpoints) {
|
if (passedAuthWellKnownEndpoints) {
|
||||||
this.authWellKnownService.storeWellKnownEndpoints(
|
this.authWellKnownService.storeWellKnownEndpoints(
|
||||||
configuration,
|
configuration,
|
||||||
passedAuthWellKnownEndpoints
|
passedAuthWellKnownEndpoints
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { waitForAsync } from '@angular/core/testing';
|
import { waitForAsync } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { OpenIdConfiguration } from '../openid-configuration';
|
import type { OpenIdConfiguration } from '../openid-configuration';
|
||||||
import { StsConfigHttpLoader, StsConfigStaticLoader } from './config-loader';
|
import { StsConfigHttpLoader, StsConfigStaticLoader } from './config-loader';
|
||||||
|
|
||||||
describe('ConfigLoader', () => {
|
describe('ConfigLoader', () => {
|
||||||
describe('StsConfigStaticLoader', () => {
|
describe('StsConfigStaticLoader', () => {
|
||||||
describe('loadConfigs', () => {
|
describe('loadConfigs', () => {
|
||||||
it('returns an array if an array is passed', waitForAsync(() => {
|
it('returns an array if an array is passed', async () => {
|
||||||
const toPass = [
|
const toPass = [
|
||||||
{ configId: 'configId1' } as OpenIdConfiguration,
|
{ configId: 'configId1' } as OpenIdConfiguration,
|
||||||
{ configId: 'configId2' } as OpenIdConfiguration,
|
{ configId: 'configId2' } as OpenIdConfiguration,
|
||||||
@@ -17,11 +17,11 @@ describe('ConfigLoader', () => {
|
|||||||
const result$ = loader.loadConfigs();
|
const result$ = loader.loadConfigs();
|
||||||
|
|
||||||
result$.subscribe((result) => {
|
result$.subscribe((result) => {
|
||||||
expect(Array.isArray(result)).toBeTrue();
|
expect(Array.isArray(result)).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns an array if only one config is passed', waitForAsync(() => {
|
it('returns an array if only one config is passed', async () => {
|
||||||
const loader = new StsConfigStaticLoader({
|
const loader = new StsConfigStaticLoader({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
} as OpenIdConfiguration);
|
} as OpenIdConfiguration);
|
||||||
@@ -29,15 +29,15 @@ describe('ConfigLoader', () => {
|
|||||||
const result$ = loader.loadConfigs();
|
const result$ = loader.loadConfigs();
|
||||||
|
|
||||||
result$.subscribe((result) => {
|
result$.subscribe((result) => {
|
||||||
expect(Array.isArray(result)).toBeTrue();
|
expect(Array.isArray(result)).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('StsConfigHttpLoader', () => {
|
describe('StsConfigHttpLoader', () => {
|
||||||
describe('loadConfigs', () => {
|
describe('loadConfigs', () => {
|
||||||
it('returns an array if an array of observables is passed', waitForAsync(() => {
|
it('returns an array if an array of observables is passed', async () => {
|
||||||
const toPass = [
|
const toPass = [
|
||||||
of({ configId: 'configId1' } as OpenIdConfiguration),
|
of({ configId: 'configId1' } as OpenIdConfiguration),
|
||||||
of({ configId: 'configId2' } as OpenIdConfiguration),
|
of({ configId: 'configId2' } as OpenIdConfiguration),
|
||||||
@@ -47,13 +47,13 @@ describe('ConfigLoader', () => {
|
|||||||
const result$ = loader.loadConfigs();
|
const result$ = loader.loadConfigs();
|
||||||
|
|
||||||
result$.subscribe((result) => {
|
result$.subscribe((result) => {
|
||||||
expect(Array.isArray(result)).toBeTrue();
|
expect(Array.isArray(result)).toBeTruthy();
|
||||||
expect(result[0].configId).toBe('configId1');
|
expect(result[0].configId).toBe('configId1');
|
||||||
expect(result[1].configId).toBe('configId2');
|
expect(result[1].configId).toBe('configId2');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns an array if an observable with a config array is passed', waitForAsync(() => {
|
it('returns an array if an observable with a config array is passed', async () => {
|
||||||
const toPass = of([
|
const toPass = of([
|
||||||
{ configId: 'configId1' } as OpenIdConfiguration,
|
{ configId: 'configId1' } as OpenIdConfiguration,
|
||||||
{ configId: 'configId2' } as OpenIdConfiguration,
|
{ configId: 'configId2' } as OpenIdConfiguration,
|
||||||
@@ -63,13 +63,13 @@ describe('ConfigLoader', () => {
|
|||||||
const result$ = loader.loadConfigs();
|
const result$ = loader.loadConfigs();
|
||||||
|
|
||||||
result$.subscribe((result) => {
|
result$.subscribe((result) => {
|
||||||
expect(Array.isArray(result)).toBeTrue();
|
expect(Array.isArray(result)).toBeTruthy();
|
||||||
expect(result[0].configId).toBe('configId1');
|
expect(result[0].configId).toBe('configId1');
|
||||||
expect(result[1].configId).toBe('configId2');
|
expect(result[1].configId).toBe('configId2');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns an array if only one config is passed', waitForAsync(() => {
|
it('returns an array if only one config is passed', async () => {
|
||||||
const loader = new StsConfigHttpLoader(
|
const loader = new StsConfigHttpLoader(
|
||||||
of({ configId: 'configId1' } as OpenIdConfiguration)
|
of({ configId: 'configId1' } as OpenIdConfiguration)
|
||||||
);
|
);
|
||||||
@@ -77,10 +77,10 @@ describe('ConfigLoader', () => {
|
|||||||
const result$ = loader.loadConfigs();
|
const result$ = loader.loadConfigs();
|
||||||
|
|
||||||
result$.subscribe((result) => {
|
result$.subscribe((result) => {
|
||||||
expect(Array.isArray(result)).toBeTrue();
|
expect(Array.isArray(result)).toBeTruthy();
|
||||||
expect(result[0].configId).toBe('configId1');
|
expect(result[0].configId).toBe('configId1');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Provider } from 'injection-js';
|
import type { Provider } from 'injection-js';
|
||||||
import { forkJoin, Observable, of } from 'rxjs';
|
import { type Observable, forkJoin, of } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../openid-configuration';
|
import type { OpenIdConfiguration } from '../openid-configuration';
|
||||||
|
|
||||||
export class OpenIdConfigLoader {
|
export class OpenIdConfigLoader {
|
||||||
loader?: Provider;
|
loader?: Provider;
|
||||||
@@ -13,6 +13,7 @@ export abstract class StsConfigLoader {
|
|||||||
|
|
||||||
export class StsConfigStaticLoader implements StsConfigLoader {
|
export class StsConfigStaticLoader implements StsConfigLoader {
|
||||||
constructor(
|
constructor(
|
||||||
|
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||||
private readonly passedConfigs: OpenIdConfiguration | OpenIdConfiguration[]
|
private readonly passedConfigs: OpenIdConfiguration | OpenIdConfiguration[]
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ export class StsConfigStaticLoader implements StsConfigLoader {
|
|||||||
|
|
||||||
export class StsConfigHttpLoader implements StsConfigLoader {
|
export class StsConfigHttpLoader implements StsConfigLoader {
|
||||||
constructor(
|
constructor(
|
||||||
|
// biome-ignore lint/style/noParameterProperties: <explanation>
|
||||||
private readonly configs$:
|
private readonly configs$:
|
||||||
| Observable<OpenIdConfiguration>
|
| Observable<OpenIdConfiguration>
|
||||||
| Observable<OpenIdConfiguration>[]
|
| Observable<OpenIdConfiguration>[]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { LogLevel } from '../logging/log-level';
|
import type { LogLevel } from '../logging/log-level';
|
||||||
import { AuthWellKnownEndpoints } from './auth-well-known/auth-well-known-endpoints';
|
import type { AuthWellKnownEndpoints } from './auth-well-known/auth-well-known-endpoints';
|
||||||
|
|
||||||
export interface OpenIdConfiguration {
|
export interface OpenIdConfiguration {
|
||||||
/**
|
/**
|
||||||
@@ -207,5 +207,5 @@ export interface OpenIdConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Disable cleaning up the popup when receiving invalid messages
|
* Disable cleaning up the popup when receiving invalid messages
|
||||||
*/
|
*/
|
||||||
disableCleaningPopupOnInvalidMessage?: boolean
|
disableCleaningPopupOnInvalidMessage?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LogLevel } from '../../logging/log-level';
|
import { LogLevel } from '../../logging/log-level';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { OpenIdConfiguration } from '../openid-configuration';
|
import { mockProvider } from '../../testing/mock';
|
||||||
|
import type { OpenIdConfiguration } from '../openid-configuration';
|
||||||
import { ConfigValidationService } from './config-validation.service';
|
import { ConfigValidationService } from './config-validation.service';
|
||||||
import { allMultipleConfigRules } from './rules';
|
import { allMultipleConfigRules } from './rules';
|
||||||
|
|
||||||
@@ -14,6 +15,8 @@ describe('Config Validation Service', () => {
|
|||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [ConfigValidationService, mockProvider(LoggerService)],
|
providers: [ConfigValidationService, mockProvider(LoggerService)],
|
||||||
});
|
});
|
||||||
|
configValidationService = TestBed.inject(ConfigValidationService);
|
||||||
|
loggerService = TestBed.inject(LoggerService);
|
||||||
});
|
});
|
||||||
|
|
||||||
const VALID_CONFIG = {
|
const VALID_CONFIG = {
|
||||||
@@ -29,11 +32,6 @@ describe('Config Validation Service', () => {
|
|||||||
logLevel: LogLevel.Debug,
|
logLevel: LogLevel.Debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
configValidationService = TestBed.inject(ConfigValidationService);
|
|
||||||
loggerService = TestBed.inject(LoggerService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
expect(configValidationService).toBeTruthy();
|
expect(configValidationService).toBeTruthy();
|
||||||
});
|
});
|
||||||
@@ -42,26 +40,27 @@ describe('Config Validation Service', () => {
|
|||||||
const config = {};
|
const config = {};
|
||||||
const result = configValidationService.validateConfig(config);
|
const result = configValidationService.validateConfig(config);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true for valid config', () => {
|
it('should return true for valid config', () => {
|
||||||
const result = configValidationService.validateConfig(VALID_CONFIG);
|
const result = configValidationService.validateConfig(VALID_CONFIG);
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls `logWarning` if one rule has warning level', () => {
|
it('calls `logWarning` if one rule has warning level', () => {
|
||||||
const loggerWarningSpy = spyOn(loggerService, 'logWarning');
|
const loggerWarningSpy = vi.spyOn(loggerService, 'logWarning');
|
||||||
const messageTypeSpy = spyOn(
|
const messageTypeSpy = vi.spyOn(
|
||||||
configValidationService as any,
|
configValidationService as any,
|
||||||
'getAllMessagesOfType'
|
'getAllMessagesOfType'
|
||||||
);
|
);
|
||||||
|
|
||||||
messageTypeSpy
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('warning', jasmine.any(Array))
|
messageTypeSpy,
|
||||||
.and.returnValue(['A warning message']);
|
(arg1: any, arg2: any) => arg1 === 'warning' && Array.isArray(arg2),
|
||||||
messageTypeSpy.withArgs('error', jasmine.any(Array)).and.callThrough();
|
() => ['A warning message']
|
||||||
|
);
|
||||||
|
|
||||||
configValidationService.validateConfig(VALID_CONFIG);
|
configValidationService.validateConfig(VALID_CONFIG);
|
||||||
expect(loggerWarningSpy).toHaveBeenCalled();
|
expect(loggerWarningSpy).toHaveBeenCalled();
|
||||||
@@ -72,7 +71,7 @@ describe('Config Validation Service', () => {
|
|||||||
const config = { ...VALID_CONFIG, clientId: '' } as OpenIdConfiguration;
|
const config = { ...VALID_CONFIG, clientId: '' } as OpenIdConfiguration;
|
||||||
const result = configValidationService.validateConfig(config);
|
const result = configValidationService.validateConfig(config);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,7 +83,7 @@ describe('Config Validation Service', () => {
|
|||||||
} as OpenIdConfiguration;
|
} as OpenIdConfiguration;
|
||||||
const result = configValidationService.validateConfig(config);
|
const result = configValidationService.validateConfig(config);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -93,7 +92,7 @@ describe('Config Validation Service', () => {
|
|||||||
const config = { ...VALID_CONFIG, redirectUrl: '' };
|
const config = { ...VALID_CONFIG, redirectUrl: '' };
|
||||||
const result = configValidationService.validateConfig(config);
|
const result = configValidationService.validateConfig(config);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ describe('Config Validation Service', () => {
|
|||||||
} as OpenIdConfiguration;
|
} as OpenIdConfiguration;
|
||||||
const result = configValidationService.validateConfig(config);
|
const result = configValidationService.validateConfig(config);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -120,12 +119,12 @@ describe('Config Validation Service', () => {
|
|||||||
scopes: 'scope1 scope2 but_no_offline_access',
|
scopes: 'scope1 scope2 but_no_offline_access',
|
||||||
};
|
};
|
||||||
|
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const loggerWarningSpy = spyOn(loggerService, 'logWarning');
|
const loggerWarningSpy = vi.spyOn(loggerService, 'logWarning');
|
||||||
|
|
||||||
const result = configValidationService.validateConfig(config);
|
const result = configValidationService.validateConfig(config);
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
expect(loggerSpy).not.toHaveBeenCalled();
|
expect(loggerSpy).not.toHaveBeenCalled();
|
||||||
expect(loggerWarningSpy).toHaveBeenCalled();
|
expect(loggerWarningSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@@ -146,47 +145,47 @@ describe('Config Validation Service', () => {
|
|||||||
scopes: 'scope1 scope2 but_no_offline_access',
|
scopes: 'scope1 scope2 but_no_offline_access',
|
||||||
};
|
};
|
||||||
|
|
||||||
const loggerErrorSpy = spyOn(loggerService, 'logError');
|
const loggerErrorSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const loggerWarningSpy = spyOn(loggerService, 'logWarning');
|
const loggerWarningSpy = vi.spyOn(loggerService, 'logWarning');
|
||||||
|
|
||||||
const result = configValidationService.validateConfigs([
|
const result = configValidationService.validateConfigs([
|
||||||
config1,
|
config1,
|
||||||
config2,
|
config2,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
expect(loggerErrorSpy).not.toHaveBeenCalled();
|
expect(loggerErrorSpy).not.toHaveBeenCalled();
|
||||||
expect(loggerWarningSpy.calls.argsFor(0)).toEqual([
|
expect(vi.mocked(loggerWarningSpy).mock.calls[0]).toEqual([
|
||||||
config1,
|
config1,
|
||||||
'You added multiple configs with the same authority, clientId and scope',
|
'You added multiple configs with the same authority, clientId and scope',
|
||||||
]);
|
]);
|
||||||
expect(loggerWarningSpy.calls.argsFor(1)).toEqual([
|
expect(vi.mocked(loggerWarningSpy).mock.calls[1]).toEqual([
|
||||||
config2,
|
config2,
|
||||||
'You added multiple configs with the same authority, clientId and scope',
|
'You added multiple configs with the same authority, clientId and scope',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false and a better error message when config is not passed as object with config property', () => {
|
it('should return false and a better error message when config is not passed as object with config property', () => {
|
||||||
const loggerWarningSpy = spyOn(loggerService, 'logWarning');
|
const loggerWarningSpy = vi.spyOn(loggerService, 'logWarning');
|
||||||
|
|
||||||
const result = configValidationService.validateConfigs([]);
|
const result = configValidationService.validateConfigs([]);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
expect(loggerWarningSpy).not.toHaveBeenCalled();
|
expect(loggerWarningSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('validateConfigs', () => {
|
describe('validateConfigs', () => {
|
||||||
it('calls internal method with empty array if something falsy is passed', () => {
|
it('calls internal method with empty array if something falsy is passed', () => {
|
||||||
const spy = spyOn(
|
const spy = vi.spyOn(
|
||||||
configValidationService as any,
|
configValidationService as any,
|
||||||
'validateConfigsInternal'
|
'validateConfigsInternal'
|
||||||
).and.callThrough();
|
);
|
||||||
|
|
||||||
const result = configValidationService.validateConfigs([]);
|
const result = configValidationService.validateConfigs([]);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
expect(spy).toHaveBeenCalledOnceWith([], allMultipleConfigRules);
|
expect(spy).toHaveBeenCalledExactlyOnceWith([], allMultipleConfigRules);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { CryptoService } from '../utils/crypto/crypto.service';
|
import { CryptoService } from '../utils/crypto/crypto.service';
|
||||||
import {
|
import {
|
||||||
JwkExtractor,
|
JwkExtractor,
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { HttpErrorResponse, HttpHeaders } from '@ngify/http';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { createRetriableStream } from '../../../test/create-retriable-stream.helper';
|
|
||||||
import { DataService } from '../../api/data.service';
|
import { DataService } from '../../api/data.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
|
import { createRetriableStream } from '../../testing/create-retriable-stream.helper';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { TokenValidationService } from '../../validation/token-validation.service';
|
import { TokenValidationService } from '../../validation/token-validation.service';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { CodeFlowCallbackHandlerService } from './code-flow-callback-handler.service';
|
import { CodeFlowCallbackHandlerService } from './code-flow-callback-handler.service';
|
||||||
|
|
||||||
@@ -46,13 +47,16 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('codeFlowCallback', () => {
|
describe('codeFlowCallback', () => {
|
||||||
it('throws error if no state is given', waitForAsync(() => {
|
it('throws error if no state is given', async () => {
|
||||||
const getUrlParameterSpy = spyOn(
|
const getUrlParameterSpy = vi
|
||||||
urlService,
|
.spyOn(urlService, 'getUrlParameter')
|
||||||
'getUrlParameter'
|
.mockReturnValue('params');
|
||||||
).and.returnValue('params');
|
|
||||||
|
|
||||||
getUrlParameterSpy.withArgs('test-url', 'state').and.returnValue('');
|
mockImplementationWhenArgsEqual(
|
||||||
|
getUrlParameterSpy,
|
||||||
|
['test-url', 'state'],
|
||||||
|
() => ''
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCallback('test-url', { configId: 'configId1' })
|
.codeFlowCallback('test-url', { configId: 'configId1' })
|
||||||
@@ -61,15 +65,14 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if no code is given', waitForAsync(() => {
|
it('throws error if no code is given', async () => {
|
||||||
const getUrlParameterSpy = spyOn(
|
const getUrlParameterSpy = vi
|
||||||
urlService,
|
.spyOn(urlService, 'getUrlParameter')
|
||||||
'getUrlParameter'
|
.mockReturnValue('params');
|
||||||
).and.returnValue('params');
|
|
||||||
|
|
||||||
getUrlParameterSpy.withArgs('test-url', 'code').and.returnValue('');
|
getUrlParameterSpy.withArgs('test-url', 'code').mockReturnValue('');
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCallback('test-url', { configId: 'configId1' })
|
.codeFlowCallback('test-url', { configId: 'configId1' })
|
||||||
@@ -78,10 +81,10 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns callbackContext if all params are good', waitForAsync(() => {
|
it('returns callbackContext if all params are good', async () => {
|
||||||
spyOn(urlService, 'getUrlParameter').and.returnValue('params');
|
vi.spyOn(urlService, 'getUrlParameter').mockReturnValue('params');
|
||||||
|
|
||||||
const expectedCallbackContext = {
|
const expectedCallbackContext = {
|
||||||
code: 'params',
|
code: 'params',
|
||||||
@@ -100,7 +103,7 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
.subscribe((callbackContext) => {
|
.subscribe((callbackContext) => {
|
||||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('codeFlowCodeRequest ', () => {
|
describe('codeFlowCodeRequest ', () => {
|
||||||
@@ -112,11 +115,11 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
url: 'https://identity-server.test/openid-connect/token',
|
url: 'https://identity-server.test/openid-connect/token',
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws error if state is not correct', waitForAsync(() => {
|
it('throws error if state is not correct', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||||
@@ -125,16 +128,18 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if authWellknownEndpoints is null is given', waitForAsync(() => {
|
it('throws error if authWellknownEndpoints is null is given', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => null
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||||
@@ -143,16 +148,18 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if tokenendpoint is null is given', waitForAsync(() => {
|
it('throws error if tokenendpoint is null is given', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: null });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ tokenEndpoint: null })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||||
@@ -161,34 +168,36 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls dataService if all params are good', waitForAsync(() => {
|
it('calls dataService if all params are good', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(postSpy).toHaveBeenCalledOnceWith(
|
expect(postSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'tokenEndpoint',
|
'tokenEndpoint',
|
||||||
undefined,
|
undefined,
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
jasmine.any(HttpHeaders)
|
expect.any(HttpHeaders)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls url service with custom token params', waitForAsync(() => {
|
it('calls url service with custom token params', async () => {
|
||||||
const urlServiceSpy = spyOn(
|
const urlServiceSpy = vi.spyOn(
|
||||||
urlService,
|
urlService,
|
||||||
'createBodyForCodeFlowCodeRequest'
|
'createBodyForCodeFlowCodeRequest'
|
||||||
);
|
);
|
||||||
@@ -197,76 +206,84 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
customParamsCodeRequest: { foo: 'bar' },
|
customParamsCodeRequest: { foo: 'bar' },
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCodeRequest({ code: 'foo' } as CallbackContext, config)
|
.codeFlowCodeRequest({ code: 'foo' } as CallbackContext, config)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(urlServiceSpy).toHaveBeenCalledOnceWith('foo', config, {
|
expect(urlServiceSpy).toHaveBeenCalledExactlyOnceWith('foo', config, {
|
||||||
foo: 'bar',
|
foo: 'bar',
|
||||||
});
|
});
|
||||||
expect(postSpy).toHaveBeenCalledTimes(1);
|
expect(postSpy).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls dataService with correct headers if all params are good', waitForAsync(() => {
|
it('calls dataService with correct headers if all params are good', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
customParamsCodeRequest: { foo: 'bar' },
|
customParamsCodeRequest: { foo: 'bar' },
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
service
|
service
|
||||||
.codeFlowCodeRequest({} as CallbackContext, config)
|
.codeFlowCodeRequest({} as CallbackContext, config)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
||||||
|
|
||||||
expect(httpHeaders.has('Content-Type')).toBeTrue();
|
expect(httpHeaders.has('Content-Type')).toBeTruthy();
|
||||||
expect(httpHeaders.get('Content-Type')).toBe(
|
expect(httpHeaders.get('Content-Type')).toBe(
|
||||||
'application/x-www-form-urlencoded'
|
'application/x-www-form-urlencoded'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns error in case of http error', waitForAsync(() => {
|
it('returns error in case of http error', async () => {
|
||||||
spyOn(dataService, 'post').and.returnValue(throwError(() => HTTP_ERROR));
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
|
throwError(() => HTTP_ERROR)
|
||||||
|
);
|
||||||
const config = {
|
const config = {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
customParamsCodeRequest: { foo: 'bar' },
|
customParamsCodeRequest: { foo: 'bar' },
|
||||||
authority: 'authority',
|
authority: 'authority',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('retries request in case of no connection http error and succeeds', waitForAsync(() => {
|
it('retries request in case of no connection http error and succeeds', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => CONNECTION_ERROR),
|
throwError(() => CONNECTION_ERROR),
|
||||||
of({})
|
of({})
|
||||||
@@ -278,14 +295,16 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
authority: 'authority',
|
authority: 'authority',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
||||||
next: (res) => {
|
next: (res) => {
|
||||||
@@ -297,10 +316,10 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('retries request in case of no connection http error and fails because of http error afterwards', waitForAsync(() => {
|
it('retries request in case of no connection http error and fails because of http error afterwards', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => CONNECTION_ERROR),
|
throwError(() => CONNECTION_ERROR),
|
||||||
throwError(() => HTTP_ERROR)
|
throwError(() => HTTP_ERROR)
|
||||||
@@ -312,14 +331,16 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
authority: 'authority',
|
authority: 'authority',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
tokenValidationService,
|
tokenValidationService,
|
||||||
'validateStateFromHashCallback'
|
'validateStateFromHashCallback'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
||||||
next: (res) => {
|
next: (res) => {
|
||||||
@@ -331,6 +352,6 @@ describe('CodeFlowCallbackHandlerService', () => {
|
|||||||
expect(postSpy).toHaveBeenCalledTimes(1);
|
expect(postSpy).toHaveBeenCalledTimes(1);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@ngify/http';
|
||||||
import { isNetworkError } from './error-helper';
|
import { isNetworkError } from './error-helper';
|
||||||
|
|
||||||
describe('error helper', () => {
|
describe('error helper', () => {
|
||||||
@@ -27,31 +27,31 @@ describe('error helper', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns true on http error with status = 0', () => {
|
it('returns true on http error with status = 0', () => {
|
||||||
expect(isNetworkError(CONNECTION_ERROR)).toBeTrue();
|
expect(isNetworkError(CONNECTION_ERROR)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true on http error with status = 0 and unknown error', () => {
|
it('returns true on http error with status = 0 and unknown error', () => {
|
||||||
expect(isNetworkError(UNKNOWN_CONNECTION_ERROR)).toBeTrue();
|
expect(isNetworkError(UNKNOWN_CONNECTION_ERROR)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true on http error with status <> 0 and error ProgressEvent', () => {
|
it('returns true on http error with status <> 0 and error ProgressEvent', () => {
|
||||||
expect(isNetworkError(PARTIAL_CONNECTION_ERROR)).toBeTrue();
|
expect(isNetworkError(PARTIAL_CONNECTION_ERROR)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false on non http error', () => {
|
it('returns false on non http error', () => {
|
||||||
expect(isNetworkError(new Error('not a HttpErrorResponse'))).toBeFalse();
|
expect(isNetworkError(new Error('not a HttpErrorResponse'))).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false on string error', () => {
|
it('returns false on string error', () => {
|
||||||
expect(isNetworkError('not a HttpErrorResponse')).toBeFalse();
|
expect(isNetworkError('not a HttpErrorResponse')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false on undefined', () => {
|
it('returns false on undefined', () => {
|
||||||
expect(isNetworkError(undefined)).toBeFalse();
|
expect(isNetworkError(undefined)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false on empty http error', () => {
|
it('returns false on empty http error', () => {
|
||||||
expect(isNetworkError(HTTP_ERROR)).toBeFalse();
|
expect(isNetworkError(HTTP_ERROR)).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
import { JwtKey, JwtKeys } from '../../validation/jwtkeys';
|
import { mockProvider } from '../../testing/mock';
|
||||||
|
import type { JwtKey, JwtKeys } from '../../validation/jwtkeys';
|
||||||
import { ValidationResult } from '../../validation/validation-result';
|
import { ValidationResult } from '../../validation/validation-result';
|
||||||
import { AuthResult, CallbackContext } from '../callback-context';
|
import type { AuthResult, CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
import { SigninKeyDataService } from '../signin-key-data.service';
|
import { SigninKeyDataService } from '../signin-key-data.service';
|
||||||
@@ -46,9 +47,6 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
mockProvider(ResetAuthDataService),
|
mockProvider(ResetAuthDataService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = TestBed.inject(HistoryJwtKeysCallbackHandlerService);
|
service = TestBed.inject(HistoryJwtKeysCallbackHandlerService);
|
||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
resetAuthDataService = TestBed.inject(ResetAuthDataService);
|
resetAuthDataService = TestBed.inject(ResetAuthDataService);
|
||||||
@@ -62,8 +60,8 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('callbackHistoryAndResetJwtKeys', () => {
|
describe('callbackHistoryAndResetJwtKeys', () => {
|
||||||
it('writes authResult into the storage', waitForAsync(() => {
|
it('writes authResult into the storage', async () => {
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
@@ -75,86 +73,86 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of({ keys: [] } as JwtKeys)
|
of({ keys: [] } as JwtKeys)
|
||||||
);
|
);
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||||
['jwtKeys', { keys: [] }, allconfigs[0]],
|
['jwtKeys', { keys: [] }, allConfigs[0]],
|
||||||
]);
|
]);
|
||||||
// write authnResult & jwtKeys
|
// write authnResult & jwtKeys
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('writes refresh_token into the storage without reuse (refresh token rotation)', waitForAsync(() => {
|
it('writes refresh_token into the storage without reuse (refresh token rotation)', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
refresh_token: 'dummy_refresh_token',
|
refresh_token: 'dummy_refresh_token',
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
|
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of({ keys: [] } as JwtKeys)
|
of({ keys: [] } as JwtKeys)
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||||
['jwtKeys', { keys: [] }, allconfigs[0]],
|
['jwtKeys', { keys: [] }, allConfigs[0]],
|
||||||
]);
|
]);
|
||||||
// write authnResult & refresh_token & jwtKeys
|
// write authnResult & refresh_token & jwtKeys
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('writes refresh_token into the storage with reuse (without refresh token rotation)', waitForAsync(() => {
|
it('writes refresh_token into the storage with reuse (without refresh token rotation)', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
refresh_token: 'dummy_refresh_token',
|
refresh_token: 'dummy_refresh_token',
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
|
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
@@ -162,27 +160,27 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of({ keys: [] } as JwtKeys)
|
of({ keys: [] } as JwtKeys)
|
||||||
);
|
);
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||||
['reusable_refresh_token', 'dummy_refresh_token', allconfigs[0]],
|
['reusable_refresh_token', 'dummy_refresh_token', allConfigs[0]],
|
||||||
['jwtKeys', { keys: [] }, allconfigs[0]],
|
['jwtKeys', { keys: [] }, allConfigs[0]],
|
||||||
]);
|
]);
|
||||||
// write authnResult & refresh_token & jwtKeys
|
// write authnResult & refresh_token & jwtKeys
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(3);
|
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(3);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('resetBrowserHistory if historyCleanup is turned on and is not in a renewProcess', waitForAsync(() => {
|
it('resetBrowserHistory if historyCleanup is turned on and is not in a renewProcess', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
@@ -190,30 +188,30 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: false,
|
historyCleanupOff: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const windowSpy = spyOn(window.history, 'replaceState');
|
const windowSpy = vi.spyOn(window.history, 'replaceState');
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of({ keys: [] } as JwtKeys)
|
of({ keys: [] } as JwtKeys)
|
||||||
);
|
);
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(windowSpy).toHaveBeenCalledTimes(1);
|
expect(windowSpy).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns callbackContext with jwtkeys filled if everything works fine', waitForAsync(() => {
|
it('returns callbackContext with jwtkeys filled if everything works fine', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
@@ -222,21 +220,21 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: false,
|
historyCleanupOff: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of({ keys: [{ kty: 'henlo' } as JwtKey] } as JwtKeys)
|
of({ keys: [{ kty: 'henlo' } as JwtKey] } as JwtKeys)
|
||||||
);
|
);
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
@@ -245,9 +243,9 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
jwtKeys: { keys: [{ kty: 'henlo' }] },
|
jwtKeys: { keys: [{ kty: 'henlo' }] },
|
||||||
} as CallbackContext);
|
} as CallbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns error if no jwtKeys have been in the call --> keys are null', waitForAsync(() => {
|
it('returns error if no jwtKeys have been in the call --> keys are null', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
@@ -256,32 +254,32 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: false,
|
historyCleanupOff: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of({} as JwtKeys)
|
of({} as JwtKeys)
|
||||||
);
|
);
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err.message).toEqual(
|
expect(err.message).toEqual(
|
||||||
`Failed to retrieve signing key with error: Error: Failed to retrieve signing key`
|
'Failed to retrieve signing key with error: Error: Failed to retrieve signing key'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns error if no jwtKeys have been in the call --> keys throw an error', waitForAsync(() => {
|
it('returns error if no jwtKeys have been in the call --> keys throw an error', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
@@ -289,36 +287,36 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: false,
|
historyCleanupOff: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
throwError(() => new Error('error'))
|
throwError(() => new Error('error'))
|
||||||
);
|
);
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err.message).toEqual(
|
expect(err.message).toEqual(
|
||||||
`Failed to retrieve signing key with error: Error: Error: error`
|
'Failed to retrieve signing key with error: Error: Error: error'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns error if callbackContext.authresult has an error property filled', waitForAsync(() => {
|
it('returns error if callbackContext.authresult has an error property filled', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
authResult: { error: 'someError' },
|
authResult: { error: 'someError' },
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
@@ -328,36 +326,36 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err.message).toEqual(
|
expect(err.message).toEqual(
|
||||||
`AuthCallback AuthResult came with error: someError`
|
'AuthCallback AuthResult came with error: someError'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls resetAuthorizationData, resets nonce and authStateService in case of an error', waitForAsync(() => {
|
it('calls resetAuthorizationData, resets nonce and authStateService in case of an error', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
authResult: { error: 'someError' },
|
authResult: { error: 'someError' },
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const setNonceSpy = spyOn(flowsDataService, 'setNonce');
|
const setNonceSpy = vi.spyOn(flowsDataService, 'setNonce');
|
||||||
const updateAndPublishAuthStateSpy = spyOn(
|
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
@@ -365,40 +363,42 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(setNonceSpy).toHaveBeenCalledTimes(1);
|
expect(setNonceSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
expect(
|
||||||
|
updateAndPublishAuthStateSpy
|
||||||
|
).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
validationResult: ValidationResult.SecureTokenServerError,
|
validationResult: ValidationResult.SecureTokenServerError,
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authStateService.updateAndPublishAuthState with login required if the error is `login_required`', waitForAsync(() => {
|
it('calls authStateService.updateAndPublishAuthState with login required if the error is `login_required`', async () => {
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
authResult: { error: 'login_required' },
|
authResult: { error: 'login_required' },
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const setNonceSpy = spyOn(flowsDataService, 'setNonce');
|
const setNonceSpy = vi.spyOn(flowsDataService, 'setNonce');
|
||||||
const updateAndPublishAuthStateSpy = spyOn(
|
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
@@ -406,23 +406,25 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
callbackContext,
|
callbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(setNonceSpy).toHaveBeenCalledTimes(1);
|
expect(setNonceSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
expect(
|
||||||
|
updateAndPublishAuthStateSpy
|
||||||
|
).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
validationResult: ValidationResult.LoginRequired,
|
validationResult: ValidationResult.LoginRequired,
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should store jwtKeys', waitForAsync(() => {
|
it('should store jwtKeys', async () => {
|
||||||
const DUMMY_AUTH_RESULT = {
|
const DUMMY_AUTH_RESULT = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
};
|
};
|
||||||
@@ -430,33 +432,33 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
const initialCallbackContext = {
|
const initialCallbackContext = {
|
||||||
authResult: DUMMY_AUTH_RESULT,
|
authResult: DUMMY_AUTH_RESULT,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
of(DUMMY_JWT_KEYS)
|
of(DUMMY_JWT_KEYS)
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
initialCallbackContext,
|
initialCallbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (callbackContext: CallbackContext) => {
|
next: (callbackContext: CallbackContext) => {
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
||||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||||
['jwtKeys', DUMMY_JWT_KEYS, allconfigs[0]],
|
['jwtKeys', DUMMY_JWT_KEYS, allConfigs[0]],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(callbackContext.jwtKeys).toEqual(DUMMY_JWT_KEYS);
|
expect(callbackContext.jwtKeys).toEqual(DUMMY_JWT_KEYS);
|
||||||
@@ -465,9 +467,9 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not store jwtKeys on error', waitForAsync(() => {
|
it('should not store jwtKeys on error', async () => {
|
||||||
const authResult = {
|
const authResult = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
access_token: 'some-access-token',
|
access_token: 'some-access-token',
|
||||||
@@ -476,26 +478,26 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
authResult,
|
authResult,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
|
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
initialCallbackContext,
|
initialCallbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (callbackContext: CallbackContext) => {
|
next: (callbackContext: CallbackContext) => {
|
||||||
@@ -505,16 +507,18 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
|
|
||||||
// storagePersistenceService.write() should not have been called with jwtKeys
|
// storagePersistenceService.write() should not have been called with jwtKeys
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledOnceWith(
|
expect(
|
||||||
|
storagePersistenceServiceSpy
|
||||||
|
).toHaveBeenCalledExactlyOnceWith(
|
||||||
'authnResult',
|
'authnResult',
|
||||||
authResult,
|
authResult,
|
||||||
allconfigs[0]
|
allConfigs[0]
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should fallback to stored jwtKeys on error', waitForAsync(() => {
|
it('should fallback to stored jwtKeys on error', async () => {
|
||||||
const authResult = {
|
const authResult = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
access_token: 'some-access-token',
|
access_token: 'some-access-token',
|
||||||
@@ -523,66 +527,65 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
authResult,
|
authResult,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
|
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'read'
|
'read'
|
||||||
);
|
);
|
||||||
|
|
||||||
storagePersistenceServiceSpy.and.returnValue(DUMMY_JWT_KEYS);
|
storagePersistenceServiceSpy.mockReturnValue(DUMMY_JWT_KEYS);
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
initialCallbackContext,
|
initialCallbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (callbackContext: CallbackContext) => {
|
next: (callbackContext: CallbackContext) => {
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledOnceWith(
|
expect(
|
||||||
'jwtKeys',
|
storagePersistenceServiceSpy
|
||||||
allconfigs[0]
|
).toHaveBeenCalledExactlyOnceWith('jwtKeys', allConfigs[0]);
|
||||||
);
|
|
||||||
expect(callbackContext.jwtKeys).toEqual(DUMMY_JWT_KEYS);
|
expect(callbackContext.jwtKeys).toEqual(DUMMY_JWT_KEYS);
|
||||||
},
|
},
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should throw error if no jwtKeys are stored', waitForAsync(() => {
|
it('should throw error if no jwtKeys are stored', async () => {
|
||||||
const authResult = {
|
const authResult = {
|
||||||
id_token: 'some-id-token',
|
id_token: 'some-id-token',
|
||||||
access_token: 'some-access-token',
|
access_token: 'some-access-token',
|
||||||
} as AuthResult;
|
} as AuthResult;
|
||||||
|
|
||||||
const initialCallbackContext = { authResult } as CallbackContext;
|
const initialCallbackContext = { authResult } as CallbackContext;
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
historyCleanupOff: true,
|
historyCleanupOff: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue(null);
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue(null);
|
||||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackHistoryAndResetJwtKeys(
|
.callbackHistoryAndResetJwtKeys(
|
||||||
initialCallbackContext,
|
initialCallbackContext,
|
||||||
allconfigs[0],
|
allConfigs[0]!,
|
||||||
allconfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (callbackContext: CallbackContext) => {
|
next: (callbackContext: CallbackContext) => {
|
||||||
@@ -592,7 +595,7 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('historyCleanUpTurnedOn ', () => {
|
describe('historyCleanUpTurnedOn ', () => {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { DOCUMENT } from '../../dom';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { inject, Injectable } from 'injection-js';
|
import { type Observable, of, throwError } from 'rxjs';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
|
||||||
import { catchError, switchMap, tap } from 'rxjs/operators';
|
import { catchError, switchMap, tap } from 'rxjs/operators';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
|
import { DOCUMENT } from '../../dom';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
import { JwtKeys } from '../../validation/jwtkeys';
|
import type { JwtKeys } from '../../validation/jwtkeys';
|
||||||
import { ValidationResult } from '../../validation/validation-result';
|
import { ValidationResult } from '../../validation/validation-result';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
import { SigninKeyDataService } from '../signin-key-data.service';
|
import { SigninKeyDataService } from '../signin-key-data.service';
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import { TestBed } from '@/testing';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { DOCUMENT } from '../../dom';
|
import { DOCUMENT } from '../../dom';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { CallbackContext } from '../callback-context';
|
import { mockProvider } from '../../testing/mock';
|
||||||
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
import { ImplicitFlowCallbackHandlerService } from './implicit-flow-callback-handler.service';
|
import { ImplicitFlowCallbackHandlerService } from './implicit-flow-callback-handler.service';
|
||||||
@@ -34,9 +35,6 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = TestBed.inject(ImplicitFlowCallbackHandlerService);
|
service = TestBed.inject(ImplicitFlowCallbackHandlerService);
|
||||||
flowsDataService = TestBed.inject(FlowsDataService);
|
flowsDataService = TestBed.inject(FlowsDataService);
|
||||||
resetAuthDataService = TestBed.inject(ResetAuthDataService);
|
resetAuthDataService = TestBed.inject(ResetAuthDataService);
|
||||||
@@ -47,46 +45,46 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('implicitFlowCallback', () => {
|
describe('implicitFlowCallback', () => {
|
||||||
it('calls "resetAuthorizationData" if silent renew is not running', waitForAsync(() => {
|
it('calls "resetAuthorizationData" if silent renew is not running', async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.implicitFlowCallback(allconfigs[0], allconfigs, 'any-hash')
|
.implicitFlowCallback(allConfigs[0]!, allConfigs, 'any-hash')
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalled();
|
expect(resetAuthorizationDataSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('does NOT calls "resetAuthorizationData" if silent renew is running', waitForAsync(() => {
|
it('does NOT calls "resetAuthorizationData" if silent renew is running', async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.implicitFlowCallback(allconfigs[0], allconfigs, 'any-hash')
|
.implicitFlowCallback(allConfigs[0]!, allConfigs, 'any-hash')
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(resetAuthorizationDataSpy).not.toHaveBeenCalled();
|
expect(resetAuthorizationDataSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns callbackContext if all params are good', waitForAsync(() => {
|
it('returns callbackContext if all params are good', async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
const expectedCallbackContext = {
|
const expectedCallbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -99,21 +97,21 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
|||||||
existingIdToken: null,
|
existingIdToken: null,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
|
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.implicitFlowCallback(allconfigs[0], allconfigs, 'anyHash')
|
.implicitFlowCallback(allConfigs[0]!, allConfigs, 'anyHash')
|
||||||
.subscribe((callbackContext) => {
|
.subscribe((callbackContext) => {
|
||||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('uses window location hash if no hash is passed', waitForAsync(() => {
|
it('uses window location hash if no hash is passed', async () => {
|
||||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||||
const expectedCallbackContext = {
|
const expectedCallbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -126,17 +124,17 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
|||||||
existingIdToken: null,
|
existingIdToken: null,
|
||||||
} as CallbackContext;
|
} as CallbackContext;
|
||||||
|
|
||||||
const allconfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.implicitFlowCallback(allconfigs[0], allconfigs)
|
.implicitFlowCallback(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((callbackContext) => {
|
.subscribe((callbackContext) => {
|
||||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { Injectable, inject } from 'injection-js';
|
||||||
|
import { type Observable, of } from 'rxjs';
|
||||||
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
import { DOCUMENT } from '../../dom';
|
import { DOCUMENT } from '../../dom';
|
||||||
import { inject, Injectable } from 'injection-js';
|
|
||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { AuthResult, CallbackContext } from '../callback-context';
|
import type { AuthResult, CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { CallbackContext } from '../callback-context';
|
import { mockProvider } from '../../testing/mock';
|
||||||
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { RefreshSessionCallbackHandlerService } from './refresh-session-callback-handler.service';
|
import { RefreshSessionCallbackHandlerService } from './refresh-session-callback-handler.service';
|
||||||
|
|
||||||
@@ -33,15 +34,15 @@ describe('RefreshSessionCallbackHandlerService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('refreshSessionWithRefreshTokens', () => {
|
describe('refreshSessionWithRefreshTokens', () => {
|
||||||
it('returns callbackContext if all params are good', waitForAsync(() => {
|
it('returns callbackContext if all params are good', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'getExistingOrCreateAuthStateControl'
|
'getExistingOrCreateAuthStateControl'
|
||||||
).and.returnValue('state-data');
|
).mockReturnValue('state-data');
|
||||||
spyOn(authStateService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(authStateService, 'getRefreshToken').mockReturnValue(
|
||||||
'henlo-furiend'
|
'henlo-furiend'
|
||||||
);
|
);
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('henlo-legger');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('henlo-legger');
|
||||||
|
|
||||||
const expectedCallbackContext = {
|
const expectedCallbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
@@ -60,15 +61,15 @@ describe('RefreshSessionCallbackHandlerService', () => {
|
|||||||
.subscribe((callbackContext) => {
|
.subscribe((callbackContext) => {
|
||||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if no refresh token is given', waitForAsync(() => {
|
it('throws error if no refresh token is given', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'getExistingOrCreateAuthStateControl'
|
'getExistingOrCreateAuthStateControl'
|
||||||
).and.returnValue('state-data');
|
).mockReturnValue('state-data');
|
||||||
spyOn(authStateService, 'getRefreshToken').and.returnValue('');
|
vi.spyOn(authStateService, 'getRefreshToken').mockReturnValue('');
|
||||||
spyOn(authStateService, 'getIdToken').and.returnValue('henlo-legger');
|
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('henlo-legger');
|
||||||
|
|
||||||
service
|
service
|
||||||
.refreshSessionWithRefreshTokens({ configId: 'configId1' })
|
.refreshSessionWithRefreshTokens({ configId: 'configId1' })
|
||||||
@@ -77,6 +78,6 @@ describe('RefreshSessionCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { HttpErrorResponse, HttpHeaders } from '@ngify/http';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { createRetriableStream } from '../../../test/create-retriable-stream.helper';
|
|
||||||
import { DataService } from '../../api/data.service';
|
import { DataService } from '../../api/data.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
|
import { createRetriableStream } from '../../testing/create-retriable-stream.helper';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { RefreshTokenCallbackHandlerService } from './refresh-token-callback-handler.service';
|
import { RefreshTokenCallbackHandlerService } from './refresh-token-callback-handler.service';
|
||||||
|
|
||||||
describe('RefreshTokenCallbackHandlerService', () => {
|
describe('RefreshTokenCallbackHandlerService', () => {
|
||||||
@@ -46,7 +47,7 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
url: 'https://identity-server.test/openid-connect/token',
|
url: 'https://identity-server.test/openid-connect/token',
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws error if no tokenEndpoint is given', waitForAsync(() => {
|
it('throws error if no tokenEndpoint is given', async () => {
|
||||||
(service as any)
|
(service as any)
|
||||||
.refreshTokensRequestTokens({} as CallbackContext)
|
.refreshTokensRequestTokens({} as CallbackContext)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
@@ -54,41 +55,45 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls data service if all params are good', waitForAsync(() => {
|
it('calls data service if all params are good', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.refreshTokensRequestTokens({} as CallbackContext, {
|
.refreshTokensRequestTokens({} as CallbackContext, {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
})
|
})
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(postSpy).toHaveBeenCalledOnceWith(
|
expect(postSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'tokenEndpoint',
|
'tokenEndpoint',
|
||||||
undefined,
|
undefined,
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
jasmine.any(HttpHeaders)
|
expect.any(HttpHeaders)
|
||||||
);
|
);
|
||||||
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
||||||
|
|
||||||
expect(httpHeaders.has('Content-Type')).toBeTrue();
|
expect(httpHeaders.has('Content-Type')).toBeTruthy();
|
||||||
expect(httpHeaders.get('Content-Type')).toBe(
|
expect(httpHeaders.get('Content-Type')).toBe(
|
||||||
'application/x-www-form-urlencoded'
|
'application/x-www-form-urlencoded'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls data service with correct headers if all params are good', waitForAsync(() => {
|
it('calls data service with correct headers if all params are good', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.refreshTokensRequestTokens({} as CallbackContext, {
|
.refreshTokensRequestTokens({} as CallbackContext, {
|
||||||
@@ -97,20 +102,24 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
||||||
|
|
||||||
expect(httpHeaders.has('Content-Type')).toBeTrue();
|
expect(httpHeaders.has('Content-Type')).toBeTruthy();
|
||||||
expect(httpHeaders.get('Content-Type')).toBe(
|
expect(httpHeaders.get('Content-Type')).toBe(
|
||||||
'application/x-www-form-urlencoded'
|
'application/x-www-form-urlencoded'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns error in case of http error', waitForAsync(() => {
|
it('returns error in case of http error', async () => {
|
||||||
spyOn(dataService, 'post').and.returnValue(throwError(() => HTTP_ERROR));
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
|
throwError(() => HTTP_ERROR)
|
||||||
|
);
|
||||||
const config = { configId: 'configId1', authority: 'authority' };
|
const config = { configId: 'configId1', authority: 'authority' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.refreshTokensRequestTokens({} as CallbackContext, config)
|
.refreshTokensRequestTokens({} as CallbackContext, config)
|
||||||
@@ -119,10 +128,10 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('retries request in case of no connection http error and succeeds', waitForAsync(() => {
|
it('retries request in case of no connection http error and succeeds', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => CONNECTION_ERROR),
|
throwError(() => CONNECTION_ERROR),
|
||||||
of({})
|
of({})
|
||||||
@@ -130,9 +139,11 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
);
|
);
|
||||||
const config = { configId: 'configId1', authority: 'authority' };
|
const config = { configId: 'configId1', authority: 'authority' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.refreshTokensRequestTokens({} as CallbackContext, config)
|
.refreshTokensRequestTokens({} as CallbackContext, config)
|
||||||
@@ -146,10 +157,10 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('retries request in case of no connection http error and fails because of http error afterwards', waitForAsync(() => {
|
it('retries request in case of no connection http error and fails because of http error afterwards', async () => {
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => CONNECTION_ERROR),
|
throwError(() => CONNECTION_ERROR),
|
||||||
throwError(() => HTTP_ERROR)
|
throwError(() => HTTP_ERROR)
|
||||||
@@ -157,9 +168,11 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
);
|
);
|
||||||
const config = { configId: 'configId1', authority: 'authority' };
|
const config = { configId: 'configId1', authority: 'authority' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.refreshTokensRequestTokens({} as CallbackContext, config)
|
.refreshTokensRequestTokens({} as CallbackContext, config)
|
||||||
@@ -173,6 +186,6 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
|||||||
expect(postSpy).toHaveBeenCalledTimes(1);
|
expect(postSpy).toHaveBeenCalledTimes(1);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { DOCUMENT } from '../../dom';
|
import { TestBed } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
|
import { DOCUMENT } from '../../dom';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StateValidationResult } from '../../validation/state-validation-result';
|
import { mockProvider } from '../../testing/mock';
|
||||||
|
import type { StateValidationResult } from '../../validation/state-validation-result';
|
||||||
import { StateValidationService } from '../../validation/state-validation.service';
|
import { StateValidationService } from '../../validation/state-validation.service';
|
||||||
import { ValidationResult } from '../../validation/validation-result';
|
import { ValidationResult } from '../../validation/validation-result';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
import { StateValidationCallbackHandlerService } from './state-validation-callback-handler.service';
|
import { StateValidationCallbackHandlerService } from './state-validation-callback-handler.service';
|
||||||
|
|
||||||
@@ -56,8 +57,11 @@ describe('StateValidationCallbackHandlerService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('callbackStateValidation', () => {
|
describe('callbackStateValidation', () => {
|
||||||
it('returns callbackContext with validationResult if validationResult is valid', waitForAsync(() => {
|
it('returns callbackContext with validationResult if validationResult is valid', async () => {
|
||||||
spyOn(stateValidationService, 'getValidatedStateResult').and.returnValue(
|
vi.spyOn(
|
||||||
|
stateValidationService,
|
||||||
|
'getValidatedStateResult'
|
||||||
|
).mockReturnValue(
|
||||||
of({
|
of({
|
||||||
idToken: 'idTokenJustForTesting',
|
idToken: 'idTokenJustForTesting',
|
||||||
authResponseIsValid: true,
|
authResponseIsValid: true,
|
||||||
@@ -68,7 +72,7 @@ describe('StateValidationCallbackHandlerService', () => {
|
|||||||
service
|
service
|
||||||
.callbackStateValidation(
|
.callbackStateValidation(
|
||||||
{} as CallbackContext,
|
{} as CallbackContext,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe((newCallbackContext) => {
|
.subscribe((newCallbackContext) => {
|
||||||
@@ -79,47 +83,53 @@ describe('StateValidationCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
} as CallbackContext);
|
} as CallbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error in case of an error', waitForAsync(() => {
|
it('logs error in case of an error', async () => {
|
||||||
spyOn(stateValidationService, 'getValidatedStateResult').and.returnValue(
|
vi.spyOn(
|
||||||
|
stateValidationService,
|
||||||
|
'getValidatedStateResult'
|
||||||
|
).mockReturnValue(
|
||||||
of({
|
of({
|
||||||
authResponseIsValid: false,
|
authResponseIsValid: false,
|
||||||
} as StateValidationResult)
|
} as StateValidationResult)
|
||||||
);
|
);
|
||||||
|
|
||||||
const loggerSpy = spyOn(loggerService, 'logWarning');
|
const loggerSpy = vi.spyOn(loggerService, 'logWarning');
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackStateValidation(
|
.callbackStateValidation(
|
||||||
{} as CallbackContext,
|
{} as CallbackContext,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(loggerSpy).toHaveBeenCalledOnceWith(
|
expect(loggerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
'authorizedCallback, token(s) validation failed, resetting. Hash: &anyFakeHash'
|
'authorizedCallback, token(s) validation failed, resetting. Hash: &anyFakeHash'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls resetAuthDataService.resetAuthorizationData and authStateService.updateAndPublishAuthState in case of an error', waitForAsync(() => {
|
it('calls resetAuthDataService.resetAuthorizationData and authStateService.updateAndPublishAuthState in case of an error', async () => {
|
||||||
spyOn(stateValidationService, 'getValidatedStateResult').and.returnValue(
|
vi.spyOn(
|
||||||
|
stateValidationService,
|
||||||
|
'getValidatedStateResult'
|
||||||
|
).mockReturnValue(
|
||||||
of({
|
of({
|
||||||
authResponseIsValid: false,
|
authResponseIsValid: false,
|
||||||
state: ValidationResult.LoginRequired,
|
state: ValidationResult.LoginRequired,
|
||||||
} as StateValidationResult)
|
} as StateValidationResult)
|
||||||
);
|
);
|
||||||
|
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const updateAndPublishAuthStateSpy = spyOn(
|
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
@@ -128,19 +138,21 @@ describe('StateValidationCallbackHandlerService', () => {
|
|||||||
service
|
service
|
||||||
.callbackStateValidation(
|
.callbackStateValidation(
|
||||||
{ isRenewProcess: true } as CallbackContext,
|
{ isRenewProcess: true } as CallbackContext,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
expect(
|
||||||
|
updateAndPublishAuthStateSpy
|
||||||
|
).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
validationResult: ValidationResult.LoginRequired,
|
validationResult: ValidationResult.LoginRequired,
|
||||||
isRenewProcess: true,
|
isRenewProcess: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { DOCUMENT } from '../../dom';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { inject, Injectable } from 'injection-js';
|
import type { Observable } from 'rxjs';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
|
import { DOCUMENT } from '../../dom';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StateValidationResult } from '../../validation/state-validation-result';
|
import type { StateValidationResult } from '../../validation/state-validation-result';
|
||||||
import { StateValidationService } from '../../validation/state-validation.service';
|
import { StateValidationService } from '../../validation/state-validation.service';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { UserService } from '../../user-data/user.service';
|
import { UserService } from '../../user-data/user.service';
|
||||||
import { StateValidationResult } from '../../validation/state-validation-result';
|
import { StateValidationResult } from '../../validation/state-validation-result';
|
||||||
import { ValidationResult } from '../../validation/validation-result';
|
import { ValidationResult } from '../../validation/validation-result';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
import { UserCallbackHandlerService } from './user-callback-handler.service';
|
import { UserCallbackHandlerService } from './user-callback-handler.service';
|
||||||
@@ -44,7 +45,7 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('callbackUser', () => {
|
describe('callbackUser', () => {
|
||||||
it('calls flowsDataService.setSessionState with correct params if autoUserInfo is false, isRenewProcess is false and refreshToken is null', waitForAsync(() => {
|
it('calls flowsDataService.setSessionState with correct params if autoUserInfo is false, isRenewProcess is false and refreshToken is null', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -70,17 +71,17 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith('mystate', allConfigs[0]);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('mystate', allConfigs[0]);
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('does NOT call flowsDataService.setSessionState if autoUserInfo is false, isRenewProcess is true and refreshToken is null', waitForAsync(() => {
|
it('does NOT call flowsDataService.setSessionState if autoUserInfo is false, isRenewProcess is true and refreshToken is null', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -104,17 +105,17 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
autoUserInfo: false,
|
autoUserInfo: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('does NOT call flowsDataService.setSessionState if autoUserInfo is false isRenewProcess is false, refreshToken has value', waitForAsync(() => {
|
it('does NOT call flowsDataService.setSessionState if autoUserInfo is false isRenewProcess is false, refreshToken has value', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -138,17 +139,17 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
autoUserInfo: false,
|
autoUserInfo: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('does NOT call flowsDataService.setSessionState if autoUserInfo is false isRenewProcess is false, refreshToken has value, id_token is false', waitForAsync(() => {
|
it('does NOT call flowsDataService.setSessionState if autoUserInfo is false isRenewProcess is false, refreshToken has value, id_token is false', async () => {
|
||||||
const svr = new StateValidationResult('accesstoken', '', true, '');
|
const svr = new StateValidationResult('accesstoken', '', true, '');
|
||||||
const callbackContext = {
|
const callbackContext = {
|
||||||
code: '',
|
code: '',
|
||||||
@@ -168,17 +169,17 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authStateService.updateAndPublishAuthState with correct params if autoUserInfo is false', waitForAsync(() => {
|
it('calls authStateService.updateAndPublishAuthState with correct params if autoUserInfo is false', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -204,24 +205,24 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const updateAndPublishAuthStateSpy = spyOn(
|
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: true,
|
isAuthenticated: true,
|
||||||
validationResult: ValidationResult.NotSet,
|
validationResult: ValidationResult.NotSet,
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
});
|
});
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls userService.getAndPersistUserDataInStore with correct params if autoUserInfo is true', waitForAsync(() => {
|
it('calls userService.getAndPersistUserDataInStore with correct params if autoUserInfo is true', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -247,16 +248,17 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const getAndPersistUserDataInStoreSpy = spyOn(
|
const getAndPersistUserDataInStoreSpy = vi
|
||||||
userService,
|
.spyOn(userService, 'getAndPersistUserDataInStore')
|
||||||
'getAndPersistUserDataInStore'
|
.mockReturnValue(of({ user: 'some_data' }));
|
||||||
).and.returnValue(of({ user: 'some_data' }));
|
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(getAndPersistUserDataInStoreSpy).toHaveBeenCalledOnceWith(
|
expect(
|
||||||
allConfigs[0],
|
getAndPersistUserDataInStoreSpy
|
||||||
|
).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
allConfigs[0]!,
|
||||||
allConfigs,
|
allConfigs,
|
||||||
false,
|
false,
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -264,9 +266,9 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
);
|
);
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authStateService.updateAndPublishAuthState with correct params if autoUserInfo is true', waitForAsync(() => {
|
it('calls authStateService.updateAndPublishAuthState with correct params if autoUserInfo is true', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -293,27 +295,27 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||||
of({ user: 'some_data' })
|
of({ user: 'some_data' })
|
||||||
);
|
);
|
||||||
const updateAndPublishAuthStateSpy = spyOn(
|
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: true,
|
isAuthenticated: true,
|
||||||
validationResult: ValidationResult.MaxOffsetExpired,
|
validationResult: ValidationResult.MaxOffsetExpired,
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
});
|
});
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls flowsDataService.setSessionState with correct params if user data is present and NOT refresh token', waitForAsync(() => {
|
it('calls flowsDataService.setSessionState with correct params if user data is present and NOT refresh token', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -340,23 +342,23 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||||
of({ user: 'some_data' })
|
of({ user: 'some_data' })
|
||||||
);
|
);
|
||||||
const setSessionStateSpy = spyOn(flowsDataService, 'setSessionState');
|
const setSessionStateSpy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe((resultCallbackContext) => {
|
.subscribe((resultCallbackContext) => {
|
||||||
expect(setSessionStateSpy).toHaveBeenCalledOnceWith(
|
expect(setSessionStateSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'mystate',
|
'mystate',
|
||||||
allConfigs[0]
|
allConfigs[0]
|
||||||
);
|
);
|
||||||
expect(resultCallbackContext).toEqual(callbackContext);
|
expect(resultCallbackContext).toEqual(callbackContext);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authStateService.publishUnauthorizedState with correct params if user info which are coming back are null', waitForAsync(() => {
|
it('calls authStateService.publishUnauthorizedState with correct params if user info which are coming back are null', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -383,19 +385,21 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||||
of(null)
|
of(null)
|
||||||
);
|
);
|
||||||
const updateAndPublishAuthStateSpy = spyOn(
|
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
expect(
|
||||||
|
updateAndPublishAuthStateSpy
|
||||||
|
).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
validationResult: ValidationResult.MaxOffsetExpired,
|
validationResult: ValidationResult.MaxOffsetExpired,
|
||||||
isRenewProcess: false,
|
isRenewProcess: false,
|
||||||
@@ -405,9 +409,9 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls resetAuthDataService.resetAuthorizationData if user info which are coming back are null', waitForAsync(() => {
|
it('calls resetAuthDataService.resetAuthorizationData if user info which are coming back are null', async () => {
|
||||||
const svr = new StateValidationResult(
|
const svr = new StateValidationResult(
|
||||||
'accesstoken',
|
'accesstoken',
|
||||||
'idtoken',
|
'idtoken',
|
||||||
@@ -434,16 +438,16 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||||
of(null)
|
of(null)
|
||||||
);
|
);
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
|
|
||||||
service
|
service
|
||||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||||
@@ -452,6 +456,6 @@ describe('UserCallbackHandlerService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { type Observable, of, throwError } from 'rxjs';
|
||||||
import { catchError, switchMap } from 'rxjs/operators';
|
import { catchError, switchMap } from 'rxjs/operators';
|
||||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { UserService } from '../../user-data/user.service';
|
import { UserService } from '../../user-data/user.service';
|
||||||
import { StateValidationResult } from '../../validation/state-validation-result';
|
import type { StateValidationResult } from '../../validation/state-validation-result';
|
||||||
import { CallbackContext } from '../callback-context';
|
import type { CallbackContext } from '../callback-context';
|
||||||
import { FlowsDataService } from '../flows-data.service';
|
import { FlowsDataService } from '../flows-data.service';
|
||||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { CryptoService } from '../utils/crypto/crypto.service';
|
import { CryptoService } from '../utils/crypto/crypto.service';
|
||||||
import { FlowsDataService } from './flows-data.service';
|
import { FlowsDataService } from './flows-data.service';
|
||||||
import { RandomService } from './random/random.service';
|
import { RandomService } from './random/random.service';
|
||||||
@@ -37,12 +38,12 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
describe('createNonce', () => {
|
describe('createNonce', () => {
|
||||||
it('createNonce returns nonce and stores it', () => {
|
it('createNonce returns nonce and stores it', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const result = service.createNonce({ configId: 'configId1' });
|
const result = service.createNonce({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeTruthy();
|
expect(result).toBeTruthy();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authNonce', result, {
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authNonce', result, {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -50,32 +51,38 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
describe('AuthStateControl', () => {
|
describe('AuthStateControl', () => {
|
||||||
it('getAuthStateControl returns property from store', () => {
|
it('getAuthStateControl returns property from store', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'read');
|
const spy = vi.spyOn(storagePersistenceService, 'read');
|
||||||
|
|
||||||
service.getAuthStateControl({ configId: 'configId1' });
|
service.getAuthStateControl({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authStateControl', {
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authStateControl', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('setAuthStateControl saves property in store', () => {
|
it('setAuthStateControl saves property in store', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
service.setAuthStateControl('ToSave', { configId: 'configId1' });
|
service.setAuthStateControl('ToSave', { configId: 'configId1' });
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authStateControl', 'ToSave', {
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
'authStateControl',
|
||||||
});
|
'ToSave',
|
||||||
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getExistingOrCreateAuthStateControl', () => {
|
describe('getExistingOrCreateAuthStateControl', () => {
|
||||||
it('if nothing stored it creates a 40 char one and saves the authStateControl', () => {
|
it('if nothing stored it creates a 40 char one and saves the authStateControl', () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authStateControl', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['authStateControl', { configId: 'configId1' }],
|
||||||
const setSpy = spyOn(storagePersistenceService, 'write');
|
() => null
|
||||||
|
);
|
||||||
|
const setSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const result = service.getExistingOrCreateAuthStateControl({
|
const result = service.getExistingOrCreateAuthStateControl({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -83,16 +90,22 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
expect(result).toBeTruthy();
|
expect(result).toBeTruthy();
|
||||||
expect(result.length).toBe(41);
|
expect(result.length).toBe(41);
|
||||||
expect(setSpy).toHaveBeenCalledOnceWith('authStateControl', result, {
|
expect(setSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
'authStateControl',
|
||||||
});
|
result,
|
||||||
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if stored it returns the value and does NOT Store the value again', () => {
|
it('if stored it returns the value and does NOT Store the value again', () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authStateControl', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue('someAuthStateControl');
|
['authStateControl', { configId: 'configId1' }],
|
||||||
const setSpy = spyOn(storagePersistenceService, 'write');
|
() => 'someAuthStateControl'
|
||||||
|
);
|
||||||
|
const setSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const result = service.getExistingOrCreateAuthStateControl({
|
const result = service.getExistingOrCreateAuthStateControl({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -106,11 +119,11 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
describe('setSessionState', () => {
|
describe('setSessionState', () => {
|
||||||
it('setSessionState saves the value in the storage', () => {
|
it('setSessionState saves the value in the storage', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
service.setSessionState('Genesis', { configId: 'configId1' });
|
service.setSessionState('Genesis', { configId: 'configId1' });
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('session_state', 'Genesis', {
|
expect(spy).toHaveBeenCalledExactlyOnceWith('session_state', 'Genesis', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -118,7 +131,7 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
describe('resetStorageFlowData', () => {
|
describe('resetStorageFlowData', () => {
|
||||||
it('resetStorageFlowData calls correct method on storagePersistenceService', () => {
|
it('resetStorageFlowData calls correct method on storagePersistenceService', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'resetStorageFlowData');
|
const spy = vi.spyOn(storagePersistenceService, 'resetStorageFlowData');
|
||||||
|
|
||||||
service.resetStorageFlowData({ configId: 'configId1' });
|
service.resetStorageFlowData({ configId: 'configId1' });
|
||||||
|
|
||||||
@@ -128,26 +141,27 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
describe('codeVerifier', () => {
|
describe('codeVerifier', () => {
|
||||||
it('getCodeVerifier returns value from the store', () => {
|
it('getCodeVerifier returns value from the store', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'read')
|
const spy = vi
|
||||||
|
.spyOn(storagePersistenceService, 'read')
|
||||||
.withArgs('codeVerifier', { configId: 'configId1' })
|
.withArgs('codeVerifier', { configId: 'configId1' })
|
||||||
.and.returnValue('Genesis');
|
.mockReturnValue('Genesis');
|
||||||
|
|
||||||
const result = service.getCodeVerifier({ configId: 'configId1' });
|
const result = service.getCodeVerifier({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBe('Genesis');
|
expect(result).toBe('Genesis');
|
||||||
expect(spy).toHaveBeenCalledOnceWith('codeVerifier', {
|
expect(spy).toHaveBeenCalledExactlyOnceWith('codeVerifier', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('createCodeVerifier returns random createCodeVerifier and stores it', () => {
|
it('createCodeVerifier returns random createCodeVerifier and stores it', () => {
|
||||||
const setSpy = spyOn(storagePersistenceService, 'write');
|
const setSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const result = service.createCodeVerifier({ configId: 'configId1' });
|
const result = service.createCodeVerifier({ configId: 'configId1' });
|
||||||
|
|
||||||
expect(result).toBeTruthy();
|
expect(result).toBeTruthy();
|
||||||
expect(result.length).toBe(67);
|
expect(result.length).toBe(67);
|
||||||
expect(setSpy).toHaveBeenCalledOnceWith('codeVerifier', result, {
|
expect(setSpy).toHaveBeenCalledExactlyOnceWith('codeVerifier', result, {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -165,22 +179,26 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
jasmine.clock().mockDate(baseTime);
|
jasmine.clock().mockDate(baseTime);
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('storageCodeFlowInProgress', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(true);
|
['storageCodeFlowInProgress', config],
|
||||||
const spyWrite = spyOn(storagePersistenceService, 'write');
|
() => true
|
||||||
|
);
|
||||||
|
const spyWrite = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const isCodeFlowInProgressResult = service.isCodeFlowInProgress(config);
|
const isCodeFlowInProgressResult = service.isCodeFlowInProgress(config);
|
||||||
|
|
||||||
expect(spyWrite).not.toHaveBeenCalled();
|
expect(spyWrite).not.toHaveBeenCalled();
|
||||||
expect(isCodeFlowInProgressResult).toBeTrue();
|
expect(isCodeFlowInProgressResult).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('state object does not exist returns false result', () => {
|
it('state object does not exist returns false result', () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('storageCodeFlowInProgress', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['storageCodeFlowInProgress', { configId: 'configId1' }],
|
||||||
|
() => null
|
||||||
|
);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
const isCodeFlowInProgressResult = service.isCodeFlowInProgress({
|
const isCodeFlowInProgressResult = service.isCodeFlowInProgress({
|
||||||
@@ -188,7 +206,7 @@ describe('Flows Data Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(isCodeFlowInProgressResult).toBeFalse();
|
expect(isCodeFlowInProgressResult).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -200,23 +218,31 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
jasmine.clock().mockDate(baseTime);
|
jasmine.clock().mockDate(baseTime);
|
||||||
|
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
service.setCodeFlowInProgress({ configId: 'configId1' });
|
service.setCodeFlowInProgress({ configId: 'configId1' });
|
||||||
expect(spy).toHaveBeenCalledOnceWith('storageCodeFlowInProgress', true, {
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
'storageCodeFlowInProgress',
|
||||||
});
|
true,
|
||||||
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resetCodeFlowInProgress', () => {
|
describe('resetCodeFlowInProgress', () => {
|
||||||
it('set resetCodeFlowInProgress to false when called', () => {
|
it('set resetCodeFlowInProgress to false when called', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
service.resetCodeFlowInProgress({ configId: 'configId1' });
|
service.resetCodeFlowInProgress({ configId: 'configId1' });
|
||||||
expect(spy).toHaveBeenCalledOnceWith('storageCodeFlowInProgress', false, {
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
'storageCodeFlowInProgress',
|
||||||
});
|
false,
|
||||||
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -238,21 +264,21 @@ describe('Flows Data Service', () => {
|
|||||||
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
vi.spyOn(storagePersistenceService, 'read')
|
||||||
.withArgs('storageSilentRenewRunning', config)
|
.withArgs('storageSilentRenewRunning', config)
|
||||||
.and.returnValue(JSON.stringify(storageObject));
|
.mockReturnValue(JSON.stringify(storageObject));
|
||||||
const spyWrite = spyOn(storagePersistenceService, 'write');
|
const spyWrite = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
jasmine.clock().tick((config.silentRenewTimeoutInSeconds + 1) * 1000);
|
jasmine.clock().tick((config.silentRenewTimeoutInSeconds + 1) * 1000);
|
||||||
|
|
||||||
const isSilentRenewRunningResult = service.isSilentRenewRunning(config);
|
const isSilentRenewRunningResult = service.isSilentRenewRunning(config);
|
||||||
|
|
||||||
expect(spyWrite).toHaveBeenCalledOnceWith(
|
expect(spyWrite).toHaveBeenCalledExactlyOnceWith(
|
||||||
'storageSilentRenewRunning',
|
'storageSilentRenewRunning',
|
||||||
'',
|
'',
|
||||||
config
|
config
|
||||||
);
|
);
|
||||||
expect(isSilentRenewRunningResult).toBeFalse();
|
expect(isSilentRenewRunningResult).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('checks silent renew process and returns result', () => {
|
it('checks silent renew process and returns result', () => {
|
||||||
@@ -272,27 +298,29 @@ describe('Flows Data Service', () => {
|
|||||||
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
vi.spyOn(storagePersistenceService, 'read')
|
||||||
.withArgs('storageSilentRenewRunning', config)
|
.withArgs('storageSilentRenewRunning', config)
|
||||||
.and.returnValue(JSON.stringify(storageObject));
|
.mockReturnValue(JSON.stringify(storageObject));
|
||||||
const spyWrite = spyOn(storagePersistenceService, 'write');
|
const spyWrite = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
const isSilentRenewRunningResult = service.isSilentRenewRunning(config);
|
const isSilentRenewRunningResult = service.isSilentRenewRunning(config);
|
||||||
|
|
||||||
expect(spyWrite).not.toHaveBeenCalled();
|
expect(spyWrite).not.toHaveBeenCalled();
|
||||||
expect(isSilentRenewRunningResult).toBeTrue();
|
expect(isSilentRenewRunningResult).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('state object does not exist returns false result', () => {
|
it('state object does not exist returns false result', () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('storageSilentRenewRunning', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['storageSilentRenewRunning', { configId: 'configId1' }],
|
||||||
|
() => null
|
||||||
|
);
|
||||||
|
|
||||||
const isSilentRenewRunningResult = service.isSilentRenewRunning({
|
const isSilentRenewRunningResult = service.isSilentRenewRunning({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(isSilentRenewRunningResult).toBeFalse();
|
expect(isSilentRenewRunningResult).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -309,10 +337,10 @@ describe('Flows Data Service', () => {
|
|||||||
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
service.setSilentRenewRunning({ configId: 'configId1' });
|
service.setSilentRenewRunning({ configId: 'configId1' });
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'storageSilentRenewRunning',
|
'storageSilentRenewRunning',
|
||||||
JSON.stringify(storageObject),
|
JSON.stringify(storageObject),
|
||||||
{ configId: 'configId1' }
|
{ configId: 'configId1' }
|
||||||
@@ -322,12 +350,16 @@ describe('Flows Data Service', () => {
|
|||||||
|
|
||||||
describe('resetSilentRenewRunning', () => {
|
describe('resetSilentRenewRunning', () => {
|
||||||
it('set resetSilentRenewRunning to empty string when called', () => {
|
it('set resetSilentRenewRunning to empty string when called', () => {
|
||||||
const spy = spyOn(storagePersistenceService, 'write');
|
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||||
|
|
||||||
service.resetSilentRenewRunning({ configId: 'configId1' });
|
service.resetSilentRenewRunning({ configId: 'configId1' });
|
||||||
expect(spy).toHaveBeenCalledOnceWith('storageSilentRenewRunning', '', {
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
configId: 'configId1',
|
'storageSilentRenewRunning',
|
||||||
});
|
'',
|
||||||
|
{
|
||||||
|
configId: 'configId1',
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
import { SilentRenewRunning } from './flows.models';
|
import type { SilentRenewRunning } from './flows.models';
|
||||||
import { RandomService } from './random/random.service';
|
import { RandomService } from './random/random.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -18,7 +18,7 @@ export class FlowsDataService {
|
|||||||
createNonce(configuration: OpenIdConfiguration): string {
|
createNonce(configuration: OpenIdConfiguration): string {
|
||||||
const nonce = this.randomService.createRandom(40, configuration);
|
const nonce = this.randomService.createRandom(40, configuration);
|
||||||
|
|
||||||
this.loggerService.logDebug(configuration, 'Nonce created. nonce:' + nonce);
|
this.loggerService.logDebug(configuration, `Nonce created. nonce:${nonce}`);
|
||||||
this.setNonce(nonce, configuration);
|
this.setNonce(nonce, configuration);
|
||||||
|
|
||||||
return nonce;
|
return nonce;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CallbackContext } from './callback-context';
|
import { mockProvider } from '../testing/mock';
|
||||||
|
import type { CallbackContext } from './callback-context';
|
||||||
import { CodeFlowCallbackHandlerService } from './callback-handling/code-flow-callback-handler.service';
|
import { CodeFlowCallbackHandlerService } from './callback-handling/code-flow-callback-handler.service';
|
||||||
import { HistoryJwtKeysCallbackHandlerService } from './callback-handling/history-jwt-keys-callback-handler.service';
|
import { HistoryJwtKeysCallbackHandlerService } from './callback-handling/history-jwt-keys-callback-handler.service';
|
||||||
import { ImplicitFlowCallbackHandlerService } from './callback-handling/implicit-flow-callback-handler.service';
|
import { ImplicitFlowCallbackHandlerService } from './callback-handling/implicit-flow-callback-handler.service';
|
||||||
@@ -64,27 +65,25 @@ describe('Flows Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('processCodeFlowCallback', () => {
|
describe('processCodeFlowCallback', () => {
|
||||||
it('calls all methods correctly', waitForAsync(() => {
|
it('calls all methods correctly', async () => {
|
||||||
const codeFlowCallbackSpy = spyOn(
|
const codeFlowCallbackSpy = vi
|
||||||
codeFlowCallbackHandlerService,
|
.spyOn(codeFlowCallbackHandlerService, 'codeFlowCallback')
|
||||||
'codeFlowCallback'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
const codeFlowCodeRequestSpy = vi
|
||||||
const codeFlowCodeRequestSpy = spyOn(
|
.spyOn(codeFlowCallbackHandlerService, 'codeFlowCodeRequest')
|
||||||
codeFlowCallbackHandlerService,
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
'codeFlowCodeRequest'
|
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.spyOn(
|
||||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
historyJwtKeysCallbackHandlerService,
|
||||||
historyJwtKeysCallbackHandlerService,
|
'callbackHistoryAndResetJwtKeys'
|
||||||
'callbackHistoryAndResetJwtKeys'
|
)
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
const callbackStateValidationSpy = spyOn(
|
const callbackStateValidationSpy = vi
|
||||||
stateValidationCallbackHandlerService,
|
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||||
'callbackStateValidation'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
const callbackUserSpy = vi
|
||||||
const callbackUserSpy = spyOn(
|
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||||
userCallbackHandlerService,
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
'callbackUser'
|
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -92,10 +91,10 @@ describe('Flows Service', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.processCodeFlowCallback('some-url1234', allConfigs[0], allConfigs)
|
.processCodeFlowCallback('some-url1234', allConfigs[0]!, allConfigs)
|
||||||
.subscribe((value) => {
|
.subscribe((value) => {
|
||||||
expect(value).toEqual({} as CallbackContext);
|
expect(value).toEqual({} as CallbackContext);
|
||||||
expect(codeFlowCallbackSpy).toHaveBeenCalledOnceWith(
|
expect(codeFlowCallbackSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'some-url1234',
|
'some-url1234',
|
||||||
allConfigs[0]
|
allConfigs[0]
|
||||||
);
|
);
|
||||||
@@ -104,27 +103,26 @@ describe('Flows Service', () => {
|
|||||||
expect(callbackStateValidationSpy).toHaveBeenCalledTimes(1);
|
expect(callbackStateValidationSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(callbackUserSpy).toHaveBeenCalledTimes(1);
|
expect(callbackUserSpy).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processSilentRenewCodeFlowCallback', () => {
|
describe('processSilentRenewCodeFlowCallback', () => {
|
||||||
it('calls all methods correctly', waitForAsync(() => {
|
it('calls all methods correctly', async () => {
|
||||||
const codeFlowCodeRequestSpy = spyOn(
|
const codeFlowCodeRequestSpy = vi
|
||||||
codeFlowCallbackHandlerService,
|
.spyOn(codeFlowCallbackHandlerService, 'codeFlowCodeRequest')
|
||||||
'codeFlowCodeRequest'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
.spyOn(
|
||||||
historyJwtKeysCallbackHandlerService,
|
historyJwtKeysCallbackHandlerService,
|
||||||
'callbackHistoryAndResetJwtKeys'
|
'callbackHistoryAndResetJwtKeys'
|
||||||
).and.returnValue(of({} as CallbackContext));
|
)
|
||||||
const callbackStateValidationSpy = spyOn(
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
stateValidationCallbackHandlerService,
|
const callbackStateValidationSpy = vi
|
||||||
'callbackStateValidation'
|
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
const callbackUserSpy = spyOn(
|
const callbackUserSpy = vi
|
||||||
userCallbackHandlerService,
|
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||||
'callbackUser'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -134,7 +132,7 @@ describe('Flows Service', () => {
|
|||||||
service
|
service
|
||||||
.processSilentRenewCodeFlowCallback(
|
.processSilentRenewCodeFlowCallback(
|
||||||
{} as CallbackContext,
|
{} as CallbackContext,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
)
|
)
|
||||||
.subscribe((value) => {
|
.subscribe((value) => {
|
||||||
@@ -144,27 +142,26 @@ describe('Flows Service', () => {
|
|||||||
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
||||||
expect(callbackUserSpy).toHaveBeenCalled();
|
expect(callbackUserSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processImplicitFlowCallback', () => {
|
describe('processImplicitFlowCallback', () => {
|
||||||
it('calls all methods correctly', waitForAsync(() => {
|
it('calls all methods correctly', async () => {
|
||||||
const implicitFlowCallbackSpy = spyOn(
|
const implicitFlowCallbackSpy = vi
|
||||||
implicitFlowCallbackHandlerService,
|
.spyOn(implicitFlowCallbackHandlerService, 'implicitFlowCallback')
|
||||||
'implicitFlowCallback'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
.spyOn(
|
||||||
historyJwtKeysCallbackHandlerService,
|
historyJwtKeysCallbackHandlerService,
|
||||||
'callbackHistoryAndResetJwtKeys'
|
'callbackHistoryAndResetJwtKeys'
|
||||||
).and.returnValue(of({} as CallbackContext));
|
)
|
||||||
const callbackStateValidationSpy = spyOn(
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
stateValidationCallbackHandlerService,
|
const callbackStateValidationSpy = vi
|
||||||
'callbackStateValidation'
|
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
const callbackUserSpy = spyOn(
|
const callbackUserSpy = vi
|
||||||
userCallbackHandlerService,
|
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||||
'callbackUser'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -172,7 +169,7 @@ describe('Flows Service', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.processImplicitFlowCallback(allConfigs[0], allConfigs, 'any-hash')
|
.processImplicitFlowCallback(allConfigs[0]!, allConfigs, 'any-hash')
|
||||||
.subscribe((value) => {
|
.subscribe((value) => {
|
||||||
expect(value).toEqual({} as CallbackContext);
|
expect(value).toEqual({} as CallbackContext);
|
||||||
expect(implicitFlowCallbackSpy).toHaveBeenCalled();
|
expect(implicitFlowCallbackSpy).toHaveBeenCalled();
|
||||||
@@ -180,31 +177,32 @@ describe('Flows Service', () => {
|
|||||||
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
||||||
expect(callbackUserSpy).toHaveBeenCalled();
|
expect(callbackUserSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processRefreshToken', () => {
|
describe('processRefreshToken', () => {
|
||||||
it('calls all methods correctly', waitForAsync(() => {
|
it('calls all methods correctly', async () => {
|
||||||
const refreshSessionWithRefreshTokensSpy = spyOn(
|
const refreshSessionWithRefreshTokensSpy = vi
|
||||||
refreshSessionCallbackHandlerService,
|
.spyOn(
|
||||||
'refreshSessionWithRefreshTokens'
|
refreshSessionCallbackHandlerService,
|
||||||
).and.returnValue(of({} as CallbackContext));
|
'refreshSessionWithRefreshTokens'
|
||||||
const refreshTokensRequestTokensSpy = spyOn(
|
)
|
||||||
refreshTokenCallbackHandlerService,
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
'refreshTokensRequestTokens'
|
const refreshTokensRequestTokensSpy = vi
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.spyOn(refreshTokenCallbackHandlerService, 'refreshTokensRequestTokens')
|
||||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
historyJwtKeysCallbackHandlerService,
|
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||||
'callbackHistoryAndResetJwtKeys'
|
.spyOn(
|
||||||
).and.returnValue(of({} as CallbackContext));
|
historyJwtKeysCallbackHandlerService,
|
||||||
const callbackStateValidationSpy = spyOn(
|
'callbackHistoryAndResetJwtKeys'
|
||||||
stateValidationCallbackHandlerService,
|
)
|
||||||
'callbackStateValidation'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
const callbackStateValidationSpy = vi
|
||||||
const callbackUserSpy = spyOn(
|
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||||
userCallbackHandlerService,
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
'callbackUser'
|
const callbackUserSpy = vi
|
||||||
).and.returnValue(of({} as CallbackContext));
|
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||||
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
const allConfigs = [
|
const allConfigs = [
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -212,7 +210,7 @@ describe('Flows Service', () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
service
|
service
|
||||||
.processRefreshToken(allConfigs[0], allConfigs)
|
.processRefreshToken(allConfigs[0]!, allConfigs)
|
||||||
.subscribe((value) => {
|
.subscribe((value) => {
|
||||||
expect(value).toEqual({} as CallbackContext);
|
expect(value).toEqual({} as CallbackContext);
|
||||||
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
||||||
@@ -221,6 +219,6 @@ describe('Flows Service', () => {
|
|||||||
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
||||||
expect(callbackUserSpy).toHaveBeenCalled();
|
expect(callbackUserSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable } from 'rxjs';
|
import type { Observable } from 'rxjs';
|
||||||
import { concatMap } from 'rxjs/operators';
|
import { concatMap } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from './callback-context';
|
import type { CallbackContext } from './callback-context';
|
||||||
import { CodeFlowCallbackHandlerService } from './callback-handling/code-flow-callback-handler.service';
|
import { CodeFlowCallbackHandlerService } from './callback-handling/code-flow-callback-handler.service';
|
||||||
import { HistoryJwtKeysCallbackHandlerService } from './callback-handling/history-jwt-keys-callback-handler.service';
|
import { HistoryJwtKeysCallbackHandlerService } from './callback-handling/history-jwt-keys-callback-handler.service';
|
||||||
import { ImplicitFlowCallbackHandlerService } from './callback-handling/implicit-flow-callback-handler.service';
|
import { ImplicitFlowCallbackHandlerService } from './callback-handling/implicit-flow-callback-handler.service';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { CryptoService } from '../../utils/crypto/crypto.service';
|
import { CryptoService } from '../../utils/crypto/crypto.service';
|
||||||
import { RandomService } from './random.service';
|
import { RandomService } from './random.service';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { UserService } from '../user-data/user.service';
|
import { UserService } from '../user-data/user.service';
|
||||||
import { FlowsDataService } from './flows-data.service';
|
import { FlowsDataService } from './flows-data.service';
|
||||||
import { ResetAuthDataService } from './reset-auth-data.service';
|
import { ResetAuthDataService } from './reset-auth-data.service';
|
||||||
@@ -37,7 +38,7 @@ describe('ResetAuthDataService', () => {
|
|||||||
|
|
||||||
describe('resetAuthorizationData', () => {
|
describe('resetAuthorizationData', () => {
|
||||||
it('calls resetUserDataInStore when autoUserInfo is true', () => {
|
it('calls resetUserDataInStore when autoUserInfo is true', () => {
|
||||||
const resetUserDataInStoreSpy = spyOn(
|
const resetUserDataInStoreSpy = vi.spyOn(
|
||||||
userService,
|
userService,
|
||||||
'resetUserDataInStore'
|
'resetUserDataInStore'
|
||||||
);
|
);
|
||||||
@@ -47,16 +48,16 @@ describe('ResetAuthDataService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
service.resetAuthorizationData(allConfigs[0], allConfigs);
|
service.resetAuthorizationData(allConfigs[0]!, allConfigs);
|
||||||
expect(resetUserDataInStoreSpy).toHaveBeenCalled();
|
expect(resetUserDataInStoreSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls correct methods', () => {
|
it('calls correct methods', () => {
|
||||||
const resetStorageFlowDataSpy = spyOn(
|
const resetStorageFlowDataSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetStorageFlowData'
|
'resetStorageFlowData'
|
||||||
);
|
);
|
||||||
const setUnauthorizedAndFireEventSpy = spyOn(
|
const setUnauthorizedAndFireEventSpy = vi.spyOn(
|
||||||
authStateService,
|
authStateService,
|
||||||
'setUnauthenticatedAndFireEvent'
|
'setUnauthenticatedAndFireEvent'
|
||||||
);
|
);
|
||||||
@@ -66,7 +67,7 @@ describe('ResetAuthDataService', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
service.resetAuthorizationData(allConfigs[0], allConfigs);
|
service.resetAuthorizationData(allConfigs[0]!, allConfigs);
|
||||||
|
|
||||||
expect(resetStorageFlowDataSpy).toHaveBeenCalled();
|
expect(resetStorageFlowDataSpy).toHaveBeenCalled();
|
||||||
expect(setUnauthorizedAndFireEventSpy).toHaveBeenCalled();
|
expect(setUnauthorizedAndFireEventSpy).toHaveBeenCalled();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { UserService } from '../user-data/user.service';
|
import { UserService } from '../user-data/user.service';
|
||||||
import { FlowsDataService } from './flows-data.service';
|
import { FlowsDataService } from './flows-data.service';
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { HttpResponse } from '@angular/common/http';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { HttpResponse } from '@ngify/http';
|
||||||
import { isObservable, of, throwError } from 'rxjs';
|
import { isObservable, of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { createRetriableStream } from '../../test/create-retriable-stream.helper';
|
|
||||||
import { DataService } from '../api/data.service';
|
import { DataService } from '../api/data.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { createRetriableStream } from '../testing/create-retriable-stream.helper';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { SigninKeyDataService } from './signin-key-data.service';
|
import { SigninKeyDataService } from './signin-key-data.service';
|
||||||
|
|
||||||
const DUMMY_JWKS = {
|
const DUMMY_JWKS = {
|
||||||
@@ -53,10 +54,12 @@ describe('Signin Key Data Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getSigningKeys', () => {
|
describe('getSigningKeys', () => {
|
||||||
it('throws error when no wellKnownEndpoints given', waitForAsync(() => {
|
it('throws error when no wellKnownEndpoints given', async () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => null
|
||||||
|
);
|
||||||
const result = service.getSigningKeys({ configId: 'configId1' });
|
const result = service.getSigningKeys({ configId: 'configId1' });
|
||||||
|
|
||||||
result.subscribe({
|
result.subscribe({
|
||||||
@@ -64,12 +67,14 @@ describe('Signin Key Data Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error when no jwksUri given', waitForAsync(() => {
|
it('throws error when no jwksUri given', async () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ jwksUri: null });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ jwksUri: null })
|
||||||
|
);
|
||||||
const result = service.getSigningKeys({ configId: 'configId1' });
|
const result = service.getSigningKeys({ configId: 'configId1' });
|
||||||
|
|
||||||
result.subscribe({
|
result.subscribe({
|
||||||
@@ -77,30 +82,34 @@ describe('Signin Key Data Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls dataservice if jwksurl is given', waitForAsync(() => {
|
it('calls dataservice if jwksurl is given', async () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ jwksUri: 'someUrl' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
const spy = spyOn(dataService, 'get').and.callFake(() => of());
|
() => ({ jwksUri: 'someUrl' })
|
||||||
|
);
|
||||||
|
const spy = vi.spyOn(dataService, 'get').mockImplementation(() => of());
|
||||||
|
|
||||||
const result = service.getSigningKeys({ configId: 'configId1' });
|
const result = service.getSigningKeys({ configId: 'configId1' });
|
||||||
|
|
||||||
result.subscribe({
|
result.subscribe({
|
||||||
complete: () => {
|
complete: () => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith('someUrl', {
|
expect(spy).toHaveBeenCalledExactlyOnceWith('someUrl', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry once', waitForAsync(() => {
|
it('should retry once', async () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ jwksUri: 'someUrl' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'get').and.returnValue(
|
() => ({ jwksUri: 'someUrl' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
of(DUMMY_JWKS)
|
of(DUMMY_JWKS)
|
||||||
@@ -113,13 +122,15 @@ describe('Signin Key Data Service', () => {
|
|||||||
expect(res).toEqual(DUMMY_JWKS);
|
expect(res).toEqual(DUMMY_JWKS);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry twice', waitForAsync(() => {
|
it('should retry twice', async () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ jwksUri: 'someUrl' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'get').and.returnValue(
|
() => ({ jwksUri: 'someUrl' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
@@ -133,13 +144,15 @@ describe('Signin Key Data Service', () => {
|
|||||||
expect(res).toEqual(DUMMY_JWKS);
|
expect(res).toEqual(DUMMY_JWKS);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should fail after three tries', waitForAsync(() => {
|
it('should fail after three tries', async () => {
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ jwksUri: 'someUrl' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'get').and.returnValue(
|
() => ({ jwksUri: 'someUrl' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
@@ -153,21 +166,21 @@ describe('Signin Key Data Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('handleErrorGetSigningKeys', () => {
|
describe('handleErrorGetSigningKeys', () => {
|
||||||
it('keeps observable if error is catched', waitForAsync(() => {
|
it('keeps observable if error is catched', async () => {
|
||||||
const result = (service as any).handleErrorGetSigningKeys(
|
const result = (service as any).handleErrorGetSigningKeys(
|
||||||
new HttpResponse()
|
new HttpResponse()
|
||||||
);
|
);
|
||||||
const hasTypeObservable = isObservable(result);
|
const hasTypeObservable = isObservable(result);
|
||||||
|
|
||||||
expect(hasTypeObservable).toBeTrue();
|
expect(hasTypeObservable).toBeTruthy();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error if error is response', waitForAsync(() => {
|
it('logs error if error is response', async () => {
|
||||||
const logSpy = spyOn(loggerService, 'logError');
|
const logSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
(service as any)
|
(service as any)
|
||||||
.handleErrorGetSigningKeys(
|
.handleErrorGetSigningKeys(
|
||||||
@@ -176,31 +189,31 @@ describe('Signin Key Data Service', () => {
|
|||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(logSpy).toHaveBeenCalledOnceWith(
|
expect(logSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'400 - nono {}'
|
'400 - nono {}'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error if error is not a response', waitForAsync(() => {
|
it('logs error if error is not a response', async () => {
|
||||||
const logSpy = spyOn(loggerService, 'logError');
|
const logSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
(service as any)
|
(service as any)
|
||||||
.handleErrorGetSigningKeys('Just some Error', { configId: 'configId1' })
|
.handleErrorGetSigningKeys('Just some Error', { configId: 'configId1' })
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(logSpy).toHaveBeenCalledOnceWith(
|
expect(logSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'Just some Error'
|
'Just some Error'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error if error with message property is not a response', waitForAsync(() => {
|
it('logs error if error with message property is not a response', async () => {
|
||||||
const logSpy = spyOn(loggerService, 'logError');
|
const logSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
(service as any)
|
(service as any)
|
||||||
.handleErrorGetSigningKeys(
|
.handleErrorGetSigningKeys(
|
||||||
@@ -209,12 +222,12 @@ describe('Signin Key Data Service', () => {
|
|||||||
)
|
)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: () => {
|
error: () => {
|
||||||
expect(logSpy).toHaveBeenCalledOnceWith(
|
expect(logSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'Just some Error'
|
'Just some Error'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
11
src/http/index.ts
Normal file
11
src/http/index.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import type { HttpFeature } from '@ngify/http';
|
||||||
|
|
||||||
|
export function provideHttpClient() {
|
||||||
|
// todo
|
||||||
|
throw new Error('todo!');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withInterceptorsFromDi(): HttpFeature {
|
||||||
|
// todo
|
||||||
|
throw new Error('todo!');
|
||||||
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { skip } from 'rxjs/operators';
|
import { skip } from 'rxjs/operators';
|
||||||
import { mockAbstractProvider, mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { OidcSecurityService } from '../oidc.security.service';
|
import { OidcSecurityService } from '../oidc.security.service';
|
||||||
import { PublicEventsService } from '../public-events/public-events.service';
|
import { PublicEventsService } from '../public-events/public-events.service';
|
||||||
import { AbstractSecurityStorage } from '../storage/abstract-security-storage';
|
import { AbstractSecurityStorage } from '../storage/abstract-security-storage';
|
||||||
import { DefaultSessionStorageService } from '../storage/default-sessionstorage.service';
|
import { DefaultSessionStorageService } from '../storage/default-sessionstorage.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { mockAbstractProvider, mockProvider } from '../testing/mock';
|
||||||
import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
import { PlatformProvider } from '../utils/platform-provider/platform.provider';
|
||||||
import { CheckSessionService } from './check-session.service';
|
import { CheckSessionService } from './check-session.service';
|
||||||
import { IFrameService } from './existing-iframe.service';
|
import { IFrameService } from './existing-iframe.service';
|
||||||
@@ -67,7 +68,7 @@ describe('CheckSessionService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('getOrCreateIframe calls iFrameService.addIFrameToWindowBody if no Iframe exists', () => {
|
it('getOrCreateIframe calls iFrameService.addIFrameToWindowBody if no Iframe exists', () => {
|
||||||
spyOn(iFrameService, 'addIFrameToWindowBody').and.callThrough();
|
vi.spyOn(iFrameService, 'addIFrameToWindowBody')();
|
||||||
|
|
||||||
const result = (checkSessionService as any).getOrCreateIframe({
|
const result = (checkSessionService as any).getOrCreateIframe({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -89,7 +90,7 @@ describe('CheckSessionService', () => {
|
|||||||
|
|
||||||
it('init appends iframe on body with correct values', () => {
|
it('init appends iframe on body with correct values', () => {
|
||||||
expect((checkSessionService as any).sessionIframe).toBeFalsy();
|
expect((checkSessionService as any).sessionIframe).toBeFalsy();
|
||||||
spyOn<any>(loggerService, 'logDebug').and.callFake(() => undefined);
|
vi.spyOn(loggerService, 'logDebug').mockImplementation(() => undefined);
|
||||||
|
|
||||||
(checkSessionService as any).init();
|
(checkSessionService as any).init();
|
||||||
const iframe = (checkSessionService as any).getOrCreateIframe({
|
const iframe = (checkSessionService as any).getOrCreateIframe({
|
||||||
@@ -105,29 +106,34 @@ describe('CheckSessionService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('log warning if authWellKnownEndpoints.check_session_iframe is not existing', () => {
|
it('log warning if authWellKnownEndpoints.check_session_iframe is not existing', () => {
|
||||||
const spyLogWarning = spyOn<any>(loggerService, 'logWarning');
|
const spyLogWarning = vi.spyOn<any>(loggerService, 'logWarning');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn<any>(loggerService, 'logDebug').and.callFake(() => undefined);
|
vi.spyOn<any>(loggerService, 'logDebug').mockImplementation(
|
||||||
spyOn(storagePersistenceService, 'read')
|
() => undefined
|
||||||
|
);
|
||||||
|
vi.spyOn(storagePersistenceService, 'read')
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
.withArgs('authWellKnownEndPoints', config)
|
||||||
.and.returnValue({ checkSessionIframe: undefined });
|
.mockReturnValue({ checkSessionIframe: undefined });
|
||||||
(checkSessionService as any).init(config);
|
(checkSessionService as any).init(config);
|
||||||
|
|
||||||
expect(spyLogWarning).toHaveBeenCalledOnceWith(config, jasmine.any(String));
|
expect(spyLogWarning).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
config,
|
||||||
|
expect.any(String)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('start() calls pollserversession() with clientId if no scheduledheartbeat is set', () => {
|
it('start() calls pollserversession() with clientId if no scheduledheartbeat is set', () => {
|
||||||
const spy = spyOn<any>(checkSessionService, 'pollServerSession');
|
const spy = vi.spyOn<any>(checkSessionService, 'pollServerSession');
|
||||||
const config = { clientId: 'clientId', configId: 'configId1' };
|
const config = { clientId: 'clientId', configId: 'configId1' };
|
||||||
|
|
||||||
checkSessionService.start(config);
|
checkSessionService.start(config);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('clientId', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('clientId', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('start() does not call pollServerSession() if scheduledHeartBeatRunning is set', () => {
|
it('start() does not call pollServerSession() if scheduledHeartBeatRunning is set', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const spy = spyOn<any>(checkSessionService, 'pollServerSession');
|
const spy = vi.spyOn<any>(checkSessionService, 'pollServerSession');
|
||||||
|
|
||||||
(checkSessionService as any).scheduledHeartBeatRunning = (): void =>
|
(checkSessionService as any).scheduledHeartBeatRunning = (): void =>
|
||||||
undefined;
|
undefined;
|
||||||
@@ -148,10 +154,10 @@ describe('CheckSessionService', () => {
|
|||||||
|
|
||||||
it('stopCheckingSession does nothing if scheduledHeartBeatRunning is not set', () => {
|
it('stopCheckingSession does nothing if scheduledHeartBeatRunning is not set', () => {
|
||||||
(checkSessionService as any).scheduledHeartBeatRunning = null;
|
(checkSessionService as any).scheduledHeartBeatRunning = null;
|
||||||
const spy = spyOn<any>(checkSessionService, 'clearScheduledHeartBeat');
|
const spy = vi.spyOn<any>(checkSessionService, 'clearScheduledHeartBeat');
|
||||||
|
|
||||||
checkSessionService.stop();
|
checkSessionService.stop();
|
||||||
expect(spy).not.toHaveBeenCalledOnceWith();
|
expect(spy).not.toHaveBeenCalledExactlyOnceWith();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('serverStateChanged', () => {
|
describe('serverStateChanged', () => {
|
||||||
@@ -167,7 +173,7 @@ describe('CheckSessionService', () => {
|
|||||||
const config = { startCheckSession: true, configId: 'configId1' };
|
const config = { startCheckSession: true, configId: 'configId1' };
|
||||||
const result = checkSessionService.serverStateChanged(config);
|
const result = checkSessionService.serverStateChanged(config);
|
||||||
|
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if startCheckSession is configured and checkSessionReceived is true', () => {
|
it('returns true if startCheckSession is configured and checkSessionReceived is true', () => {
|
||||||
@@ -175,17 +181,17 @@ describe('CheckSessionService', () => {
|
|||||||
const config = { startCheckSession: true, configId: 'configId1' };
|
const config = { startCheckSession: true, configId: 'configId1' };
|
||||||
const result = checkSessionService.serverStateChanged(config);
|
const result = checkSessionService.serverStateChanged(config);
|
||||||
|
|
||||||
expect(result).toBeTrue();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('pollServerSession', () => {
|
describe('pollServerSession', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn<any>(checkSessionService, 'init').and.returnValue(of(undefined));
|
vi.spyOn<any>(checkSessionService, 'init').mockReturnValue(of(undefined));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('increases outstandingMessages', () => {
|
it('increases outstandingMessages', () => {
|
||||||
spyOn<any>(checkSessionService, 'getExistingIframe').and.returnValue({
|
vi.spyOn<any>(checkSessionService, 'getExistingIframe').mockReturnValue({
|
||||||
contentWindow: { postMessage: () => undefined },
|
contentWindow: { postMessage: () => undefined },
|
||||||
});
|
});
|
||||||
const authWellKnownEndpoints = {
|
const authWellKnownEndpoints = {
|
||||||
@@ -193,18 +199,20 @@ describe('CheckSessionService', () => {
|
|||||||
};
|
};
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(authWellKnownEndpoints)
|
['authWellKnownEndPoints', config],
|
||||||
|
() => authWellKnownEndpoints
|
||||||
|
)
|
||||||
.withArgs('session_state', config)
|
.withArgs('session_state', config)
|
||||||
.and.returnValue('session_state');
|
.mockReturnValue('session_state');
|
||||||
spyOn(loggerService, 'logDebug').and.callFake(() => undefined);
|
vi.spyOn(loggerService, 'logDebug').mockImplementation(() => undefined);
|
||||||
(checkSessionService as any).pollServerSession('clientId', config);
|
(checkSessionService as any).pollServerSession('clientId', config);
|
||||||
expect((checkSessionService as any).outstandingMessages).toBe(1);
|
expect((checkSessionService as any).outstandingMessages).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs warning if iframe does not exist', () => {
|
it('logs warning if iframe does not exist', () => {
|
||||||
spyOn<any>(checkSessionService, 'getExistingIframe').and.returnValue(
|
vi.spyOn<any>(checkSessionService, 'getExistingIframe').mockReturnValue(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const authWellKnownEndpoints = {
|
const authWellKnownEndpoints = {
|
||||||
@@ -212,77 +220,91 @@ describe('CheckSessionService', () => {
|
|||||||
};
|
};
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(authWellKnownEndpoints);
|
['authWellKnownEndPoints', config],
|
||||||
const spyLogWarning = spyOn(loggerService, 'logWarning').and.callFake(
|
() => authWellKnownEndpoints
|
||||||
() => undefined
|
|
||||||
);
|
);
|
||||||
|
const spyLogWarning = vi
|
||||||
|
.spyOn(loggerService, 'logWarning')
|
||||||
|
.mockImplementation(() => undefined);
|
||||||
|
|
||||||
spyOn(loggerService, 'logDebug').and.callFake(() => undefined);
|
vi.spyOn(loggerService, 'logDebug').mockImplementation(() => undefined);
|
||||||
(checkSessionService as any).pollServerSession('clientId', config);
|
(checkSessionService as any).pollServerSession('clientId', config);
|
||||||
expect(spyLogWarning).toHaveBeenCalledOnceWith(
|
expect(spyLogWarning).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
jasmine.any(String)
|
expect.any(String)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs warning if clientId is not set', () => {
|
it('logs warning if clientId is not set', () => {
|
||||||
spyOn<any>(checkSessionService, 'getExistingIframe').and.returnValue({});
|
vi.spyOn<any>(checkSessionService, 'getExistingIframe').mockReturnValue(
|
||||||
|
{}
|
||||||
|
);
|
||||||
const authWellKnownEndpoints = {
|
const authWellKnownEndpoints = {
|
||||||
checkSessionIframe: 'https://some-testing-url.com',
|
checkSessionIframe: 'https://some-testing-url.com',
|
||||||
};
|
};
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(authWellKnownEndpoints);
|
['authWellKnownEndPoints', config],
|
||||||
const spyLogWarning = spyOn(loggerService, 'logWarning').and.callFake(
|
() => authWellKnownEndpoints
|
||||||
() => undefined
|
|
||||||
);
|
);
|
||||||
|
const spyLogWarning = vi
|
||||||
|
.spyOn(loggerService, 'logWarning')
|
||||||
|
.mockImplementation(() => undefined);
|
||||||
|
|
||||||
spyOn(loggerService, 'logDebug').and.callFake(() => undefined);
|
vi.spyOn(loggerService, 'logDebug').mockImplementation(() => undefined);
|
||||||
(checkSessionService as any).pollServerSession('', config);
|
(checkSessionService as any).pollServerSession('', config);
|
||||||
expect(spyLogWarning).toHaveBeenCalledOnceWith(
|
expect(spyLogWarning).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
jasmine.any(String)
|
expect.any(String)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs debug if session_state is not set', () => {
|
it('logs debug if session_state is not set', () => {
|
||||||
spyOn<any>(checkSessionService, 'getExistingIframe').and.returnValue({});
|
vi.spyOn<any>(checkSessionService, 'getExistingIframe').mockReturnValue(
|
||||||
|
{}
|
||||||
|
);
|
||||||
const authWellKnownEndpoints = {
|
const authWellKnownEndpoints = {
|
||||||
checkSessionIframe: 'https://some-testing-url.com',
|
checkSessionIframe: 'https://some-testing-url.com',
|
||||||
};
|
};
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(authWellKnownEndpoints)
|
['authWellKnownEndPoints', config],
|
||||||
|
() => authWellKnownEndpoints
|
||||||
|
)
|
||||||
.withArgs('session_state', config)
|
.withArgs('session_state', config)
|
||||||
.and.returnValue(null);
|
.mockReturnValue(null);
|
||||||
|
|
||||||
const spyLogDebug = spyOn(loggerService, 'logDebug').and.callFake(
|
const spyLogDebug = vi
|
||||||
() => undefined
|
.spyOn(loggerService, 'logDebug')
|
||||||
);
|
.mockImplementation(() => undefined);
|
||||||
|
|
||||||
(checkSessionService as any).pollServerSession('clientId', config);
|
(checkSessionService as any).pollServerSession('clientId', config);
|
||||||
expect(spyLogDebug).toHaveBeenCalledTimes(2);
|
expect(spyLogDebug).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs debug if session_state is set but authWellKnownEndpoints are not set', () => {
|
it('logs debug if session_state is set but authWellKnownEndpoints are not set', () => {
|
||||||
spyOn<any>(checkSessionService, 'getExistingIframe').and.returnValue({});
|
vi.spyOn<any>(checkSessionService, 'getExistingIframe').mockReturnValue(
|
||||||
|
{}
|
||||||
|
);
|
||||||
const authWellKnownEndpoints = null;
|
const authWellKnownEndpoints = null;
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(authWellKnownEndpoints)
|
['authWellKnownEndPoints', config],
|
||||||
|
() => authWellKnownEndpoints
|
||||||
|
)
|
||||||
.withArgs('session_state', config)
|
.withArgs('session_state', config)
|
||||||
.and.returnValue('some_session_state');
|
.mockReturnValue('some_session_state');
|
||||||
const spyLogDebug = spyOn(loggerService, 'logDebug').and.callFake(
|
const spyLogDebug = vi
|
||||||
() => undefined
|
.spyOn(loggerService, 'logDebug')
|
||||||
);
|
.mockImplementation(() => undefined);
|
||||||
|
|
||||||
(checkSessionService as any).pollServerSession('clientId', config);
|
(checkSessionService as any).pollServerSession('clientId', config);
|
||||||
expect(spyLogDebug).toHaveBeenCalledTimes(2);
|
expect(spyLogDebug).toHaveBeenCalledTimes(2);
|
||||||
@@ -290,7 +312,7 @@ describe('CheckSessionService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('init', () => {
|
describe('init', () => {
|
||||||
it('returns falsy observable when lastIframerefresh and iframeRefreshInterval are bigger than now', waitForAsync(() => {
|
it('returns falsy observable when lastIframerefresh and iframeRefreshInterval are bigger than now', async () => {
|
||||||
const serviceAsAny = checkSessionService as any;
|
const serviceAsAny = checkSessionService as any;
|
||||||
const dateNow = new Date();
|
const dateNow = new Date();
|
||||||
const lastRefresh = dateNow.setMinutes(dateNow.getMinutes() + 30);
|
const lastRefresh = dateNow.setMinutes(dateNow.getMinutes() + 30);
|
||||||
@@ -301,7 +323,7 @@ describe('CheckSessionService', () => {
|
|||||||
serviceAsAny.init().subscribe((result: any) => {
|
serviceAsAny.init().subscribe((result: any) => {
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isCheckSessionConfigured', () => {
|
describe('isCheckSessionConfigured', () => {
|
||||||
@@ -323,7 +345,7 @@ describe('CheckSessionService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('checkSessionChanged$', () => {
|
describe('checkSessionChanged$', () => {
|
||||||
it('emits when internal event is thrown', waitForAsync(() => {
|
it('emits when internal event is thrown', async () => {
|
||||||
checkSessionService.checkSessionChanged$
|
checkSessionService.checkSessionChanged$
|
||||||
.pipe(skip(1))
|
.pipe(skip(1))
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
@@ -333,15 +355,15 @@ describe('CheckSessionService', () => {
|
|||||||
const serviceAsAny = checkSessionService as any;
|
const serviceAsAny = checkSessionService as any;
|
||||||
|
|
||||||
serviceAsAny.checkSessionChangedInternal$.next(true);
|
serviceAsAny.checkSessionChangedInternal$.next(true);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('emits false initially', waitForAsync(() => {
|
it('emits false initially', async () => {
|
||||||
checkSessionService.checkSessionChanged$.subscribe((result) => {
|
checkSessionService.checkSessionChanged$.subscribe((result) => {
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('emits false then true when emitted', waitForAsync(() => {
|
it('emits false then true when emitted', async () => {
|
||||||
const expectedResultsInOrder = [false, true];
|
const expectedResultsInOrder = [false, true];
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
@@ -351,6 +373,6 @@ describe('CheckSessionService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
(checkSessionService as any).checkSessionChangedInternal$.next(true);
|
(checkSessionService as any).checkSessionChangedInternal$.next(true);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { UrlService } from '../utils/url/url.service';
|
import { UrlService } from '../utils/url/url.service';
|
||||||
import { RefreshSessionIframeService } from './refresh-session-iframe.service';
|
import { RefreshSessionIframeService } from './refresh-session-iframe.service';
|
||||||
import { SilentRenewService } from './silent-renew.service';
|
import { SilentRenewService } from './silent-renew.service';
|
||||||
@@ -31,37 +32,43 @@ describe('RefreshSessionIframeService ', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('refreshSessionWithIframe', () => {
|
describe('refreshSessionWithIframe', () => {
|
||||||
it('calls sendAuthorizeRequestUsingSilentRenew with created url', waitForAsync(() => {
|
it('calls sendAuthorizeRequestUsingSilentRenew with created url', async () => {
|
||||||
spyOn(urlService, 'getRefreshSessionSilentRenewUrl').and.returnValue(
|
vi.spyOn(urlService, 'getRefreshSessionSilentRenewUrl').mockReturnValue(
|
||||||
of('a-url')
|
of('a-url')
|
||||||
);
|
);
|
||||||
const sendAuthorizeRequestUsingSilentRenewSpy = spyOn(
|
const sendAuthorizeRequestUsingSilentRenewSpy = vi
|
||||||
refreshSessionIframeService as any,
|
.spyOn(
|
||||||
'sendAuthorizeRequestUsingSilentRenew'
|
refreshSessionIframeService as any,
|
||||||
).and.returnValue(of(null));
|
'sendAuthorizeRequestUsingSilentRenew'
|
||||||
|
)
|
||||||
|
.mockReturnValue(of(null));
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
refreshSessionIframeService
|
refreshSessionIframeService
|
||||||
.refreshSessionWithIframe(allConfigs[0], allConfigs)
|
.refreshSessionWithIframe(allConfigs[0]!, allConfigs)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(
|
expect(
|
||||||
sendAuthorizeRequestUsingSilentRenewSpy
|
sendAuthorizeRequestUsingSilentRenewSpy
|
||||||
).toHaveBeenCalledOnceWith('a-url', allConfigs[0], allConfigs);
|
).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'a-url',
|
||||||
|
allConfigs[0]!,
|
||||||
|
allConfigs
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('initSilentRenewRequest', () => {
|
describe('initSilentRenewRequest', () => {
|
||||||
it('dispatches customevent to window object', waitForAsync(() => {
|
it('dispatches customevent to window object', async () => {
|
||||||
const dispatchEventSpy = spyOn(window, 'dispatchEvent');
|
const dispatchEventSpy = vi.spyOn(window, 'dispatchEvent');
|
||||||
|
|
||||||
(refreshSessionIframeService as any).initSilentRenewRequest();
|
(refreshSessionIframeService as any).initSilentRenewRequest();
|
||||||
|
|
||||||
expect(dispatchEventSpy).toHaveBeenCalledOnceWith(
|
expect(dispatchEventSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
new CustomEvent('oidc-silent-renew-init', {
|
new CustomEvent('oidc-silent-renew-init', {
|
||||||
detail: jasmine.any(Number),
|
detail: expect.any(Number),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { DOCUMENT } from '../dom';
|
|
||||||
import { Injectable, RendererFactory2, inject } from 'injection-js';
|
import { Injectable, RendererFactory2, inject } from 'injection-js';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { switchMap } from 'rxjs/operators';
|
import { switchMap } from 'rxjs/operators';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
|
import { DOCUMENT } from '../dom';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { UrlService } from '../utils/url/url.service';
|
import { UrlService } from '../utils/url/url.service';
|
||||||
import { SilentRenewService } from './silent-renew.service';
|
import { SilentRenewService } from './silent-renew.service';
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed, fakeAsync, tick } from '@/testing';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { Observable, of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { ImplicitFlowCallbackService } from '../callback/implicit-flow-callback.service';
|
import { ImplicitFlowCallbackService } from '../callback/implicit-flow-callback.service';
|
||||||
import { IntervalService } from '../callback/interval.service';
|
import { IntervalService } from '../callback/interval.service';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../utils/flowHelper/flow-helper.service';
|
||||||
import { ValidationResult } from '../validation/validation-result';
|
import { ValidationResult } from '../validation/validation-result';
|
||||||
import { IFrameService } from './existing-iframe.service';
|
import { IFrameService } from './existing-iframe.service';
|
||||||
@@ -63,7 +64,7 @@ describe('SilentRenewService ', () => {
|
|||||||
describe('refreshSessionWithIFrameCompleted', () => {
|
describe('refreshSessionWithIFrameCompleted', () => {
|
||||||
it('is of type observable', () => {
|
it('is of type observable', () => {
|
||||||
expect(silentRenewService.refreshSessionWithIFrameCompleted$).toEqual(
|
expect(silentRenewService.refreshSessionWithIFrameCompleted$).toEqual(
|
||||||
jasmine.any(Observable)
|
expect.any(Observable)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -95,7 +96,7 @@ describe('SilentRenewService ', () => {
|
|||||||
|
|
||||||
describe('getOrCreateIframe', () => {
|
describe('getOrCreateIframe', () => {
|
||||||
it('returns iframe if iframe is truthy', () => {
|
it('returns iframe if iframe is truthy', () => {
|
||||||
spyOn(silentRenewService as any, 'getExistingIframe').and.returnValue({
|
vi.spyOn(silentRenewService as any, 'getExistingIframe').mockReturnValue({
|
||||||
name: 'anything',
|
name: 'anything',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -109,31 +110,33 @@ describe('SilentRenewService ', () => {
|
|||||||
it('adds iframe to body if existing iframe is falsy', () => {
|
it('adds iframe to body if existing iframe is falsy', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(silentRenewService as any, 'getExistingIframe').and.returnValue(
|
vi.spyOn(silentRenewService as any, 'getExistingIframe').mockReturnValue(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
const spy = spyOn(iFrameService, 'addIFrameToWindowBody').and.returnValue(
|
const spy = vi
|
||||||
{ name: 'anything' } as HTMLIFrameElement
|
.spyOn(iFrameService, 'addIFrameToWindowBody')
|
||||||
);
|
.mockReturnValue({ name: 'anything' } as HTMLIFrameElement);
|
||||||
|
|
||||||
const result = silentRenewService.getOrCreateIframe(config);
|
const result = silentRenewService.getOrCreateIframe(config);
|
||||||
|
|
||||||
expect(result).toEqual({ name: 'anything' } as HTMLIFrameElement);
|
expect(result).toEqual({ name: 'anything' } as HTMLIFrameElement);
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('myiFrameForSilentRenew', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'myiFrameForSilentRenew',
|
||||||
|
config
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('codeFlowCallbackSilentRenewIframe', () => {
|
describe('codeFlowCallbackSilentRenewIframe', () => {
|
||||||
it('calls processSilentRenewCodeFlowCallback with correct arguments', waitForAsync(() => {
|
it('calls processSilentRenewCodeFlowCallback with correct arguments', async () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processSilentRenewCodeFlowCallback')
|
||||||
'processSilentRenewCodeFlowCallback'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const expectedContext = {
|
const expectedContext = {
|
||||||
code: 'some-code',
|
code: 'some-code',
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
@@ -152,32 +155,31 @@ describe('SilentRenewService ', () => {
|
|||||||
silentRenewService
|
silentRenewService
|
||||||
.codeFlowCallbackSilentRenewIframe([url, urlParts], config, allConfigs)
|
.codeFlowCallbackSilentRenewIframe([url, urlParts], config, allConfigs)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
expectedContext,
|
expectedContext,
|
||||||
config,
|
config,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if url has error param and resets everything on error', waitForAsync(() => {
|
it('throws error if url has error param and resets everything on error', async () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
const spy = spyOn(
|
const spy = vi
|
||||||
flowsService,
|
.spyOn(flowsService, 'processSilentRenewCodeFlowCallback')
|
||||||
'processSilentRenewCodeFlowCallback'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
const authStateServiceSpy = vi.spyOn(
|
||||||
const authStateServiceSpy = spyOn(
|
|
||||||
authStateService,
|
authStateService,
|
||||||
'updateAndPublishAuthState'
|
'updateAndPublishAuthState'
|
||||||
);
|
);
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const setNonceSpy = spyOn(flowsDataService, 'setNonce');
|
const setNonceSpy = vi.spyOn(flowsDataService, 'setNonce');
|
||||||
const stopPeriodicTokenCheckSpy = spyOn(
|
const stopPeriodicTokenCheckSpy = vi.spyOn(
|
||||||
intervalService,
|
intervalService,
|
||||||
'stopPeriodicTokenCheck'
|
'stopPeriodicTokenCheck'
|
||||||
);
|
);
|
||||||
@@ -191,121 +193,116 @@ describe('SilentRenewService ', () => {
|
|||||||
error: (error) => {
|
error: (error) => {
|
||||||
expect(error).toEqual(new Error('some_error'));
|
expect(error).toEqual(new Error('some_error'));
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
expect(authStateServiceSpy).toHaveBeenCalledOnceWith({
|
expect(authStateServiceSpy).toHaveBeenCalledExactlyOnceWith({
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
validationResult: ValidationResult.LoginRequired,
|
validationResult: ValidationResult.LoginRequired,
|
||||||
isRenewProcess: true,
|
isRenewProcess: true,
|
||||||
});
|
});
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledOnceWith(
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
expect(setNonceSpy).toHaveBeenCalledOnceWith('', config);
|
expect(setNonceSpy).toHaveBeenCalledExactlyOnceWith('', config);
|
||||||
expect(stopPeriodicTokenCheckSpy).toHaveBeenCalledTimes(1);
|
expect(stopPeriodicTokenCheckSpy).toHaveBeenCalledTimes(1);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('silentRenewEventHandler', () => {
|
describe('silentRenewEventHandler', () => {
|
||||||
it('returns if no details is given', fakeAsync(() => {
|
it('returns if no details is given', async () => {
|
||||||
const isCurrentFlowCodeFlowSpy = spyOn(
|
const isCurrentFlowCodeFlowSpy = vi
|
||||||
flowHelper,
|
.spyOn(flowHelper, 'isCurrentFlowCodeFlow')
|
||||||
'isCurrentFlowCodeFlow'
|
.mockReturnValue(false);
|
||||||
).and.returnValue(false);
|
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
implicitFlowCallbackService,
|
implicitFlowCallbackService,
|
||||||
'authenticatedImplicitFlowCallback'
|
'authenticatedImplicitFlowCallback'
|
||||||
).and.returnValue(of({} as CallbackContext));
|
).mockReturnValue(of({} as CallbackContext));
|
||||||
const eventData = { detail: null } as CustomEvent;
|
const eventData = { detail: null } as CustomEvent;
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
expect(isCurrentFlowCodeFlowSpy).not.toHaveBeenCalled();
|
expect(isCurrentFlowCodeFlowSpy).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authorizedImplicitFlowCallback if current flow is not code flow', fakeAsync(() => {
|
it('calls authorizedImplicitFlowCallback if current flow is not code flow', async () => {
|
||||||
const isCurrentFlowCodeFlowSpy = spyOn(
|
const isCurrentFlowCodeFlowSpy = vi
|
||||||
flowHelper,
|
.spyOn(flowHelper, 'isCurrentFlowCodeFlow')
|
||||||
'isCurrentFlowCodeFlow'
|
.mockReturnValue(false);
|
||||||
).and.returnValue(false);
|
const authorizedImplicitFlowCallbackSpy = vi
|
||||||
const authorizedImplicitFlowCallbackSpy = spyOn(
|
.spyOn(implicitFlowCallbackService, 'authenticatedImplicitFlowCallback')
|
||||||
implicitFlowCallbackService,
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
'authenticatedImplicitFlowCallback'
|
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const eventData = { detail: 'detail' } as CustomEvent;
|
const eventData = { detail: 'detail' } as CustomEvent;
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
expect(isCurrentFlowCodeFlowSpy).toHaveBeenCalled();
|
expect(isCurrentFlowCodeFlowSpy).toHaveBeenCalled();
|
||||||
expect(authorizedImplicitFlowCallbackSpy).toHaveBeenCalledOnceWith(
|
expect(authorizedImplicitFlowCallbackSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs,
|
allConfigs,
|
||||||
'detail'
|
'detail'
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls codeFlowCallbackSilentRenewIframe if current flow is code flow', fakeAsync(() => {
|
it('calls codeFlowCallbackSilentRenewIframe if current flow is code flow', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
const codeFlowCallbackSilentRenewIframe = spyOn(
|
const codeFlowCallbackSilentRenewIframe = vi
|
||||||
silentRenewService,
|
.spyOn(silentRenewService, 'codeFlowCallbackSilentRenewIframe')
|
||||||
'codeFlowCallbackSilentRenewIframe'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
expect(codeFlowCallbackSilentRenewIframe).toHaveBeenCalledOnceWith(
|
expect(codeFlowCallbackSilentRenewIframe).toHaveBeenCalledExactlyOnceWith(
|
||||||
['detail', 'detail2'],
|
['detail', 'detail2'],
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls authorizedImplicitFlowCallback if current flow is not code flow', fakeAsync(() => {
|
it('calls authorizedImplicitFlowCallback if current flow is not code flow', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
const codeFlowCallbackSilentRenewIframe = spyOn(
|
const codeFlowCallbackSilentRenewIframe = vi
|
||||||
silentRenewService,
|
.spyOn(silentRenewService, 'codeFlowCallbackSilentRenewIframe')
|
||||||
'codeFlowCallbackSilentRenewIframe'
|
.mockReturnValue(of({} as CallbackContext));
|
||||||
).and.returnValue(of({} as CallbackContext));
|
|
||||||
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
expect(codeFlowCallbackSilentRenewIframe).toHaveBeenCalledOnceWith(
|
expect(codeFlowCallbackSilentRenewIframe).toHaveBeenCalledExactlyOnceWith(
|
||||||
['detail', 'detail2'],
|
['detail', 'detail2'],
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls next on refreshSessionWithIFrameCompleted with callbackcontext', fakeAsync(() => {
|
it('calls next on refreshSessionWithIFrameCompleted with callbackcontext', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'codeFlowCallbackSilentRenewIframe'
|
'codeFlowCallbackSilentRenewIframe'
|
||||||
).and.returnValue(
|
).mockReturnValue(
|
||||||
of({ refreshToken: 'callbackContext' } as CallbackContext)
|
of({ refreshToken: 'callbackContext' } as CallbackContext)
|
||||||
);
|
);
|
||||||
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
||||||
@@ -321,42 +318,42 @@ describe('SilentRenewService ', () => {
|
|||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('loggs and calls flowsDataService.resetSilentRenewRunning in case of an error', fakeAsync(() => {
|
it('loggs and calls flowsDataService.resetSilentRenewRunning in case of an error', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'codeFlowCallbackSilentRenewIframe'
|
'codeFlowCallbackSilentRenewIframe'
|
||||||
).and.returnValue(throwError(() => new Error('ERROR')));
|
).mockReturnValue(throwError(() => new Error('ERROR')));
|
||||||
const resetSilentRenewRunningSpy = spyOn(
|
const resetSilentRenewRunningSpy = vi.spyOn(
|
||||||
flowsDataService,
|
flowsDataService,
|
||||||
'resetSilentRenewRunning'
|
'resetSilentRenewRunning'
|
||||||
);
|
);
|
||||||
const logErrorSpy = spyOn(loggerService, 'logError');
|
const logErrorSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
expect(resetSilentRenewRunningSpy).toHaveBeenCalledTimes(1);
|
expect(resetSilentRenewRunningSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(logErrorSpy).toHaveBeenCalledTimes(1);
|
expect(logErrorSpy).toHaveBeenCalledTimes(1);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls next on refreshSessionWithIFrameCompleted with null in case of error', fakeAsync(() => {
|
it('calls next on refreshSessionWithIFrameCompleted with null in case of error', async () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
silentRenewService,
|
silentRenewService,
|
||||||
'codeFlowCallbackSilentRenewIframe'
|
'codeFlowCallbackSilentRenewIframe'
|
||||||
).and.returnValue(throwError(() => new Error('ERROR')));
|
).mockReturnValue(throwError(() => new Error('ERROR')));
|
||||||
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
const eventData = { detail: 'detail?detail2' } as CustomEvent;
|
||||||
const allConfigs = [{ configId: 'configId1' }];
|
const allConfigs = [{ configId: 'configId1' }];
|
||||||
|
|
||||||
@@ -368,10 +365,10 @@ describe('SilentRenewService ', () => {
|
|||||||
|
|
||||||
silentRenewService.silentRenewEventHandler(
|
silentRenewService.silentRenewEventHandler(
|
||||||
eventData,
|
eventData,
|
||||||
allConfigs[0],
|
allConfigs[0]!,
|
||||||
allConfigs
|
allConfigs
|
||||||
);
|
);
|
||||||
tick(1000);
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { HttpParams } from '@ngify/http';
|
import { HttpParams } from '@ngify/http';
|
||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, Subject, throwError } from 'rxjs';
|
import { type Observable, Subject, throwError } from 'rxjs';
|
||||||
import { catchError } from 'rxjs/operators';
|
import { catchError } from 'rxjs/operators';
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { ImplicitFlowCallbackService } from '../callback/implicit-flow-callback.service';
|
import { ImplicitFlowCallbackService } from '../callback/implicit-flow-callback.service';
|
||||||
import { IntervalService } from '../callback/interval.service';
|
import { IntervalService } from '../callback/interval.service';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { CallbackContext } from '../flows/callback-context';
|
import type { CallbackContext } from '../flows/callback-context';
|
||||||
import { FlowsDataService } from '../flows/flows-data.service';
|
import { FlowsDataService } from '../flows/flows-data.service';
|
||||||
import { FlowsService } from '../flows/flows.service';
|
import { FlowsService } from '../flows/flows.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ export * from './auth-options';
|
|||||||
export * from './auth-state/auth-result';
|
export * from './auth-state/auth-result';
|
||||||
export * from './auth-state/auth-state';
|
export * from './auth-state/auth-state';
|
||||||
export * from './auth.module';
|
export * from './auth.module';
|
||||||
export * from './auto-login/auto-login-all-routes.guard';
|
|
||||||
export * from './auto-login/auto-login-partial-routes.guard';
|
export * from './auto-login/auto-login-partial-routes.guard';
|
||||||
export * from './config/auth-well-known/auth-well-known-endpoints';
|
export * from './config/auth-well-known/auth-well-known-endpoints';
|
||||||
export * from './config/config.service';
|
export * from './config/config.service';
|
||||||
@@ -29,3 +28,5 @@ export * from './user-data/userdata-result';
|
|||||||
export * from './validation/jwtkeys';
|
export * from './validation/jwtkeys';
|
||||||
export * from './validation/state-validation-result';
|
export * from './validation/state-validation-result';
|
||||||
export * from './validation/validation-result';
|
export * from './validation/validation-result';
|
||||||
|
export * from './injection';
|
||||||
|
export * from './router';
|
||||||
|
|||||||
7
src/injection/convention.ts
Normal file
7
src/injection/convention.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { InjectionToken } from 'injection-js';
|
||||||
|
import type { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
export const APP_INITIALIZER = new InjectionToken<
|
||||||
|
// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>
|
||||||
|
readonly (() => void | Observable<unknown> | Promise<unknown>)[]
|
||||||
|
>('APP_INITIALIZER');
|
||||||
3
src/injection/index.ts
Normal file
3
src/injection/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export { Module } from './module';
|
||||||
|
export { APP_INITIALIZER } from './convention';
|
||||||
|
export { injectAbstractType } from './inject';
|
||||||
10
src/injection/inject.ts
Normal file
10
src/injection/inject.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { inject } from 'injection-js';
|
||||||
|
|
||||||
|
// biome-ignore lint/complexity/noBannedTypes: <explanation>
|
||||||
|
export interface AbstractType<T> extends Function {
|
||||||
|
prototype: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function injectAbstractType<T>(abstractType: AbstractType<T>): T {
|
||||||
|
return inject<T>(abstractType as any);
|
||||||
|
}
|
||||||
4
src/injection/module.ts
Normal file
4
src/injection/module.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import 'reflect-metadata';
|
||||||
|
import type { Injector } from 'injection-js';
|
||||||
|
|
||||||
|
export type Module = (parentInjector: Injector) => Injector;
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
|
import { TestBed } from '@/testing';
|
||||||
import {
|
import {
|
||||||
HTTP_INTERCEPTORS,
|
HTTP_INTERCEPTORS,
|
||||||
HttpClient,
|
HttpClient,
|
||||||
provideHttpClient,
|
provideHttpClient,
|
||||||
withInterceptors,
|
withInterceptors,
|
||||||
withInterceptorsFromDi,
|
withInterceptorsFromDi,
|
||||||
} from '@angular/common/http';
|
} from '@ngify/http';
|
||||||
import {
|
import {
|
||||||
HttpTestingController,
|
HttpTestingController,
|
||||||
provideHttpClientTesting,
|
provideHttpClientTesting,
|
||||||
} from '@angular/common/http/testing';
|
} from '@ngify/http/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { vi } from 'vitest';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
|
||||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||||
import { ConfigurationService } from '../config/config.service';
|
import { ConfigurationService } from '../config/config.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { AuthInterceptor, authInterceptor } from './auth.interceptor';
|
import { AuthInterceptor, authInterceptor } from './auth.interceptor';
|
||||||
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
||||||
|
|
||||||
@@ -85,18 +86,22 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function runTests(): void {
|
function runTests(): void {
|
||||||
it('should add an Authorization header when route matches and token is present', waitForAsync(() => {
|
it('should add an Authorization header when route matches and token is present', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{
|
{
|
||||||
secureRoutes: [actionUrl],
|
secureRoutes: [actionUrl],
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
vi.spyOn(authStateService, 'getAccessToken').mockReturnValue(
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
'thisIsAToken'
|
||||||
|
);
|
||||||
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -108,18 +113,22 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add an Authorization header when `secureRoutes` is not given', waitForAsync(() => {
|
it('should not add an Authorization header when `secureRoutes` is not given', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{
|
{
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
vi.spyOn(authStateService, 'getAccessToken').mockReturnValue(
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
'thisIsAToken'
|
||||||
|
);
|
||||||
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -131,20 +140,24 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add an Authorization header when no routes configured', waitForAsync(() => {
|
it('should not add an Authorization header when no routes configured', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{
|
{
|
||||||
secureRoutes: [],
|
secureRoutes: [],
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
true
|
||||||
|
);
|
||||||
|
vi.spyOn(authStateService, 'getAccessToken').mockReturnValue(
|
||||||
|
'thisIsAToken'
|
||||||
|
);
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -156,19 +169,21 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add an Authorization header when no routes configured', waitForAsync(() => {
|
it('should not add an Authorization header when no routes configured', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{
|
{
|
||||||
secureRoutes: [],
|
secureRoutes: [],
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -180,20 +195,22 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add an Authorization header when route is configured but no token is present', waitForAsync(() => {
|
it('should not add an Authorization header when route is configured but no token is present', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{
|
{
|
||||||
secureRoutes: [actionUrl],
|
secureRoutes: [actionUrl],
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
spyOn(authStateService, 'getAccessToken').and.returnValue('');
|
true
|
||||||
|
);
|
||||||
|
vi.spyOn(authStateService, 'getAccessToken').mockReturnValue('');
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -205,12 +222,14 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add an Authorization header when no config is present', waitForAsync(() => {
|
it('should not add an Authorization header when no config is present', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(false);
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -222,22 +241,24 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should not add an Authorization header when no configured route is matching the request', waitForAsync(() => {
|
it('should not add an Authorization header when no configured route is matching the request', async () => {
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{
|
{
|
||||||
secureRoutes: [actionUrl],
|
secureRoutes: [actionUrl],
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
closestMatchingRouteService,
|
closestMatchingRouteService,
|
||||||
'getConfigIdForClosestMatchingRoute'
|
'getConfigIdForClosestMatchingRoute'
|
||||||
).and.returnValue({
|
).mockReturnValue({
|
||||||
matchingRoute: null,
|
matchingRoute: null,
|
||||||
matchingConfig: null,
|
matchingConfig: null,
|
||||||
});
|
});
|
||||||
@@ -252,18 +273,22 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
|
|
||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should add an Authorization header when multiple routes are configured and token is present', waitForAsync(() => {
|
it('should add an Authorization header when multiple routes are configured and token is present', async () => {
|
||||||
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
const actionUrl = `https://jsonplaceholder.typicode.com/`;
|
||||||
const actionUrl2 = `https://some-other-url.com/`;
|
const actionUrl2 = `https://some-other-url.com/`;
|
||||||
|
|
||||||
spyOn(configurationService, 'getAllConfigurations').and.returnValue([
|
vi.spyOn(configurationService, 'getAllConfigurations').mockReturnValue([
|
||||||
{ secureRoutes: [actionUrl, actionUrl2], configId: 'configId1' },
|
{ secureRoutes: [actionUrl, actionUrl2], configId: 'configId1' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
spyOn(authStateService, 'getAccessToken').and.returnValue('thisIsAToken');
|
vi.spyOn(authStateService, 'getAccessToken').mockReturnValue(
|
||||||
spyOn(configurationService, 'hasAtLeastOneConfig').and.returnValue(true);
|
'thisIsAToken'
|
||||||
|
);
|
||||||
|
vi.spyOn(configurationService, 'hasAtLeastOneConfig').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
httpClient.get(actionUrl).subscribe((response) => {
|
httpClient.get(actionUrl).subscribe((response) => {
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
@@ -284,6 +309,6 @@ describe(`AuthHttpInterceptor`, () => {
|
|||||||
httpRequest.flush('something');
|
httpRequest.flush('something');
|
||||||
httpRequest2.flush('something');
|
httpRequest2.flush('something');
|
||||||
httpTestingController.verify();
|
httpTestingController.verify();
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
import { ClosestMatchingRouteService } from './closest-matching-route.service';
|
||||||
|
|
||||||
describe('ClosestMatchingRouteService', () => {
|
describe('ClosestMatchingRouteService', () => {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { AbstractLoggerService } from './abstract-logger.service';
|
import { AbstractLoggerService } from './abstract-logger.service';
|
||||||
import { ConsoleLoggerService } from './console-logger.service';
|
import { ConsoleLoggerService } from './console-logger.service';
|
||||||
import { LogLevel } from './log-level';
|
import { LogLevel } from './log-level';
|
||||||
@@ -26,7 +27,7 @@ describe('Logger Service', () => {
|
|||||||
|
|
||||||
describe('logError', () => {
|
describe('logError', () => {
|
||||||
it('should not log error if loglevel is None', () => {
|
it('should not log error if loglevel is None', () => {
|
||||||
const spy = spyOn(console, 'error');
|
const spy = vi.spyOn(console, 'error');
|
||||||
|
|
||||||
loggerService.logError(
|
loggerService.logError(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.None },
|
{ configId: 'configId1', logLevel: LogLevel.None },
|
||||||
@@ -36,23 +37,25 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log error as default if error is string', () => {
|
it('should log error as default if error is string', () => {
|
||||||
const spy = spyOn(console, 'error');
|
const spy = vi.spyOn(console, 'error');
|
||||||
|
|
||||||
loggerService.logError({ configId: 'configId1' }, 'some message');
|
loggerService.logError({ configId: 'configId1' }, 'some message');
|
||||||
expect(spy).toHaveBeenCalledOnceWith('[ERROR] configId1 - some message');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'[ERROR] configId1 - some message'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log error as default if error is object', () => {
|
it('should log error as default if error is object', () => {
|
||||||
const spy = spyOn(console, 'error');
|
const spy = vi.spyOn(console, 'error');
|
||||||
|
|
||||||
loggerService.logError({ configId: 'configId1' }, { some: 'message' });
|
loggerService.logError({ configId: 'configId1' }, { some: 'message' });
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'[ERROR] configId1 - {"some":"message"}'
|
'[ERROR] configId1 - {"some":"message"}'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should always log error with args', () => {
|
it('should always log error with args', () => {
|
||||||
const spy = spyOn(console, 'error');
|
const spy = vi.spyOn(console, 'error');
|
||||||
|
|
||||||
loggerService.logError(
|
loggerService.logError(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
@@ -60,7 +63,7 @@ describe('Logger Service', () => {
|
|||||||
'arg1',
|
'arg1',
|
||||||
'arg2'
|
'arg2'
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'[ERROR] configId1 - some message',
|
'[ERROR] configId1 - some message',
|
||||||
'arg1',
|
'arg1',
|
||||||
'arg2'
|
'arg2'
|
||||||
@@ -70,7 +73,7 @@ describe('Logger Service', () => {
|
|||||||
|
|
||||||
describe('logWarn', () => {
|
describe('logWarn', () => {
|
||||||
it('should not log if no log level is set (null)', () => {
|
it('should not log if no log level is set (null)', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: undefined },
|
{ configId: 'configId1', logLevel: undefined },
|
||||||
@@ -80,14 +83,14 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not log if no config is given', () => {
|
it('should not log if no config is given', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning({}, 'some message');
|
loggerService.logWarning({}, 'some message');
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not log if no log level is set (undefined)', () => {
|
it('should not log if no log level is set (undefined)', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning({ configId: 'configId1' }, 'some message');
|
loggerService.logWarning({ configId: 'configId1' }, 'some message');
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not log if log level is turned off', () => {
|
it('should not log if log level is turned off', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.None },
|
{ configId: 'configId1', logLevel: LogLevel.None },
|
||||||
@@ -105,29 +108,31 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log warning when loglevel is Warn and message is string', () => {
|
it('should log warning when loglevel is Warn and message is string', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
||||||
'some message'
|
'some message'
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('[WARN] configId1 - some message');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'[WARN] configId1 - some message'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log warning when loglevel is Warn and message is object', () => {
|
it('should log warning when loglevel is Warn and message is object', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
||||||
{ some: 'message' }
|
{ some: 'message' }
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'[WARN] configId1 - {"some":"message"}'
|
'[WARN] configId1 - {"some":"message"}'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log warning when loglevel is Warn with args', () => {
|
it('should log warning when loglevel is Warn with args', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
||||||
@@ -135,7 +140,7 @@ describe('Logger Service', () => {
|
|||||||
'arg1',
|
'arg1',
|
||||||
'arg2'
|
'arg2'
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'[WARN] configId1 - some message',
|
'[WARN] configId1 - some message',
|
||||||
'arg1',
|
'arg1',
|
||||||
'arg2'
|
'arg2'
|
||||||
@@ -143,17 +148,19 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log warning when loglevel is Debug', () => {
|
it('should log warning when loglevel is Debug', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
||||||
'some message'
|
'some message'
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('[WARN] configId1 - some message');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'[WARN] configId1 - some message'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not log warning when loglevel is error', () => {
|
it('should not log warning when loglevel is error', () => {
|
||||||
const spy = spyOn(console, 'warn');
|
const spy = vi.spyOn(console, 'warn');
|
||||||
|
|
||||||
loggerService.logWarning(
|
loggerService.logWarning(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Error },
|
{ configId: 'configId1', logLevel: LogLevel.Error },
|
||||||
@@ -165,7 +172,7 @@ describe('Logger Service', () => {
|
|||||||
|
|
||||||
describe('logDebug', () => {
|
describe('logDebug', () => {
|
||||||
it('should not log if no log level is set (null)', () => {
|
it('should not log if no log level is set (null)', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: undefined },
|
{ configId: 'configId1', logLevel: undefined },
|
||||||
@@ -175,14 +182,14 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not log if no log level is set (undefined)', () => {
|
it('should not log if no log level is set (undefined)', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug({ configId: 'configId1' }, 'some message');
|
loggerService.logDebug({ configId: 'configId1' }, 'some message');
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not log if log level is turned off', () => {
|
it('should not log if log level is turned off', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.None },
|
{ configId: 'configId1', logLevel: LogLevel.None },
|
||||||
@@ -192,29 +199,31 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log when loglevel is Debug and value is string', () => {
|
it('should log when loglevel is Debug and value is string', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
||||||
'some message'
|
'some message'
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('[DEBUG] configId1 - some message');
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'[DEBUG] configId1 - some message'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log when loglevel is Debug and value is object', () => {
|
it('should log when loglevel is Debug and value is object', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
||||||
{ some: 'message' }
|
{ some: 'message' }
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'[DEBUG] configId1 - {"some":"message"}'
|
'[DEBUG] configId1 - {"some":"message"}'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log when loglevel is Debug with args', () => {
|
it('should log when loglevel is Debug with args', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
{ configId: 'configId1', logLevel: LogLevel.Debug },
|
||||||
@@ -222,7 +231,7 @@ describe('Logger Service', () => {
|
|||||||
'arg1',
|
'arg1',
|
||||||
'arg2'
|
'arg2'
|
||||||
);
|
);
|
||||||
expect(spy).toHaveBeenCalledOnceWith(
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'[DEBUG] configId1 - some message',
|
'[DEBUG] configId1 - some message',
|
||||||
'arg1',
|
'arg1',
|
||||||
'arg2'
|
'arg2'
|
||||||
@@ -230,7 +239,7 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not log when loglevel is Warn', () => {
|
it('should not log when loglevel is Warn', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
{ configId: 'configId1', logLevel: LogLevel.Warn },
|
||||||
@@ -240,7 +249,7 @@ describe('Logger Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not log when loglevel is error', () => {
|
it('should not log when loglevel is error', () => {
|
||||||
const spy = spyOn(console, 'debug');
|
const spy = vi.spyOn(console, 'debug');
|
||||||
|
|
||||||
loggerService.logDebug(
|
loggerService.logDebug(
|
||||||
{ configId: 'configId1', logLevel: LogLevel.Error },
|
{ configId: 'configId1', logLevel: LogLevel.Error },
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable } from 'injection-js';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
|
import { injectAbstractType } from '../injection/inject';
|
||||||
import { AbstractLoggerService } from './abstract-logger.service';
|
import { AbstractLoggerService } from './abstract-logger.service';
|
||||||
import { LogLevel } from './log-level';
|
import { LogLevel } from './log-level';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LoggerService {
|
export class LoggerService {
|
||||||
private readonly abstractLoggerService = inject(AbstractLoggerService);
|
private readonly abstractLoggerService = injectAbstractType(
|
||||||
|
AbstractLoggerService
|
||||||
|
);
|
||||||
|
|
||||||
logError(
|
logError(
|
||||||
configuration: OpenIdConfiguration,
|
configuration: OpenIdConfiguration,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import { TestBed } from '@/testing';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
import { LoginResponse } from './login-response';
|
import { mockProvider } from '../testing/mock';
|
||||||
|
import type { LoginResponse } from './login-response';
|
||||||
import { LoginService } from './login.service';
|
import { LoginService } from './login.service';
|
||||||
import { ParLoginService } from './par/par-login.service';
|
import { ParLoginService } from './par/par-login.service';
|
||||||
import { PopUpLoginService } from './popup/popup-login.service';
|
import { PopUpLoginService } from './popup/popup-login.service';
|
||||||
@@ -48,8 +49,8 @@ describe('LoginService', () => {
|
|||||||
describe('login', () => {
|
describe('login', () => {
|
||||||
it('calls parLoginService loginPar if usePushedAuthorisationRequests is true', () => {
|
it('calls parLoginService loginPar if usePushedAuthorisationRequests is true', () => {
|
||||||
const config = { usePushedAuthorisationRequests: true };
|
const config = { usePushedAuthorisationRequests: true };
|
||||||
const loginParSpy = spyOn(parLoginService, 'loginPar');
|
const loginParSpy = vi.spyOn(parLoginService, 'loginPar');
|
||||||
const standardLoginSpy = spyOn(standardLoginService, 'loginStandard');
|
const standardLoginSpy = vi.spyOn(standardLoginService, 'loginStandard');
|
||||||
|
|
||||||
service.login(config);
|
service.login(config);
|
||||||
|
|
||||||
@@ -59,8 +60,8 @@ describe('LoginService', () => {
|
|||||||
|
|
||||||
it('calls standardLoginService loginStandard if usePushedAuthorisationRequests is false', () => {
|
it('calls standardLoginService loginStandard if usePushedAuthorisationRequests is false', () => {
|
||||||
const config = { usePushedAuthorisationRequests: false };
|
const config = { usePushedAuthorisationRequests: false };
|
||||||
const loginParSpy = spyOn(parLoginService, 'loginPar');
|
const loginParSpy = vi.spyOn(parLoginService, 'loginPar');
|
||||||
const standardLoginSpy = spyOn(standardLoginService, 'loginStandard');
|
const standardLoginSpy = vi.spyOn(standardLoginService, 'loginStandard');
|
||||||
|
|
||||||
service.login(config);
|
service.login(config);
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ describe('LoginService', () => {
|
|||||||
it('stores the customParams to the storage if customParams are given', () => {
|
it('stores the customParams to the storage if customParams are given', () => {
|
||||||
// arrange
|
// arrange
|
||||||
const config = { usePushedAuthorisationRequests: false };
|
const config = { usePushedAuthorisationRequests: false };
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
@@ -79,7 +80,7 @@ describe('LoginService', () => {
|
|||||||
|
|
||||||
service.login(config, authOptions);
|
service.login(config, authOptions);
|
||||||
|
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledOnceWith(
|
expect(storagePersistenceServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'storageCustomParamsAuthRequest',
|
'storageCustomParamsAuthRequest',
|
||||||
{ custom: 'params' },
|
{ custom: 'params' },
|
||||||
config
|
config
|
||||||
@@ -89,8 +90,8 @@ describe('LoginService', () => {
|
|||||||
it("should throw error if configuration is null and doesn't call loginPar or loginStandard", () => {
|
it("should throw error if configuration is null and doesn't call loginPar or loginStandard", () => {
|
||||||
// arrange
|
// arrange
|
||||||
const config = null;
|
const config = null;
|
||||||
const loginParSpy = spyOn(parLoginService, 'loginPar');
|
const loginParSpy = vi.spyOn(parLoginService, 'loginPar');
|
||||||
const standardLoginSpy = spyOn(standardLoginService, 'loginStandard');
|
const standardLoginSpy = vi.spyOn(standardLoginService, 'loginStandard');
|
||||||
const authOptions = { customParams: { custom: 'params' } };
|
const authOptions = { customParams: { custom: 'params' } };
|
||||||
|
|
||||||
// act
|
// act
|
||||||
@@ -106,17 +107,15 @@ describe('LoginService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('loginWithPopUp', () => {
|
describe('loginWithPopUp', () => {
|
||||||
it('calls parLoginService loginWithPopUpPar if usePushedAuthorisationRequests is true', waitForAsync(() => {
|
it('calls parLoginService loginWithPopUpPar if usePushedAuthorisationRequests is true', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const config = { usePushedAuthorisationRequests: true };
|
const config = { usePushedAuthorisationRequests: true };
|
||||||
const loginWithPopUpPar = spyOn(
|
const loginWithPopUpPar = vi
|
||||||
parLoginService,
|
.spyOn(parLoginService, 'loginWithPopUpPar')
|
||||||
'loginWithPopUpPar'
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
).and.returnValue(of({} as LoginResponse));
|
const loginWithPopUpStandardSpy = vi
|
||||||
const loginWithPopUpStandardSpy = spyOn(
|
.spyOn(popUpLoginService, 'loginWithPopUpStandard')
|
||||||
popUpLoginService,
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
'loginWithPopUpStandard'
|
|
||||||
).and.returnValue(of({} as LoginResponse));
|
|
||||||
|
|
||||||
// act
|
// act
|
||||||
service.loginWithPopUp(config, [config]).subscribe(() => {
|
service.loginWithPopUp(config, [config]).subscribe(() => {
|
||||||
@@ -124,19 +123,17 @@ describe('LoginService', () => {
|
|||||||
expect(loginWithPopUpPar).toHaveBeenCalledTimes(1);
|
expect(loginWithPopUpPar).toHaveBeenCalledTimes(1);
|
||||||
expect(loginWithPopUpStandardSpy).not.toHaveBeenCalled();
|
expect(loginWithPopUpStandardSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls standardLoginService loginstandard if usePushedAuthorisationRequests is false', waitForAsync(() => {
|
it('calls standardLoginService loginstandard if usePushedAuthorisationRequests is false', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const config = { usePushedAuthorisationRequests: false };
|
const config = { usePushedAuthorisationRequests: false };
|
||||||
const loginWithPopUpPar = spyOn(
|
const loginWithPopUpPar = vi
|
||||||
parLoginService,
|
.spyOn(parLoginService, 'loginWithPopUpPar')
|
||||||
'loginWithPopUpPar'
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
).and.returnValue(of({} as LoginResponse));
|
const loginWithPopUpStandardSpy = vi
|
||||||
const loginWithPopUpStandardSpy = spyOn(
|
.spyOn(popUpLoginService, 'loginWithPopUpStandard')
|
||||||
popUpLoginService,
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
'loginWithPopUpStandard'
|
|
||||||
).and.returnValue(of({} as LoginResponse));
|
|
||||||
|
|
||||||
// act
|
// act
|
||||||
service.loginWithPopUp(config, [config]).subscribe(() => {
|
service.loginWithPopUp(config, [config]).subscribe(() => {
|
||||||
@@ -144,46 +141,44 @@ describe('LoginService', () => {
|
|||||||
expect(loginWithPopUpPar).not.toHaveBeenCalled();
|
expect(loginWithPopUpPar).not.toHaveBeenCalled();
|
||||||
expect(loginWithPopUpStandardSpy).toHaveBeenCalledTimes(1);
|
expect(loginWithPopUpStandardSpy).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('stores the customParams to the storage if customParams are given', waitForAsync(() => {
|
it('stores the customParams to the storage if customParams are given', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const config = { usePushedAuthorisationRequests: false };
|
const config = { usePushedAuthorisationRequests: false };
|
||||||
const storagePersistenceServiceSpy = spyOn(
|
const storagePersistenceServiceSpy = vi.spyOn(
|
||||||
storagePersistenceService,
|
storagePersistenceService,
|
||||||
'write'
|
'write'
|
||||||
);
|
);
|
||||||
const authOptions = { customParams: { custom: 'params' } };
|
const authOptions = { customParams: { custom: 'params' } };
|
||||||
|
|
||||||
spyOn(popUpLoginService, 'loginWithPopUpStandard').and.returnValue(
|
vi.spyOn(popUpLoginService, 'loginWithPopUpStandard').mockReturnValue(
|
||||||
of({} as LoginResponse)
|
of({} as LoginResponse)
|
||||||
);
|
);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
service.loginWithPopUp(config, [config], authOptions).subscribe(() => {
|
service.loginWithPopUp(config, [config], authOptions).subscribe(() => {
|
||||||
// assert
|
// assert
|
||||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledOnceWith(
|
expect(storagePersistenceServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'storageCustomParamsAuthRequest',
|
'storageCustomParamsAuthRequest',
|
||||||
{ custom: 'params' },
|
{ custom: 'params' },
|
||||||
config
|
config
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns error if there is already a popup open', () => {
|
it('returns error if there is already a popup open', () => {
|
||||||
// arrange
|
// arrange
|
||||||
const config = { usePushedAuthorisationRequests: false };
|
const config = { usePushedAuthorisationRequests: false };
|
||||||
const authOptions = { customParams: { custom: 'params' } };
|
const authOptions = { customParams: { custom: 'params' } };
|
||||||
const loginWithPopUpPar = spyOn(
|
const loginWithPopUpPar = vi
|
||||||
parLoginService,
|
.spyOn(parLoginService, 'loginWithPopUpPar')
|
||||||
'loginWithPopUpPar'
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
).and.returnValue(of({} as LoginResponse));
|
const loginWithPopUpStandardSpy = vi
|
||||||
const loginWithPopUpStandardSpy = spyOn(
|
.spyOn(popUpLoginService, 'loginWithPopUpStandard')
|
||||||
popUpLoginService,
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
'loginWithPopUpStandard'
|
|
||||||
).and.returnValue(of({} as LoginResponse));
|
|
||||||
|
|
||||||
spyOn(popUpService, 'isCurrentlyInPopup').and.returnValue(true);
|
vi.spyOn(popUpService, 'isCurrentlyInPopup').mockReturnValue(true);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
service
|
service
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, of } from 'rxjs';
|
import { type Observable, of } from 'rxjs';
|
||||||
import { AuthOptions } from '../auth-options';
|
import type { AuthOptions } from '../auth-options';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
import { LoginResponse } from './login-response';
|
import type { LoginResponse } from './login-response';
|
||||||
import { ParLoginService } from './par/par-login.service';
|
import { ParLoginService } from './par/par-login.service';
|
||||||
import { PopUpLoginService } from './popup/popup-login.service';
|
import { PopUpLoginService } from './popup/popup-login.service';
|
||||||
import { PopupOptions } from './popup/popup-options';
|
import type { PopupOptions } from './popup/popup-options';
|
||||||
import { PopUpService } from './popup/popup.service';
|
import { PopUpService } from './popup/popup.service';
|
||||||
import { StandardLoginService } from './standard/standard-login.service';
|
import { StandardLoginService } from './standard/standard-login.service';
|
||||||
|
|
||||||
@@ -45,12 +45,9 @@ export class LoginService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (usePushedAuthorisationRequests) {
|
if (usePushedAuthorisationRequests) {
|
||||||
return this.parLoginService.loginPar(configuration, authOptions);
|
this.parLoginService.loginPar(configuration, authOptions);
|
||||||
} else {
|
} else {
|
||||||
return this.standardLoginService.loginStandard(
|
this.standardLoginService.loginStandard(configuration, authOptions);
|
||||||
configuration,
|
|
||||||
authOptions
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
||||||
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { RedirectService } from '../../utils/redirect/redirect.service';
|
import { RedirectService } from '../../utils/redirect/redirect.service';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { LoginResponse } from '../login-response';
|
import type { LoginResponse } from '../login-response';
|
||||||
import { PopupResult } from '../popup/popup-result';
|
import type { PopupResult } from '../popup/popup-result';
|
||||||
import { PopUpService } from '../popup/popup.service';
|
import { PopUpService } from '../popup/popup.service';
|
||||||
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
||||||
import { ParLoginService } from './par-login.service';
|
import { ParLoginService } from './par-login.service';
|
||||||
import { ParResponse } from './par-response';
|
import type { ParResponse } from './par-response';
|
||||||
import { ParService } from './par.service';
|
import { ParService } from './par.service';
|
||||||
|
|
||||||
describe('ParLoginService', () => {
|
describe('ParLoginService', () => {
|
||||||
@@ -60,33 +61,33 @@ describe('ParLoginService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('loginPar', () => {
|
describe('loginPar', () => {
|
||||||
it('does nothing if it has an invalid response type', waitForAsync(() => {
|
it('does nothing if it has an invalid response type', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
const result = service.loginPar({});
|
const result = service.loginPar({});
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls parService.postParRequest without custom params when no custom params are passed', waitForAsync(() => {
|
it('calls parService.postParRequest without custom params when no custom params are passed', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
const spy = spyOn(parService, 'postParRequest').and.returnValue(
|
const spy = vi
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
.spyOn(parService, 'postParRequest')
|
||||||
);
|
.mockReturnValue(of({ requestUri: 'requestUri' } as ParResponse));
|
||||||
|
|
||||||
const result = service.loginPar({
|
const result = service.loginPar({
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
@@ -95,69 +96,69 @@ describe('ParLoginService', () => {
|
|||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls parService.postParRequest with custom params when custom params are passed', waitForAsync(() => {
|
it('calls parService.postParRequest with custom params when custom params are passed', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
const spy = spyOn(parService, 'postParRequest').and.returnValue(
|
const spy = vi
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
.spyOn(parService, 'postParRequest')
|
||||||
);
|
.mockReturnValue(of({ requestUri: 'requestUri' } as ParResponse));
|
||||||
|
|
||||||
const result = service.loginPar(config, {
|
const result = service.loginPar(config, {
|
||||||
customParams: { some: 'thing' },
|
customParams: { some: 'thing' },
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(spy).toHaveBeenCalledOnceWith(config, {
|
expect(spy).toHaveBeenCalledExactlyOnceWith(config, {
|
||||||
customParams: { some: 'thing' },
|
customParams: { some: 'thing' },
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns undefined and logs error when no url could be created', waitForAsync(() => {
|
it('returns undefined and logs error when no url could be created', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue('');
|
||||||
const spy = spyOn(loggerService, 'logError');
|
const spy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
const result = service.loginPar(config);
|
const result = service.loginPar(config);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls redirect service redirectTo when url could be created', waitForAsync(() => {
|
it('calls redirect service redirectTo when url could be created', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
@@ -165,42 +166,46 @@ describe('ParLoginService', () => {
|
|||||||
|
|
||||||
const authOptions = {};
|
const authOptions = {};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('some-par-url');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue(
|
||||||
const spy = spyOn(redirectService, 'redirectTo');
|
'some-par-url'
|
||||||
|
);
|
||||||
|
const spy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
|
|
||||||
service.loginPar(config, authOptions);
|
service.loginPar(config, authOptions);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('some-par-url');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('some-par-url');
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls urlHandler when URL is passed', waitForAsync(() => {
|
it('calls urlHandler when URL is passed', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('some-par-url');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue(
|
||||||
const redirectToSpy = spyOn(redirectService, 'redirectTo');
|
'some-par-url'
|
||||||
|
);
|
||||||
|
const redirectToSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
const spy = jasmine.createSpy();
|
const spy = jasmine.createSpy();
|
||||||
const urlHandler = (url: any): void => {
|
const urlHandler = (url: any): void => {
|
||||||
spy(url);
|
spy(url);
|
||||||
@@ -208,18 +213,18 @@ describe('ParLoginService', () => {
|
|||||||
|
|
||||||
service.loginPar(config, { urlHandler });
|
service.loginPar(config, { urlHandler });
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('some-par-url');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('some-par-url');
|
||||||
expect(redirectToSpy).not.toHaveBeenCalled();
|
expect(redirectToSpy).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('loginWithPopUpPar', () => {
|
describe('loginWithPopUpPar', () => {
|
||||||
it('does nothing if it has an invalid response type', waitForAsync(() => {
|
it('does nothing if it has an invalid response type', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const config = {};
|
const config = {};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
@@ -229,27 +234,27 @@ describe('ParLoginService', () => {
|
|||||||
expect(err.message).toBe('Invalid response type!');
|
expect(err.message).toBe('Invalid response type!');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls parService.postParRequest without custom params when no custom params are passed', waitForAsync(() => {
|
it('calls parService.postParRequest without custom params when no custom params are passed', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
const spy = spyOn(parService, 'postParRequest').and.returnValue(
|
const spy = vi
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
.spyOn(parService, 'postParRequest')
|
||||||
);
|
.mockReturnValue(of({ requestUri: 'requestUri' } as ParResponse));
|
||||||
|
|
||||||
service.loginWithPopUpPar(config, allConfigs).subscribe({
|
service.loginWithPopUpPar(config, allConfigs).subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
@@ -259,27 +264,27 @@ describe('ParLoginService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls parService.postParRequest with custom params when custom params are passed', waitForAsync(() => {
|
it('calls parService.postParRequest with custom params when custom params are passed', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
const spy = spyOn(parService, 'postParRequest').and.returnValue(
|
const spy = vi
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
.spyOn(parService, 'postParRequest')
|
||||||
);
|
.mockReturnValue(of({ requestUri: 'requestUri' } as ParResponse));
|
||||||
|
|
||||||
service
|
service
|
||||||
.loginWithPopUpPar(config, allConfigs, {
|
.loginWithPopUpPar(config, allConfigs, {
|
||||||
@@ -287,7 +292,7 @@ describe('ParLoginService', () => {
|
|||||||
})
|
})
|
||||||
.subscribe({
|
.subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith(config, {
|
expect(spy).toHaveBeenCalledExactlyOnceWith(config, {
|
||||||
customParams: { some: 'thing' },
|
customParams: { some: 'thing' },
|
||||||
});
|
});
|
||||||
expect(err.message).toBe(
|
expect(err.message).toBe(
|
||||||
@@ -295,29 +300,29 @@ describe('ParLoginService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns undefined and logs error when no URL could be created', waitForAsync(() => {
|
it('returns undefined and logs error when no URL could be created', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue('');
|
||||||
const spy = spyOn(loggerService, 'logError');
|
const spy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
service
|
service
|
||||||
.loginWithPopUpPar(config, allConfigs, {
|
.loginWithPopUpPar(config, allConfigs, {
|
||||||
@@ -331,46 +336,52 @@ describe('ParLoginService', () => {
|
|||||||
expect(spy).toHaveBeenCalledTimes(1);
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls popupService openPopUp when URL could be created', waitForAsync(() => {
|
it('calls popupService openPopUp when URL could be created', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('some-par-url');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue(
|
||||||
spyOn(checkAuthService, 'checkAuth').and.returnValue(
|
'some-par-url'
|
||||||
|
);
|
||||||
|
vi.spyOn(checkAuthService, 'checkAuth').mockReturnValue(
|
||||||
of({} as LoginResponse)
|
of({} as LoginResponse)
|
||||||
);
|
);
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
of({} as PopupResult)
|
of({} as PopupResult)
|
||||||
);
|
);
|
||||||
const spy = spyOn(popupService, 'openPopUp');
|
const spy = vi.spyOn(popupService, 'openPopUp');
|
||||||
|
|
||||||
service.loginWithPopUpPar(config, allConfigs).subscribe(() => {
|
service.loginWithPopUpPar(config, allConfigs).subscribe(() => {
|
||||||
expect(spy).toHaveBeenCalledOnceWith('some-par-url', undefined, config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||||
|
'some-par-url',
|
||||||
|
undefined,
|
||||||
|
config
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns correct properties if URL is received', waitForAsync(() => {
|
it('returns correct properties if URL is received', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
@@ -378,34 +389,40 @@ describe('ParLoginService', () => {
|
|||||||
};
|
};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('some-par-url');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue(
|
||||||
|
'some-par-url'
|
||||||
const checkAuthSpy = spyOn(checkAuthService, 'checkAuth').and.returnValue(
|
|
||||||
of({
|
|
||||||
isAuthenticated: true,
|
|
||||||
configId: 'configId1',
|
|
||||||
idToken: '',
|
|
||||||
userData: { any: 'userData' },
|
|
||||||
accessToken: 'anyAccessToken',
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const checkAuthSpy = vi
|
||||||
|
.spyOn(checkAuthService, 'checkAuth')
|
||||||
|
.mockReturnValue(
|
||||||
|
of({
|
||||||
|
isAuthenticated: true,
|
||||||
|
configId: 'configId1',
|
||||||
|
idToken: '',
|
||||||
|
userData: { any: 'userData' },
|
||||||
|
accessToken: 'anyAccessToken',
|
||||||
|
})
|
||||||
|
);
|
||||||
const popupResult: PopupResult = {
|
const popupResult: PopupResult = {
|
||||||
userClosed: false,
|
userClosed: false,
|
||||||
receivedUrl: 'someUrl',
|
receivedUrl: 'someUrl',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(of(popupResult));
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
|
of(popupResult)
|
||||||
|
);
|
||||||
|
|
||||||
service.loginWithPopUpPar(config, allConfigs).subscribe((result) => {
|
service.loginWithPopUpPar(config, allConfigs).subscribe((result) => {
|
||||||
expect(checkAuthSpy).toHaveBeenCalledOnceWith(
|
expect(checkAuthSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
allConfigs,
|
allConfigs,
|
||||||
'someUrl'
|
'someUrl'
|
||||||
@@ -419,13 +436,13 @@ describe('ParLoginService', () => {
|
|||||||
accessToken: 'anyAccessToken',
|
accessToken: 'anyAccessToken',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns correct properties if popup was closed by user', waitForAsync(() => {
|
it('returns correct properties if popup was closed by user', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
@@ -433,20 +450,24 @@ describe('ParLoginService', () => {
|
|||||||
};
|
};
|
||||||
const allConfigs = [config];
|
const allConfigs = [config];
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
|
|
||||||
spyOn(parService, 'postParRequest').and.returnValue(
|
vi.spyOn(parService, 'postParRequest').mockReturnValue(
|
||||||
of({ requestUri: 'requestUri' } as ParResponse)
|
of({ requestUri: 'requestUri' } as ParResponse)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeParUrl').and.returnValue('some-par-url');
|
vi.spyOn(urlService, 'getAuthorizeParUrl').mockReturnValue(
|
||||||
|
'some-par-url'
|
||||||
|
);
|
||||||
|
|
||||||
const checkAuthSpy = spyOn(checkAuthService, 'checkAuth');
|
const checkAuthSpy = vi.spyOn(checkAuthService, 'checkAuth');
|
||||||
const popupResult = { userClosed: true } as PopupResult;
|
const popupResult = { userClosed: true } as PopupResult;
|
||||||
|
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(of(popupResult));
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
|
of(popupResult)
|
||||||
|
);
|
||||||
|
|
||||||
service.loginWithPopUpPar(config, allConfigs).subscribe((result) => {
|
service.loginWithPopUpPar(config, allConfigs).subscribe((result) => {
|
||||||
expect(checkAuthSpy).not.toHaveBeenCalled();
|
expect(checkAuthSpy).not.toHaveBeenCalled();
|
||||||
@@ -459,6 +480,6 @@ describe('ParLoginService', () => {
|
|||||||
accessToken: '',
|
accessToken: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { type Observable, of, throwError } from 'rxjs';
|
||||||
import { switchMap, take } from 'rxjs/operators';
|
import { switchMap, take } from 'rxjs/operators';
|
||||||
import { AuthOptions } from '../../auth-options';
|
import type { AuthOptions } from '../../auth-options';
|
||||||
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
||||||
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { RedirectService } from '../../utils/redirect/redirect.service';
|
import { RedirectService } from '../../utils/redirect/redirect.service';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { LoginResponse } from '../login-response';
|
import type { LoginResponse } from '../login-response';
|
||||||
import { PopupOptions } from '../popup/popup-options';
|
import type { PopupOptions } from '../popup/popup-options';
|
||||||
import { PopupResult } from '../popup/popup-result';
|
import type { PopupResult } from '../popup/popup-result';
|
||||||
import { PopUpService } from '../popup/popup.service';
|
import { PopUpService } from '../popup/popup.service';
|
||||||
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
||||||
import { ParResponse } from './par-response';
|
import type { ParResponse } from './par-response';
|
||||||
import { ParService } from './par.service';
|
import { ParService } from './par.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { HttpHeaders } from '@angular/common/http';
|
import { TestBed } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { HttpHeaders } from '@ngify/http';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { createRetriableStream } from '../../../test/create-retriable-stream.helper';
|
|
||||||
import { DataService } from '../../api/data.service';
|
import { DataService } from '../../api/data.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
|
import { createRetriableStream } from '../../testing/create-retriable-stream.helper';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { ParService } from './par.service';
|
import { ParService } from './par.service';
|
||||||
|
|
||||||
@@ -40,13 +41,15 @@ describe('ParService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('postParRequest', () => {
|
describe('postParRequest', () => {
|
||||||
it('throws error if authWellKnownEndPoints does not exist in storage', waitForAsync(() => {
|
it('throws error if authWellKnownEndPoints does not exist in storage', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of(null)
|
of(null)
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue(null);
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => null
|
||||||
|
);
|
||||||
service.postParRequest({ configId: 'configId1' }).subscribe({
|
service.postParRequest({ configId: 'configId1' }).subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err.message).toBe(
|
expect(err.message).toBe(
|
||||||
@@ -54,15 +57,17 @@ describe('ParService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if par endpoint does not exist in storage', waitForAsync(() => {
|
it('throws error if par endpoint does not exist in storage', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of(null)
|
of(null)
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ some: 'thing' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ some: 'thing' })
|
||||||
|
);
|
||||||
service.postParRequest({ configId: 'configId1' }).subscribe({
|
service.postParRequest({ configId: 'configId1' }).subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err.message).toBe(
|
expect(err.message).toBe(
|
||||||
@@ -70,77 +75,87 @@ describe('ParService', () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls data service with correct params', waitForAsync(() => {
|
it('calls data service with correct params', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of('some-url123')
|
of('some-url123')
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ parEndpoint: 'parEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
|
() => ({ parEndpoint: 'parEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
const dataServiceSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
const dataServiceSpy = vi
|
||||||
|
.spyOn(dataService, 'post')
|
||||||
|
.mockReturnValue(of({}));
|
||||||
|
|
||||||
service.postParRequest({ configId: 'configId1' }).subscribe(() => {
|
service.postParRequest({ configId: 'configId1' }).subscribe(() => {
|
||||||
expect(dataServiceSpy).toHaveBeenCalledOnceWith(
|
expect(dataServiceSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'parEndpoint',
|
'parEndpoint',
|
||||||
'some-url123',
|
'some-url123',
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
jasmine.any(HttpHeaders)
|
expect.any(HttpHeaders)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('Gives back correct object properties', waitForAsync(() => {
|
it('Gives back correct object properties', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of('some-url456')
|
of('some-url456')
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ parEndpoint: 'parEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
() => ({ parEndpoint: 'parEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
of({ expires_in: 123, request_uri: 'request_uri' })
|
of({ expires_in: 123, request_uri: 'request_uri' })
|
||||||
);
|
);
|
||||||
service.postParRequest({ configId: 'configId1' }).subscribe((result) => {
|
service.postParRequest({ configId: 'configId1' }).subscribe((result) => {
|
||||||
expect(result).toEqual({ expiresIn: 123, requestUri: 'request_uri' });
|
expect(result).toEqual({ expiresIn: 123, requestUri: 'request_uri' });
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('throws error if data service has got an error', waitForAsync(() => {
|
it('throws error if data service has got an error', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of('some-url789')
|
of('some-url789')
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ parEndpoint: 'parEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
() => ({ parEndpoint: 'parEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
throwError(() => new Error('ERROR'))
|
throwError(() => new Error('ERROR'))
|
||||||
);
|
);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
service.postParRequest({ configId: 'configId1' }).subscribe({
|
service.postParRequest({ configId: 'configId1' }).subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
expect(err.message).toBe(
|
expect(err.message).toBe(
|
||||||
'There was an error on ParService postParRequest'
|
'There was an error on ParService postParRequest'
|
||||||
);
|
);
|
||||||
expect(loggerSpy).toHaveBeenCalledOnceWith(
|
expect(loggerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'There was an error on ParService postParRequest',
|
'There was an error on ParService postParRequest',
|
||||||
jasmine.any(Error)
|
expect.any(Error)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry once', waitForAsync(() => {
|
it('should retry once', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of('some-url456')
|
of('some-url456')
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ parEndpoint: 'parEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
() => ({ parEndpoint: 'parEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('ERROR')),
|
throwError(() => new Error('ERROR')),
|
||||||
of({ expires_in: 123, request_uri: 'request_uri' })
|
of({ expires_in: 123, request_uri: 'request_uri' })
|
||||||
@@ -153,16 +168,18 @@ describe('ParService', () => {
|
|||||||
expect(res).toEqual({ expiresIn: 123, requestUri: 'request_uri' });
|
expect(res).toEqual({ expiresIn: 123, requestUri: 'request_uri' });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry twice', waitForAsync(() => {
|
it('should retry twice', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of('some-url456')
|
of('some-url456')
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ parEndpoint: 'parEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
() => ({ parEndpoint: 'parEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('ERROR')),
|
throwError(() => new Error('ERROR')),
|
||||||
throwError(() => new Error('ERROR')),
|
throwError(() => new Error('ERROR')),
|
||||||
@@ -176,16 +193,18 @@ describe('ParService', () => {
|
|||||||
expect(res).toEqual({ expiresIn: 123, requestUri: 'request_uri' });
|
expect(res).toEqual({ expiresIn: 123, requestUri: 'request_uri' });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should fail after three tries', waitForAsync(() => {
|
it('should fail after three tries', async () => {
|
||||||
spyOn(urlService, 'createBodyForParCodeFlowRequest').and.returnValue(
|
vi.spyOn(urlService, 'createBodyForParCodeFlowRequest').mockReturnValue(
|
||||||
of('some-url456')
|
of('some-url456')
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ parEndpoint: 'parEndpoint' });
|
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
() => ({ parEndpoint: 'parEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('ERROR')),
|
throwError(() => new Error('ERROR')),
|
||||||
throwError(() => new Error('ERROR')),
|
throwError(() => new Error('ERROR')),
|
||||||
@@ -199,6 +218,6 @@ describe('ParService', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
|
import { TestBed } from '@/testing';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
||||||
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { LoginResponse } from '../login-response';
|
import type { LoginResponse } from '../login-response';
|
||||||
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
||||||
import { PopUpLoginService } from './popup-login.service';
|
import { PopUpLoginService } from './popup-login.service';
|
||||||
import { PopupResult } from './popup-result';
|
import type { PopupResult } from './popup-result';
|
||||||
import { PopUpService } from './popup.service';
|
import { PopUpService } from './popup.service';
|
||||||
|
|
||||||
describe('PopUpLoginService', () => {
|
describe('PopUpLoginService', () => {
|
||||||
@@ -53,14 +54,14 @@ describe('PopUpLoginService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('loginWithPopUpStandard', () => {
|
describe('loginWithPopUpStandard', () => {
|
||||||
it('does nothing if it has an invalid response type', waitForAsync(() => {
|
it('does nothing if it has an invalid response type', async () => {
|
||||||
const config = { responseType: 'stubValue' };
|
const config = { responseType: 'stubValue' };
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypValidationService,
|
responseTypValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
popUpLoginService.loginWithPopUpStandard(config, [config]).subscribe({
|
popUpLoginService.loginWithPopUpStandard(config, [config]).subscribe({
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
@@ -68,27 +69,27 @@ describe('PopUpLoginService', () => {
|
|||||||
expect(err.message).toBe('Invalid response type!');
|
expect(err.message).toBe('Invalid response type!');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls urlService.getAuthorizeUrl() if everything fits', waitForAsync(() => {
|
it('calls urlService.getAuthorizeUrl() if everything fits', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypValidationService,
|
responseTypValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
of({} as PopupResult)
|
of({} as PopupResult)
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
spyOn(checkAuthService, 'checkAuth').and.returnValue(
|
vi.spyOn(checkAuthService, 'checkAuth').mockReturnValue(
|
||||||
of({} as LoginResponse)
|
of({} as LoginResponse)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -97,74 +98,78 @@ describe('PopUpLoginService', () => {
|
|||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(urlService.getAuthorizeUrl).toHaveBeenCalled();
|
expect(urlService.getAuthorizeUrl).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('opens popup if everything fits', waitForAsync(() => {
|
it('opens popup if everything fits', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypValidationService,
|
responseTypValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
of({} as PopupResult)
|
of({} as PopupResult)
|
||||||
);
|
);
|
||||||
spyOn(checkAuthService, 'checkAuth').and.returnValue(
|
vi.spyOn(checkAuthService, 'checkAuth').mockReturnValue(
|
||||||
of({} as LoginResponse)
|
of({} as LoginResponse)
|
||||||
);
|
);
|
||||||
const popupSpy = spyOn(popupService, 'openPopUp');
|
const popupSpy = vi.spyOn(popupService, 'openPopUp');
|
||||||
|
|
||||||
popUpLoginService
|
popUpLoginService
|
||||||
.loginWithPopUpStandard(config, [config])
|
.loginWithPopUpStandard(config, [config])
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
expect(popupSpy).toHaveBeenCalled();
|
expect(popupSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns three properties when popupservice received an url', waitForAsync(() => {
|
it('returns three properties when popupservice received an url', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypValidationService,
|
responseTypValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
spyOn(popupService, 'openPopUp');
|
vi.spyOn(popupService, 'openPopUp');
|
||||||
const checkAuthSpy = spyOn(checkAuthService, 'checkAuth').and.returnValue(
|
const checkAuthSpy = vi
|
||||||
of({
|
.spyOn(checkAuthService, 'checkAuth')
|
||||||
isAuthenticated: true,
|
.mockReturnValue(
|
||||||
configId: 'configId1',
|
of({
|
||||||
idToken: '',
|
isAuthenticated: true,
|
||||||
userData: { any: 'userData' },
|
configId: 'configId1',
|
||||||
accessToken: 'anyAccessToken',
|
idToken: '',
|
||||||
})
|
userData: { any: 'userData' },
|
||||||
);
|
accessToken: 'anyAccessToken',
|
||||||
|
})
|
||||||
|
);
|
||||||
const popupResult: PopupResult = {
|
const popupResult: PopupResult = {
|
||||||
userClosed: false,
|
userClosed: false,
|
||||||
receivedUrl: 'someUrl',
|
receivedUrl: 'someUrl',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(of(popupResult));
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
|
of(popupResult)
|
||||||
|
);
|
||||||
|
|
||||||
popUpLoginService
|
popUpLoginService
|
||||||
.loginWithPopUpStandard(config, [config])
|
.loginWithPopUpStandard(config, [config])
|
||||||
.subscribe((result) => {
|
.subscribe((result) => {
|
||||||
expect(checkAuthSpy).toHaveBeenCalledOnceWith(
|
expect(checkAuthSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
[config],
|
[config],
|
||||||
'someUrl'
|
'someUrl'
|
||||||
@@ -178,31 +183,33 @@ describe('PopUpLoginService', () => {
|
|||||||
accessToken: 'anyAccessToken',
|
accessToken: 'anyAccessToken',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('returns two properties if popup was closed by user', waitForAsync(() => {
|
it('returns two properties if popup was closed by user', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypValidationService,
|
responseTypValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
spyOn(popupService, 'openPopUp');
|
vi.spyOn(popupService, 'openPopUp');
|
||||||
const checkAuthSpy = spyOn(checkAuthService, 'checkAuth').and.returnValue(
|
const checkAuthSpy = vi
|
||||||
of({} as LoginResponse)
|
.spyOn(checkAuthService, 'checkAuth')
|
||||||
);
|
.mockReturnValue(of({} as LoginResponse));
|
||||||
const popupResult = { userClosed: true } as PopupResult;
|
const popupResult = { userClosed: true } as PopupResult;
|
||||||
|
|
||||||
spyOnProperty(popupService, 'result$').and.returnValue(of(popupResult));
|
vi.spyOnProperty(popupService, 'result$').mockReturnValue(
|
||||||
|
of(popupResult)
|
||||||
|
);
|
||||||
|
|
||||||
popUpLoginService
|
popUpLoginService
|
||||||
.loginWithPopUpStandard(config, [config])
|
.loginWithPopUpStandard(config, [config])
|
||||||
@@ -217,6 +224,6 @@ describe('PopUpLoginService', () => {
|
|||||||
accessToken: '',
|
accessToken: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { type Observable, of, throwError } from 'rxjs';
|
||||||
import { switchMap, take, tap } from 'rxjs/operators';
|
import { switchMap, take, tap } from 'rxjs/operators';
|
||||||
import { AuthOptions } from '../../auth-options';
|
import type { AuthOptions } from '../../auth-options';
|
||||||
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
import { CheckAuthService } from '../../auth-state/check-auth.service';
|
||||||
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { LoginResponse } from '../login-response';
|
import type { LoginResponse } from '../login-response';
|
||||||
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
||||||
import { PopupOptions } from './popup-options';
|
import type { PopupOptions } from './popup-options';
|
||||||
import { PopupResult } from './popup-result';
|
import type { PopupResult } from './popup-result';
|
||||||
import { PopUpService } from './popup.service';
|
import { PopUpService } from './popup.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed, fakeAsync, tick } from '@/testing';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||||
import { PopupResult } from './popup-result';
|
import { mockProvider } from '../../testing/mock';
|
||||||
|
import type { PopupResult } from './popup-result';
|
||||||
import { PopUpService } from './popup.service';
|
import { PopUpService } from './popup.service';
|
||||||
|
|
||||||
describe('PopUpService', () => {
|
describe('PopUpService', () => {
|
||||||
@@ -18,9 +19,6 @@ describe('PopUpService', () => {
|
|||||||
mockProvider(LoggerService),
|
mockProvider(LoggerService),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||||
loggerService = TestBed.inject(LoggerService);
|
loggerService = TestBed.inject(LoggerService);
|
||||||
popUpService = TestBed.inject(PopUpService);
|
popUpService = TestBed.inject(PopUpService);
|
||||||
@@ -51,13 +49,13 @@ describe('PopUpService', () => {
|
|||||||
describe('isCurrentlyInPopup', () => {
|
describe('isCurrentlyInPopup', () => {
|
||||||
it('returns false if can not access Session Storage', () => {
|
it('returns false if can not access Session Storage', () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOn(popUpService as any, 'canAccessSessionStorage').and.returnValue(
|
vi.spyOn(popUpService as any, 'canAccessSessionStorage').mockReturnValue(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
spyOnProperty(popUpService as any, 'windowInternal').and.returnValue({
|
vi.spyOnProperty(popUpService as any, 'windowInternal').mockReturnValue({
|
||||||
opener: {} as Window,
|
opener: {} as Window,
|
||||||
});
|
});
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue({
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue({
|
||||||
popupauth: true,
|
popupauth: true,
|
||||||
});
|
});
|
||||||
const config = {} as OpenIdConfiguration;
|
const config = {} as OpenIdConfiguration;
|
||||||
@@ -71,10 +69,10 @@ describe('PopUpService', () => {
|
|||||||
|
|
||||||
it('returns false if window has no opener', () => {
|
it('returns false if window has no opener', () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOn(popUpService as any, 'canAccessSessionStorage').and.returnValue(
|
vi.spyOn(popUpService as any, 'canAccessSessionStorage').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue({
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue({
|
||||||
popupauth: true,
|
popupauth: true,
|
||||||
});
|
});
|
||||||
const config = {} as OpenIdConfiguration;
|
const config = {} as OpenIdConfiguration;
|
||||||
@@ -88,13 +86,13 @@ describe('PopUpService', () => {
|
|||||||
|
|
||||||
it('returns true if isCurrentlyInPopup', () => {
|
it('returns true if isCurrentlyInPopup', () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOn(popUpService as any, 'canAccessSessionStorage').and.returnValue(
|
vi.spyOn(popUpService as any, 'canAccessSessionStorage').mockReturnValue(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
spyOnProperty(popUpService as any, 'windowInternal').and.returnValue({
|
vi.spyOnProperty(popUpService as any, 'windowInternal').mockReturnValue({
|
||||||
opener: {} as Window,
|
opener: {} as Window,
|
||||||
});
|
});
|
||||||
spyOn(storagePersistenceService, 'read').and.returnValue({
|
vi.spyOn(storagePersistenceService, 'read').mockReturnValue({
|
||||||
popupauth: true,
|
popupauth: true,
|
||||||
});
|
});
|
||||||
const config = {} as OpenIdConfiguration;
|
const config = {} as OpenIdConfiguration;
|
||||||
@@ -108,7 +106,7 @@ describe('PopUpService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('result$', () => {
|
describe('result$', () => {
|
||||||
it('emits when internal subject is called', waitForAsync(() => {
|
it('emits when internal subject is called', async () => {
|
||||||
const popupResult: PopupResult = {
|
const popupResult: PopupResult = {
|
||||||
userClosed: false,
|
userClosed: false,
|
||||||
receivedUrl: 'some-url1111',
|
receivedUrl: 'some-url1111',
|
||||||
@@ -119,62 +117,62 @@ describe('PopUpService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
(popUpService as any).resultInternal$.next(popupResult);
|
(popUpService as any).resultInternal$.next(popupResult);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('openPopup', () => {
|
describe('openPopup', () => {
|
||||||
it('popup opens with parameters and default options', waitForAsync(() => {
|
it('popup opens with parameters and default options', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const popupSpy = spyOn(window, 'open').and.callFake(
|
const popupSpy = vi.spyOn(window, 'open').and.callFake(
|
||||||
() =>
|
() =>
|
||||||
({
|
({
|
||||||
closed: true,
|
closed: true,
|
||||||
close: () => undefined,
|
close: () => undefined,
|
||||||
} as Window)
|
}) as Window
|
||||||
);
|
);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
popUpService.openPopUp('url', {}, { configId: 'configId1' });
|
popUpService.openPopUp('url', {}, { configId: 'configId1' });
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(popupSpy).toHaveBeenCalledOnceWith(
|
expect(popupSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'url',
|
'url',
|
||||||
'_blank',
|
'_blank',
|
||||||
jasmine.any(String)
|
expect.any(String)
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('popup opens with parameters and passed options', waitForAsync(() => {
|
it('popup opens with parameters and passed options', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const popupSpy = spyOn(window, 'open').and.callFake(
|
const popupSpy = vi.spyOn(window, 'open').and.callFake(
|
||||||
() =>
|
() =>
|
||||||
({
|
({
|
||||||
closed: true,
|
closed: true,
|
||||||
close: () => undefined,
|
close: () => undefined,
|
||||||
} as Window)
|
}) as Window
|
||||||
);
|
);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
popUpService.openPopUp('url', { width: 100 }, { configId: 'configId1' });
|
popUpService.openPopUp('url', { width: 100 }, { configId: 'configId1' });
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(popupSpy).toHaveBeenCalledOnceWith(
|
expect(popupSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'url',
|
'url',
|
||||||
'_blank',
|
'_blank',
|
||||||
jasmine.any(String)
|
expect.any(String)
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error and return if popup could not be opened', () => {
|
it('logs error and return if popup could not be opened', () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOn(window, 'open').and.callFake(() => null);
|
vi.spyOn(window, 'open').mockImplementation(() => null);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
// act
|
// act
|
||||||
popUpService.openPopUp('url', { width: 100 }, { configId: 'configId1' });
|
popUpService.openPopUp('url', { width: 100 }, { configId: 'configId1' });
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(loggerSpy).toHaveBeenCalledOnceWith(
|
expect(loggerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ configId: 'configId1' },
|
{ configId: 'configId1' },
|
||||||
'Could not open popup'
|
'Could not open popup'
|
||||||
);
|
);
|
||||||
@@ -191,21 +189,21 @@ describe('PopUpService', () => {
|
|||||||
close: () => undefined,
|
close: () => undefined,
|
||||||
} as Window;
|
} as Window;
|
||||||
|
|
||||||
spyOn(window, 'open').and.returnValue(popup);
|
vi.spyOn(window, 'open').mockReturnValue(popup);
|
||||||
|
|
||||||
cleanUpSpy = spyOn(popUpService as any, 'cleanUp').and.callThrough();
|
cleanUpSpy = vi.spyOn(popUpService as any, 'cleanUp')();
|
||||||
|
|
||||||
popupResult = {} as PopupResult;
|
popupResult = {} as PopupResult;
|
||||||
|
|
||||||
popUpService.result$.subscribe((result) => (popupResult = result));
|
popUpService.result$.subscribe((result) => (popupResult = result));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('message received with data', fakeAsync(() => {
|
it('message received with data', async () => {
|
||||||
let listener: (event: MessageEvent) => void = () => {
|
let listener: (event: MessageEvent) => void = () => {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(window, 'addEventListener').and.callFake(
|
vi.spyOn(window, 'addEventListener').and.callFake(
|
||||||
(_: any, func: any) => (listener = func)
|
(_: any, func: any) => (listener = func)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -222,20 +220,20 @@ describe('PopUpService', () => {
|
|||||||
userClosed: false,
|
userClosed: false,
|
||||||
receivedUrl: 'some-url1111',
|
receivedUrl: 'some-url1111',
|
||||||
});
|
});
|
||||||
expect(cleanUpSpy).toHaveBeenCalledOnceWith(listener, {
|
expect(cleanUpSpy).toHaveBeenCalledExactlyOnceWith(listener, {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('message received without data does return but cleanup does not throw event', fakeAsync(() => {
|
it('message received without data does return but cleanup does not throw event', async () => {
|
||||||
let listener: (event: MessageEvent) => void = () => {
|
let listener: (event: MessageEvent) => void = () => {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(window, 'addEventListener').and.callFake(
|
vi.spyOn(window, 'addEventListener').and.callFake(
|
||||||
(_: any, func: any) => (listener = func)
|
(_: any, func: any) => (listener = func)
|
||||||
);
|
);
|
||||||
const nextSpy = spyOn((popUpService as any).resultInternal$, 'next');
|
const nextSpy = vi.spyOn((popUpService as any).resultInternal$, 'next');
|
||||||
|
|
||||||
popUpService.openPopUp('url', {}, { configId: 'configId1' });
|
popUpService.openPopUp('url', {}, { configId: 'configId1' });
|
||||||
|
|
||||||
@@ -249,9 +247,9 @@ describe('PopUpService', () => {
|
|||||||
expect(popupResult).toEqual({} as PopupResult);
|
expect(popupResult).toEqual({} as PopupResult);
|
||||||
expect(cleanUpSpy).toHaveBeenCalled();
|
expect(cleanUpSpy).toHaveBeenCalled();
|
||||||
expect(nextSpy).not.toHaveBeenCalled();
|
expect(nextSpy).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('user closed', fakeAsync(() => {
|
it('user closed', async () => {
|
||||||
popUpService.openPopUp('url', undefined, { configId: 'configId1' });
|
popUpService.openPopUp('url', undefined, { configId: 'configId1' });
|
||||||
|
|
||||||
expect(popupResult).toEqual({} as PopupResult);
|
expect(popupResult).toEqual({} as PopupResult);
|
||||||
@@ -266,48 +264,48 @@ describe('PopUpService', () => {
|
|||||||
receivedUrl: '',
|
receivedUrl: '',
|
||||||
} as PopupResult);
|
} as PopupResult);
|
||||||
expect(cleanUpSpy).toHaveBeenCalled();
|
expect(cleanUpSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('sendMessageToMainWindow', () => {
|
describe('sendMessageToMainWindow', () => {
|
||||||
it('does nothing if window.opener is null', waitForAsync(() => {
|
it('does nothing if window.opener is null', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOnProperty(window, 'opener').and.returnValue(null);
|
vi.spyOnProperty(window, 'opener').mockReturnValue(null);
|
||||||
|
|
||||||
const sendMessageSpy = spyOn(popUpService as any, 'sendMessage');
|
const sendMessageSpy = vi.spyOn(popUpService as any, 'sendMessage');
|
||||||
|
|
||||||
// act
|
// act
|
||||||
popUpService.sendMessageToMainWindow('', {});
|
popUpService.sendMessageToMainWindow('', {});
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(sendMessageSpy).not.toHaveBeenCalled();
|
expect(sendMessageSpy).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls postMessage when window opener is given', waitForAsync(() => {
|
it('calls postMessage when window opener is given', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
spyOnProperty(window, 'opener').and.returnValue({
|
vi.spyOnProperty(window, 'opener').mockReturnValue({
|
||||||
postMessage: () => undefined,
|
postMessage: () => undefined,
|
||||||
});
|
});
|
||||||
const sendMessageSpy = spyOn(window.opener, 'postMessage');
|
const sendMessageSpy = vi.spyOn(window.opener, 'postMessage');
|
||||||
|
|
||||||
// act
|
// act
|
||||||
popUpService.sendMessageToMainWindow('someUrl', {});
|
popUpService.sendMessageToMainWindow('someUrl', {});
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(sendMessageSpy).toHaveBeenCalledOnceWith(
|
expect(sendMessageSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'someUrl',
|
'someUrl',
|
||||||
jasmine.any(String)
|
expect.any(String)
|
||||||
);
|
);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('cleanUp', () => {
|
describe('cleanUp', () => {
|
||||||
it('calls removeEventListener on window with correct params', waitForAsync(() => {
|
it('calls removeEventListener on window with correct params', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const spy = spyOn(window, 'removeEventListener').and.callFake(
|
const spy = vi
|
||||||
() => undefined
|
.spyOn(window, 'removeEventListener')
|
||||||
);
|
.mockImplementation(() => undefined);
|
||||||
const listener: any = null;
|
const listener: any = null;
|
||||||
|
|
||||||
// act
|
// act
|
||||||
@@ -315,29 +313,29 @@ describe('PopUpService', () => {
|
|||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(spy).toHaveBeenCalledTimes(1);
|
expect(spy).toHaveBeenCalledTimes(1);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('message', listener, false);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('message', listener, false);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('removes popup from sessionstorage, closes and nulls when popup is opened', waitForAsync(() => {
|
it('removes popup from sessionstorage, closes and nulls when popup is opened', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
const popupMock = {
|
const popupMock = {
|
||||||
anyThing: 'truthy',
|
anyThing: 'truthy',
|
||||||
sessionStorage: mockStorage,
|
sessionStorage: mockStorage,
|
||||||
close: (): void => undefined,
|
close: (): void => undefined,
|
||||||
};
|
};
|
||||||
const removeItemSpy = spyOn(storagePersistenceService, 'remove');
|
const removeItemSpy = vi.spyOn(storagePersistenceService, 'remove');
|
||||||
const closeSpy = spyOn(popupMock, 'close');
|
const closeSpy = vi.spyOn(popupMock, 'close');
|
||||||
|
|
||||||
// act
|
// act
|
||||||
(popUpService as any).popUp = popupMock;
|
(popUpService as any).popUp = popupMock;
|
||||||
(popUpService as any).cleanUp(null, { configId: 'configId1' });
|
(popUpService as any).cleanUp(null, { configId: 'configId1' });
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(removeItemSpy).toHaveBeenCalledOnceWith('popupauth', {
|
expect(removeItemSpy).toHaveBeenCalledExactlyOnceWith('popupauth', {
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
});
|
});
|
||||||
expect(closeSpy).toHaveBeenCalledTimes(1);
|
expect(closeSpy).toHaveBeenCalledTimes(1);
|
||||||
expect((popUpService as any).popUp).toBeNull();
|
expect((popUpService as any).popUp).toBeNull();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { FlowHelper } from '../../utils/flowHelper/flow-helper.service';
|
import { FlowHelper } from '../../utils/flowHelper/flow-helper.service';
|
||||||
import { ResponseTypeValidationService } from './response-type-validation.service';
|
import { ResponseTypeValidationService } from './response-type-validation.service';
|
||||||
|
|
||||||
@@ -32,7 +33,9 @@ describe('ResponseTypeValidationService', () => {
|
|||||||
|
|
||||||
describe('hasConfigValidResponseType', () => {
|
describe('hasConfigValidResponseType', () => {
|
||||||
it('returns true if current configured flow is any implicit flow', () => {
|
it('returns true if current configured flow is any implicit flow', () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').and.returnValue(true);
|
vi.spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
const result = responseTypeValidationService.hasConfigValidResponseType({
|
const result = responseTypeValidationService.hasConfigValidResponseType({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -42,8 +45,10 @@ describe('ResponseTypeValidationService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if current configured flow is code flow', () => {
|
it('returns true if current configured flow is code flow', () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').and.returnValue(false);
|
vi.spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').mockReturnValue(
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(true);
|
false
|
||||||
|
);
|
||||||
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(true);
|
||||||
|
|
||||||
const result = responseTypeValidationService.hasConfigValidResponseType({
|
const result = responseTypeValidationService.hasConfigValidResponseType({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -53,8 +58,10 @@ describe('ResponseTypeValidationService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns false if current configured flow is neither code nor implicit flow', () => {
|
it('returns false if current configured flow is neither code nor implicit flow', () => {
|
||||||
spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').and.returnValue(false);
|
vi.spyOn(flowHelper, 'isCurrentFlowAnyImplicitFlow').mockReturnValue(
|
||||||
spyOn(flowHelper, 'isCurrentFlowCodeFlow').and.returnValue(false);
|
false
|
||||||
|
);
|
||||||
|
vi.spyOn(flowHelper, 'isCurrentFlowCodeFlow').mockReturnValue(false);
|
||||||
|
|
||||||
const result = responseTypeValidationService.hasConfigValidResponseType({
|
const result = responseTypeValidationService.hasConfigValidResponseType({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed, fakeAsync, tick } from '@/testing';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from '../../config/auth-well-known/auth-well-known.service';
|
||||||
import { FlowsDataService } from '../../flows/flows-data.service';
|
import { FlowsDataService } from '../../flows/flows-data.service';
|
||||||
import { LoggerService } from '../../logging/logger.service';
|
import { LoggerService } from '../../logging/logger.service';
|
||||||
|
import { mockProvider } from '../../testing/mock';
|
||||||
import { RedirectService } from '../../utils/redirect/redirect.service';
|
import { RedirectService } from '../../utils/redirect/redirect.service';
|
||||||
import { UrlService } from '../../utils/url/url.service';
|
import { UrlService } from '../../utils/url/url.service';
|
||||||
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
import { ResponseTypeValidationService } from '../response-type-validation/response-type-validation.service';
|
||||||
@@ -51,12 +52,12 @@ describe('StandardLoginService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('loginStandard', () => {
|
describe('loginStandard', () => {
|
||||||
it('does nothing if it has an invalid response type', waitForAsync(() => {
|
it('does nothing if it has an invalid response type', async () => {
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(false);
|
).mockReturnValue(false);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
const result = standardLoginService.loginStandard({
|
const result = standardLoginService.loginStandard({
|
||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
@@ -64,95 +65,92 @@ describe('StandardLoginService', () => {
|
|||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls flowsDataService.setCodeFlowInProgress() if everything fits', waitForAsync(() => {
|
it('calls flowsDataService.setCodeFlowInProgress() if everything fits', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
const flowsDataSpy = spyOn(flowsDataService, 'setCodeFlowInProgress');
|
const flowsDataSpy = vi.spyOn(flowsDataService, 'setCodeFlowInProgress');
|
||||||
|
|
||||||
const result = standardLoginService.loginStandard(config);
|
const result = standardLoginService.loginStandard(config);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(flowsDataSpy).toHaveBeenCalled();
|
expect(flowsDataSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls urlService.getAuthorizeUrl() if everything fits', waitForAsync(() => {
|
it('calls urlService.getAuthorizeUrl() if everything fits', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
|
|
||||||
const result = standardLoginService.loginStandard(config);
|
const result = standardLoginService.loginStandard(config);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('redirects to URL with no URL handler', fakeAsync(() => {
|
it('redirects to URL with no URL handler', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
const redirectSpy = spyOn(
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo')();
|
||||||
redirectService,
|
|
||||||
'redirectTo'
|
|
||||||
).and.callThrough();
|
|
||||||
|
|
||||||
standardLoginService.loginStandard(config);
|
standardLoginService.loginStandard(config);
|
||||||
tick();
|
tick();
|
||||||
expect(redirectSpy).toHaveBeenCalledOnceWith('someUrl');
|
expect(redirectSpy).toHaveBeenCalledExactlyOnceWith('someUrl');
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('redirects to URL with URL handler when urlHandler is given', fakeAsync(() => {
|
it('redirects to URL with URL handler when urlHandler is given', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo').and.callFake(
|
const redirectSpy = vi
|
||||||
() => undefined
|
.spyOn(redirectService, 'redirectTo')
|
||||||
);
|
.mockImplementation(() => undefined);
|
||||||
const spy = jasmine.createSpy();
|
const spy = jasmine.createSpy();
|
||||||
const urlHandler = (url: any): void => {
|
const urlHandler = (url: any): void => {
|
||||||
spy(url);
|
spy(url);
|
||||||
@@ -160,94 +158,96 @@ describe('StandardLoginService', () => {
|
|||||||
|
|
||||||
standardLoginService.loginStandard(config, { urlHandler });
|
standardLoginService.loginStandard(config, { urlHandler });
|
||||||
tick();
|
tick();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('someUrl');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('someUrl');
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
expect(redirectSpy).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls resetSilentRenewRunning', fakeAsync(() => {
|
it('calls resetSilentRenewRunning', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of('someUrl'));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of('someUrl'));
|
||||||
const flowsDataSpy = spyOn(flowsDataService, 'resetSilentRenewRunning');
|
const flowsDataSpy = vi.spyOn(
|
||||||
|
flowsDataService,
|
||||||
|
'resetSilentRenewRunning'
|
||||||
|
);
|
||||||
|
|
||||||
standardLoginService.loginStandard(config, {});
|
standardLoginService.loginStandard(config, {});
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(flowsDataSpy).toHaveBeenCalled();
|
expect(flowsDataSpy).toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls getAuthorizeUrl with custom params if they are given as parameter', fakeAsync(() => {
|
it('calls getAuthorizeUrl with custom params if they are given as parameter', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
const getAuthorizeUrlSpy = spyOn(
|
const getAuthorizeUrlSpy = vi
|
||||||
urlService,
|
.spyOn(urlService, 'getAuthorizeUrl')
|
||||||
'getAuthorizeUrl'
|
.mockReturnValue(of('someUrl'));
|
||||||
).and.returnValue(of('someUrl'));
|
const redirectSpy = vi
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo').and.callFake(
|
.spyOn(redirectService, 'redirectTo')
|
||||||
() => undefined
|
.mockImplementation(() => undefined);
|
||||||
);
|
|
||||||
|
|
||||||
standardLoginService.loginStandard(config, {
|
standardLoginService.loginStandard(config, {
|
||||||
customParams: { to: 'add', as: 'well' },
|
customParams: { to: 'add', as: 'well' },
|
||||||
});
|
});
|
||||||
tick();
|
tick();
|
||||||
expect(redirectSpy).toHaveBeenCalledOnceWith('someUrl');
|
expect(redirectSpy).toHaveBeenCalledExactlyOnceWith('someUrl');
|
||||||
expect(getAuthorizeUrlSpy).toHaveBeenCalledOnceWith(config, {
|
expect(getAuthorizeUrlSpy).toHaveBeenCalledExactlyOnceWith(config, {
|
||||||
customParams: { to: 'add', as: 'well' },
|
customParams: { to: 'add', as: 'well' },
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('does nothing, logs only if getAuthorizeUrl returns falsy', fakeAsync(() => {
|
it('does nothing, logs only if getAuthorizeUrl returns falsy', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
authWellknownEndpointUrl: 'authWellknownEndpoint',
|
||||||
responseType: 'stubValue',
|
responseType: 'stubValue',
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
responseTypeValidationService,
|
responseTypeValidationService,
|
||||||
'hasConfigValidResponseType'
|
'hasConfigValidResponseType'
|
||||||
).and.returnValue(true);
|
).mockReturnValue(true);
|
||||||
spyOn(
|
vi.spyOn(
|
||||||
authWellKnownService,
|
authWellKnownService,
|
||||||
'queryAndStoreAuthWellKnownEndPoints'
|
'queryAndStoreAuthWellKnownEndPoints'
|
||||||
).and.returnValue(of({}));
|
).mockReturnValue(of({}));
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
spyOn(urlService, 'getAuthorizeUrl').and.returnValue(of(''));
|
vi.spyOn(urlService, 'getAuthorizeUrl').mockReturnValue(of(''));
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo').and.callFake(
|
const redirectSpy = vi
|
||||||
() => undefined
|
.spyOn(redirectService, 'redirectTo')
|
||||||
);
|
.mockImplementation(() => undefined);
|
||||||
|
|
||||||
standardLoginService.loginStandard(config);
|
standardLoginService.loginStandard(config);
|
||||||
tick();
|
tick();
|
||||||
expect(loggerSpy).toHaveBeenCalledOnceWith(
|
expect(loggerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
config,
|
config,
|
||||||
'Could not create URL',
|
'Could not create URL',
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
expect(redirectSpy).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { HttpHeaders } from '@angular/common/http';
|
import { TestBed } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import type { HttpHeaders } from '@ngify/http';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { Observable, of, throwError } from 'rxjs';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { createRetriableStream } from '../../test/create-retriable-stream.helper';
|
|
||||||
import { DataService } from '../api/data.service';
|
import { DataService } from '../api/data.service';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { CheckSessionService } from '../iframe/check-session.service';
|
import { CheckSessionService } from '../iframe/check-session.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||||
|
import { createRetriableStream } from '../testing/create-retriable-stream.helper';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { RedirectService } from '../utils/redirect/redirect.service';
|
import { RedirectService } from '../utils/redirect/redirect.service';
|
||||||
import { UrlService } from '../utils/url/url.service';
|
import { UrlService } from '../utils/url/url.service';
|
||||||
import { LogoffRevocationService } from './logoff-revocation.service';
|
import { LogoffRevocationService } from './logoff-revocation.service';
|
||||||
@@ -55,70 +56,70 @@ describe('Logout and Revoke Service', () => {
|
|||||||
it('uses token parameter if token as parameter is passed in the method', () => {
|
it('uses token parameter if token as parameter is passed in the method', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'passedTokenAsParam';
|
const paramToken = 'passedTokenAsParam';
|
||||||
const revocationSpy = spyOn(
|
const revocationSpy = vi.spyOn(
|
||||||
urlService,
|
urlService,
|
||||||
'createRevocationEndpointBodyAccessToken'
|
'createRevocationEndpointBodyAccessToken'
|
||||||
);
|
);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(of(null));
|
vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
service.revokeAccessToken(config, paramToken);
|
service.revokeAccessToken(config, paramToken);
|
||||||
// Assert
|
// Assert
|
||||||
expect(revocationSpy).toHaveBeenCalledOnceWith(paramToken, config);
|
expect(revocationSpy).toHaveBeenCalledExactlyOnceWith(paramToken, config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses token parameter from persistence if no param is provided', () => {
|
it('uses token parameter from persistence if no param is provided', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
const revocationSpy = spyOn(
|
const revocationSpy = vi.spyOn(
|
||||||
urlService,
|
urlService,
|
||||||
'createRevocationEndpointBodyAccessToken'
|
'createRevocationEndpointBodyAccessToken'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(of(null));
|
vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
service.revokeAccessToken(config);
|
service.revokeAccessToken(config);
|
||||||
// Assert
|
// Assert
|
||||||
expect(revocationSpy).toHaveBeenCalledOnceWith(paramToken, config);
|
expect(revocationSpy).toHaveBeenCalledExactlyOnceWith(paramToken, config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns type observable', () => {
|
it('returns type observable', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
spyOn(dataService, 'post').and.returnValue(of(null));
|
vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = service.revokeAccessToken(config);
|
const result = service.revokeAccessToken(config);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(result).toEqual(jasmine.any(Observable));
|
expect(result).toEqual(expect.any(Observable));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loggs and returns unmodified response if request is positive', waitForAsync(() => {
|
it('loggs and returns unmodified response if request is positive', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logDebug');
|
const loggerSpy = vi.spyOn(loggerService, 'logDebug');
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(of({ data: 'anything' }));
|
vi.spyOn(dataService, 'post').mockReturnValue(of({ data: 'anything' }));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -127,20 +128,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(result).toEqual({ data: 'anything' });
|
expect(result).toEqual({ data: 'anything' });
|
||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('loggs error when request is negative', waitForAsync(() => {
|
it('loggs error when request is negative', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -151,20 +152,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry once', waitForAsync(() => {
|
it('should retry once', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logDebug');
|
const loggerSpy = vi.spyOn(loggerService, 'logDebug');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
of({ data: 'anything' })
|
of({ data: 'anything' })
|
||||||
@@ -179,20 +180,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry twice', waitForAsync(() => {
|
it('should retry twice', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logDebug');
|
const loggerSpy = vi.spyOn(loggerService, 'logDebug');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
@@ -208,20 +209,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should fail after three tries', waitForAsync(() => {
|
it('should fail after three tries', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getAccessToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getAccessToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
@@ -236,76 +237,76 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('revokeRefreshToken', () => {
|
describe('revokeRefreshToken', () => {
|
||||||
it('uses refresh token parameter if token as parameter is passed in the method', () => {
|
it('uses refresh token parameter if token as parameter is passed in the method', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'passedTokenAsParam';
|
const paramToken = 'passedTokenAsParam';
|
||||||
const revocationSpy = spyOn(
|
const revocationSpy = vi.spyOn(
|
||||||
urlService,
|
urlService,
|
||||||
'createRevocationEndpointBodyRefreshToken'
|
'createRevocationEndpointBodyRefreshToken'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(of(null));
|
vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
service.revokeRefreshToken(config, paramToken);
|
service.revokeRefreshToken(config, paramToken);
|
||||||
// Assert
|
// Assert
|
||||||
expect(revocationSpy).toHaveBeenCalledOnceWith(paramToken, config);
|
expect(revocationSpy).toHaveBeenCalledExactlyOnceWith(paramToken, config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses refresh token parameter from persistence if no param is provided', () => {
|
it('uses refresh token parameter from persistence if no param is provided', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const revocationSpy = spyOn(
|
const revocationSpy = vi.spyOn(
|
||||||
urlService,
|
urlService,
|
||||||
'createRevocationEndpointBodyRefreshToken'
|
'createRevocationEndpointBodyRefreshToken'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(of(null));
|
vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
// Act
|
// Act
|
||||||
service.revokeRefreshToken(config);
|
service.revokeRefreshToken(config);
|
||||||
// Assert
|
// Assert
|
||||||
expect(revocationSpy).toHaveBeenCalledOnceWith(paramToken, config);
|
expect(revocationSpy).toHaveBeenCalledExactlyOnceWith(paramToken, config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns type observable', () => {
|
it('returns type observable', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
spyOn(dataService, 'post').and.returnValue(of(null));
|
vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = service.revokeRefreshToken(config);
|
const result = service.revokeRefreshToken(config);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(result).toEqual(jasmine.any(Observable));
|
expect(result).toEqual(expect.any(Observable));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loggs and returns unmodified response if request is positive', waitForAsync(() => {
|
it('loggs and returns unmodified response if request is positive', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logDebug');
|
const loggerSpy = vi.spyOn(loggerService, 'logDebug');
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(of({ data: 'anything' }));
|
vi.spyOn(dataService, 'post').mockReturnValue(of({ data: 'anything' }));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -314,20 +315,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(result).toEqual({ data: 'anything' });
|
expect(result).toEqual({ data: 'anything' });
|
||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('loggs error when request is negative', waitForAsync(() => {
|
it('loggs error when request is negative', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -338,20 +339,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry once', waitForAsync(() => {
|
it('should retry once', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logDebug');
|
const loggerSpy = vi.spyOn(loggerService, 'logDebug');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
of({ data: 'anything' })
|
of({ data: 'anything' })
|
||||||
@@ -366,20 +367,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should retry twice', waitForAsync(() => {
|
it('should retry twice', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logDebug');
|
const loggerSpy = vi.spyOn(loggerService, 'logDebug');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
@@ -395,20 +396,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should fail after three tries', waitForAsync(() => {
|
it('should fail after three tries', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
vi.spyOn(urlService, 'createRevocationEndpointBodyAccessToken');
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(dataService, 'post').and.returnValue(
|
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||||
createRetriableStream(
|
createRetriableStream(
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
throwError(() => new Error('Error')),
|
throwError(() => new Error('Error')),
|
||||||
@@ -423,15 +424,15 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(loggerSpy).toHaveBeenCalled();
|
expect(loggerSpy).toHaveBeenCalled();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('logoff', () => {
|
describe('logoff', () => {
|
||||||
it('logs and returns if `endSessionUrl` is false', waitForAsync(() => {
|
it('logs and returns if `endSessionUrl` is false', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('');
|
||||||
|
|
||||||
const serverStateChangedSpy = spyOn(
|
const serverStateChangedSpy = vi.spyOn(
|
||||||
checkSessionService,
|
checkSessionService,
|
||||||
'serverStateChanged'
|
'serverStateChanged'
|
||||||
);
|
);
|
||||||
@@ -444,14 +445,14 @@ describe('Logout and Revoke Service', () => {
|
|||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(serverStateChangedSpy).not.toHaveBeenCalled();
|
expect(serverStateChangedSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs and returns if `serverStateChanged` is true', waitForAsync(() => {
|
it('logs and returns if `serverStateChanged` is true', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('someValue');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('someValue');
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo');
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
|
|
||||||
spyOn(checkSessionService, 'serverStateChanged').and.returnValue(true);
|
vi.spyOn(checkSessionService, 'serverStateChanged').mockReturnValue(true);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -461,22 +462,24 @@ describe('Logout and Revoke Service', () => {
|
|||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
expect(redirectSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls urlHandler if urlhandler is passed', waitForAsync(() => {
|
it('calls urlHandler if urlhandler is passed', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('someValue');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('someValue');
|
||||||
const spy = jasmine.createSpy();
|
const spy = jasmine.createSpy();
|
||||||
const urlHandler = (url: string): void => {
|
const urlHandler = (url: string): void => {
|
||||||
spy(url);
|
spy(url);
|
||||||
};
|
};
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo');
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn(checkSessionService, 'serverStateChanged').and.returnValue(false);
|
vi.spyOn(checkSessionService, 'serverStateChanged').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -485,18 +488,20 @@ describe('Logout and Revoke Service', () => {
|
|||||||
// Assert
|
// Assert
|
||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
expect(redirectSpy).not.toHaveBeenCalled();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('someValue');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('someValue');
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalled();
|
expect(resetAuthorizationDataSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls redirect service if no logoutOptions are passed', waitForAsync(() => {
|
it('calls redirect service if no logoutOptions are passed', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('someValue');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('someValue');
|
||||||
|
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo');
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
|
|
||||||
spyOn(checkSessionService, 'serverStateChanged').and.returnValue(false);
|
vi.spyOn(checkSessionService, 'serverStateChanged').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -504,17 +509,19 @@ describe('Logout and Revoke Service', () => {
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(redirectSpy).toHaveBeenCalledOnceWith('someValue');
|
expect(redirectSpy).toHaveBeenCalledExactlyOnceWith('someValue');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls redirect service if logoutOptions are passed and method is GET', waitForAsync(() => {
|
it('calls redirect service if logoutOptions are passed and method is GET', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('someValue');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('someValue');
|
||||||
|
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo');
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
|
|
||||||
spyOn(checkSessionService, 'serverStateChanged').and.returnValue(false);
|
vi.spyOn(checkSessionService, 'serverStateChanged').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -522,28 +529,30 @@ describe('Logout and Revoke Service', () => {
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(redirectSpy).toHaveBeenCalledOnceWith('someValue');
|
expect(redirectSpy).toHaveBeenCalledExactlyOnceWith('someValue');
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls dataservice post if logoutOptions are passed and method is POST', waitForAsync(() => {
|
it('calls dataservice post if logoutOptions are passed and method is POST', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('someValue');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('someValue');
|
||||||
|
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo');
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
|
|
||||||
spyOn(checkSessionService, 'serverStateChanged').and.returnValue(false);
|
vi.spyOn(checkSessionService, 'serverStateChanged').mockReturnValue(
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
false
|
||||||
|
);
|
||||||
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'id-token'
|
'id-token'
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getPostLogoutRedirectUrl').and.returnValue(
|
vi.spyOn(urlService, 'getPostLogoutRedirectUrl').mockReturnValue(
|
||||||
'post-logout-redirect-url'
|
'post-logout-redirect-url'
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getEndSessionEndpoint').and.returnValue({
|
vi.spyOn(urlService, 'getEndSessionEndpoint').mockReturnValue({
|
||||||
url: 'some-url',
|
url: 'some-url',
|
||||||
existingParams: '',
|
existingParams: '',
|
||||||
});
|
});
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of(null));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1', clientId: 'clientId' };
|
const config = { configId: 'configId1', clientId: 'clientId' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -554,7 +563,7 @@ describe('Logout and Revoke Service', () => {
|
|||||||
// Assert
|
// Assert
|
||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
expect(redirectSpy).not.toHaveBeenCalled();
|
||||||
expect(postSpy).toHaveBeenCalledOnceWith(
|
expect(postSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'some-url',
|
'some-url',
|
||||||
{
|
{
|
||||||
id_token_hint: 'id-token',
|
id_token_hint: 'id-token',
|
||||||
@@ -562,36 +571,38 @@ describe('Logout and Revoke Service', () => {
|
|||||||
post_logout_redirect_uri: 'post-logout-redirect-url',
|
post_logout_redirect_uri: 'post-logout-redirect-url',
|
||||||
},
|
},
|
||||||
config,
|
config,
|
||||||
jasmine.anything()
|
expect.anything()
|
||||||
);
|
);
|
||||||
|
|
||||||
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
||||||
|
|
||||||
expect(httpHeaders.has('Content-Type')).toBeTrue();
|
expect(httpHeaders.has('Content-Type')).toBeTruthy();
|
||||||
expect(httpHeaders.get('Content-Type')).toBe(
|
expect(httpHeaders.get('Content-Type')).toBe(
|
||||||
'application/x-www-form-urlencoded'
|
'application/x-www-form-urlencoded'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls dataservice post if logoutOptions with customParams are passed and method is POST', waitForAsync(() => {
|
it('calls dataservice post if logoutOptions with customParams are passed and method is POST', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
spyOn(urlService, 'getEndSessionUrl').and.returnValue('someValue');
|
vi.spyOn(urlService, 'getEndSessionUrl').mockReturnValue('someValue');
|
||||||
|
|
||||||
const redirectSpy = spyOn(redirectService, 'redirectTo');
|
const redirectSpy = vi.spyOn(redirectService, 'redirectTo');
|
||||||
|
|
||||||
spyOn(checkSessionService, 'serverStateChanged').and.returnValue(false);
|
vi.spyOn(checkSessionService, 'serverStateChanged').mockReturnValue(
|
||||||
spyOn(storagePersistenceService, 'getIdToken').and.returnValue(
|
false
|
||||||
|
);
|
||||||
|
vi.spyOn(storagePersistenceService, 'getIdToken').mockReturnValue(
|
||||||
'id-token'
|
'id-token'
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getPostLogoutRedirectUrl').and.returnValue(
|
vi.spyOn(urlService, 'getPostLogoutRedirectUrl').mockReturnValue(
|
||||||
'post-logout-redirect-url'
|
'post-logout-redirect-url'
|
||||||
);
|
);
|
||||||
spyOn(urlService, 'getEndSessionEndpoint').and.returnValue({
|
vi.spyOn(urlService, 'getEndSessionEndpoint').mockReturnValue({
|
||||||
url: 'some-url',
|
url: 'some-url',
|
||||||
existingParams: '',
|
existingParams: '',
|
||||||
});
|
});
|
||||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of(null));
|
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1', clientId: 'clientId' };
|
const config = { configId: 'configId1', clientId: 'clientId' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -607,7 +618,7 @@ describe('Logout and Revoke Service', () => {
|
|||||||
// Assert
|
// Assert
|
||||||
result$.subscribe(() => {
|
result$.subscribe(() => {
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
expect(redirectSpy).not.toHaveBeenCalled();
|
||||||
expect(postSpy).toHaveBeenCalledOnceWith(
|
expect(postSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'some-url',
|
'some-url',
|
||||||
{
|
{
|
||||||
id_token_hint: 'id-token',
|
id_token_hint: 'id-token',
|
||||||
@@ -618,23 +629,23 @@ describe('Logout and Revoke Service', () => {
|
|||||||
ui_locales: 'de fr en',
|
ui_locales: 'de fr en',
|
||||||
},
|
},
|
||||||
config,
|
config,
|
||||||
jasmine.anything()
|
expect.anything()
|
||||||
);
|
);
|
||||||
|
|
||||||
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
const httpHeaders = postSpy.calls.mostRecent().args[3] as HttpHeaders;
|
||||||
|
|
||||||
expect(httpHeaders.has('Content-Type')).toBeTrue();
|
expect(httpHeaders.has('Content-Type')).toBeTruthy();
|
||||||
expect(httpHeaders.get('Content-Type')).toBe(
|
expect(httpHeaders.get('Content-Type')).toBe(
|
||||||
'application/x-www-form-urlencoded'
|
'application/x-www-form-urlencoded'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('logoffLocal', () => {
|
describe('logoffLocal', () => {
|
||||||
it('calls flowsService.resetAuthorizationData', () => {
|
it('calls flowsService.resetAuthorizationData', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
@@ -649,25 +660,25 @@ describe('Logout and Revoke Service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('logoffAndRevokeTokens', () => {
|
describe('logoffAndRevokeTokens', () => {
|
||||||
it('calls revokeRefreshToken and revokeAccessToken when storage holds a refreshtoken', waitForAsync(() => {
|
it('calls revokeRefreshToken and revokeAccessToken when storage holds a refreshtoken', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ revocationEndpoint: 'revocationEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
() => ({ revocationEndpoint: 'revocationEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
const revokeRefreshTokenSpy = spyOn(
|
const revokeRefreshTokenSpy = vi
|
||||||
service,
|
.spyOn(service, 'revokeRefreshToken')
|
||||||
'revokeRefreshToken'
|
.mockReturnValue(of({ any: 'thing' }));
|
||||||
).and.returnValue(of({ any: 'thing' }));
|
const revokeAccessTokenSpy = vi
|
||||||
const revokeAccessTokenSpy = spyOn(
|
.spyOn(service, 'revokeAccessToken')
|
||||||
service,
|
.mockReturnValue(of({ any: 'thing' }));
|
||||||
'revokeAccessToken'
|
|
||||||
).and.returnValue(of({ any: 'thing' }));
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
service.logoffAndRevokeTokens(config, [config]).subscribe(() => {
|
service.logoffAndRevokeTokens(config, [config]).subscribe(() => {
|
||||||
@@ -675,25 +686,27 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(revokeRefreshTokenSpy).toHaveBeenCalled();
|
expect(revokeRefreshTokenSpy).toHaveBeenCalled();
|
||||||
expect(revokeAccessTokenSpy).toHaveBeenCalled();
|
expect(revokeAccessTokenSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error when revokeaccesstoken throws an error', waitForAsync(() => {
|
it('logs error when revokeaccesstoken throws an error', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ revocationEndpoint: 'revocationEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
() => ({ revocationEndpoint: 'revocationEndpoint' })
|
||||||
|
);
|
||||||
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(service, 'revokeRefreshToken').and.returnValue(
|
vi.spyOn(service, 'revokeRefreshToken').mockReturnValue(
|
||||||
of({ any: 'thing' })
|
of({ any: 'thing' })
|
||||||
);
|
);
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
spyOn(service, 'revokeAccessToken').and.returnValue(
|
vi.spyOn(service, 'revokeAccessToken').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -704,20 +717,22 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls logoff in case of success', waitForAsync(() => {
|
it('calls logoff in case of success', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(service, 'revokeRefreshToken').and.returnValue(
|
vi.spyOn(service, 'revokeRefreshToken').mockReturnValue(
|
||||||
of({ any: 'thing' })
|
of({ any: 'thing' })
|
||||||
);
|
);
|
||||||
spyOn(service, 'revokeAccessToken').and.returnValue(of({ any: 'thing' }));
|
vi.spyOn(service, 'revokeAccessToken').mockReturnValue(
|
||||||
const logoffSpy = spyOn(service, 'logoff').and.returnValue(of(null));
|
of({ any: 'thing' })
|
||||||
|
);
|
||||||
|
const logoffSpy = vi.spyOn(service, 'logoff').mockReturnValue(of(null));
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -725,20 +740,22 @@ describe('Logout and Revoke Service', () => {
|
|||||||
// Assert
|
// Assert
|
||||||
expect(logoffSpy).toHaveBeenCalled();
|
expect(logoffSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls logoff with urlhandler in case of success', waitForAsync(() => {
|
it('calls logoff with urlhandler in case of success', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const paramToken = 'damien';
|
const paramToken = 'damien';
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue(
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
paramToken
|
paramToken
|
||||||
);
|
);
|
||||||
spyOn(service, 'revokeRefreshToken').and.returnValue(
|
vi.spyOn(service, 'revokeRefreshToken').mockReturnValue(
|
||||||
of({ any: 'thing' })
|
of({ any: 'thing' })
|
||||||
);
|
);
|
||||||
spyOn(service, 'revokeAccessToken').and.returnValue(of({ any: 'thing' }));
|
vi.spyOn(service, 'revokeAccessToken').mockReturnValue(
|
||||||
const logoffSpy = spyOn(service, 'logoff').and.returnValue(of(null));
|
of({ any: 'thing' })
|
||||||
|
);
|
||||||
|
const logoffSpy = vi.spyOn(service, 'logoff').mockReturnValue(of(null));
|
||||||
const urlHandler = (_url: string): void => undefined;
|
const urlHandler = (_url: string): void => undefined;
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
@@ -747,26 +764,29 @@ describe('Logout and Revoke Service', () => {
|
|||||||
.logoffAndRevokeTokens(config, [config], { urlHandler })
|
.logoffAndRevokeTokens(config, [config], { urlHandler })
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(logoffSpy).toHaveBeenCalledOnceWith(config, [config], {
|
expect(logoffSpy).toHaveBeenCalledExactlyOnceWith(config, [config], {
|
||||||
urlHandler,
|
urlHandler,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('calls revokeAccessToken when storage does not hold a refreshtoken', waitForAsync(() => {
|
it('calls revokeAccessToken when storage does not hold a refreshtoken', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ revocationEndpoint: 'revocationEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
|
() => ({ revocationEndpoint: 'revocationEndpoint' })
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue('');
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
const revokeRefreshTokenSpy = spyOn(service, 'revokeRefreshToken');
|
''
|
||||||
const revokeAccessTokenSpy = spyOn(
|
);
|
||||||
service,
|
const revokeRefreshTokenSpy = vi.spyOn(service, 'revokeRefreshToken');
|
||||||
'revokeAccessToken'
|
const revokeAccessTokenSpy = vi
|
||||||
).and.returnValue(of({ any: 'thing' }));
|
.spyOn(service, 'revokeAccessToken')
|
||||||
|
.mockReturnValue(of({ any: 'thing' }));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
service.logoffAndRevokeTokens(config, [config]).subscribe(() => {
|
service.logoffAndRevokeTokens(config, [config]).subscribe(() => {
|
||||||
@@ -774,19 +794,23 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(revokeRefreshTokenSpy).not.toHaveBeenCalled();
|
expect(revokeRefreshTokenSpy).not.toHaveBeenCalled();
|
||||||
expect(revokeAccessTokenSpy).toHaveBeenCalled();
|
expect(revokeAccessTokenSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('logs error when revokeaccesstoken throws an error', waitForAsync(() => {
|
it('logs error when revokeaccesstoken throws an error', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(storagePersistenceService, 'read')
|
mockImplementationWhenArgsEqual(
|
||||||
.withArgs('authWellKnownEndPoints', config)
|
vi.spyOn(storagePersistenceService, 'read'),
|
||||||
.and.returnValue({ revocationEndpoint: 'revocationEndpoint' });
|
['authWellKnownEndPoints', config],
|
||||||
spyOn(storagePersistenceService, 'getRefreshToken').and.returnValue('');
|
() => ({ revocationEndpoint: 'revocationEndpoint' })
|
||||||
const loggerSpy = spyOn(loggerService, 'logError');
|
);
|
||||||
|
vi.spyOn(storagePersistenceService, 'getRefreshToken').mockReturnValue(
|
||||||
|
''
|
||||||
|
);
|
||||||
|
const loggerSpy = vi.spyOn(loggerService, 'logError');
|
||||||
|
|
||||||
spyOn(service, 'revokeAccessToken').and.returnValue(
|
vi.spyOn(service, 'revokeAccessToken').mockReturnValue(
|
||||||
throwError(() => new Error('Error'))
|
throwError(() => new Error('Error'))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -797,18 +821,18 @@ describe('Logout and Revoke Service', () => {
|
|||||||
expect(err).toBeTruthy();
|
expect(err).toBeTruthy();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('logoffLocalMultiple', () => {
|
describe('logoffLocalMultiple', () => {
|
||||||
it('calls logoffLocal for every config which is present', () => {
|
it('calls logoffLocal for every config which is present', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const allConfigs = [{ configId: 'configId1' }, { configId: 'configId2' }];
|
const allConfigs = [{ configId: 'configId1' }, { configId: 'configId2' }];
|
||||||
const resetAuthorizationDataSpy = spyOn(
|
const resetAuthorizationDataSpy = vi.spyOn(
|
||||||
resetAuthDataService,
|
resetAuthDataService,
|
||||||
'resetAuthorizationData'
|
'resetAuthorizationData'
|
||||||
);
|
);
|
||||||
const checkSessionServiceSpy = spyOn(checkSessionService, 'stop');
|
const checkSessionServiceSpy = vi.spyOn(checkSessionService, 'stop');
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
service.logoffLocalMultiple(allConfigs);
|
service.logoffLocalMultiple(allConfigs);
|
||||||
@@ -816,8 +840,8 @@ describe('Logout and Revoke Service', () => {
|
|||||||
// Assert
|
// Assert
|
||||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(2);
|
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(2);
|
||||||
expect(checkSessionServiceSpy).toHaveBeenCalledTimes(2);
|
expect(checkSessionServiceSpy).toHaveBeenCalledTimes(2);
|
||||||
expect(resetAuthorizationDataSpy.calls.allArgs()).toEqual([
|
expect(resetAuthorizationDataSpy).toBeCalledWith([
|
||||||
[allConfigs[0], allConfigs],
|
[allConfigs[0]!, allConfigs],
|
||||||
[allConfigs[1], allConfigs],
|
[allConfigs[1], allConfigs],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { HttpHeaders } from '@ngify/http';
|
import { HttpHeaders } from '@ngify/http';
|
||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable, of, throwError } from 'rxjs';
|
import { type Observable, of, throwError } from 'rxjs';
|
||||||
import { catchError, concatMap, retry, switchMap } from 'rxjs/operators';
|
import { catchError, concatMap, retry, switchMap } from 'rxjs/operators';
|
||||||
import { DataService } from '../api/data.service';
|
import { DataService } from '../api/data.service';
|
||||||
import { LogoutAuthOptions } from '../auth-options';
|
import type { LogoutAuthOptions } from '../auth-options';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
import { ResetAuthDataService } from '../flows/reset-auth-data.service';
|
||||||
import { CheckSessionService } from '../iframe/check-session.service';
|
import { CheckSessionService } from '../iframe/check-session.service';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,28 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { Injectable, inject } from 'injection-js';
|
||||||
import { Observable } from 'rxjs';
|
import { toSignal } from 'injection-js/rxjs-interop';
|
||||||
import { concatMap, map } from 'rxjs/operators';
|
import type { Observable } from 'rxjs';
|
||||||
import { AuthOptions, LogoutAuthOptions } from './auth-options';
|
import { concatMap, map, shareReplay } from 'rxjs/operators';
|
||||||
import { AuthenticatedResult } from './auth-state/auth-result';
|
import type { AuthOptions, LogoutAuthOptions } from './auth-options';
|
||||||
|
import type { AuthenticatedResult } from './auth-state/auth-result';
|
||||||
import { AuthStateService } from './auth-state/auth-state.service';
|
import { AuthStateService } from './auth-state/auth-state.service';
|
||||||
import { CheckAuthService } from './auth-state/check-auth.service';
|
import { CheckAuthService } from './auth-state/check-auth.service';
|
||||||
import { CallbackService } from './callback/callback.service';
|
import { CallbackService } from './callback/callback.service';
|
||||||
import { RefreshSessionService } from './callback/refresh-session.service';
|
import { RefreshSessionService } from './callback/refresh-session.service';
|
||||||
import { AuthWellKnownEndpoints } from './config/auth-well-known/auth-well-known-endpoints';
|
import type { AuthWellKnownEndpoints } from './config/auth-well-known/auth-well-known-endpoints';
|
||||||
import { AuthWellKnownService } from './config/auth-well-known/auth-well-known.service';
|
import { AuthWellKnownService } from './config/auth-well-known/auth-well-known.service';
|
||||||
import { ConfigurationService } from './config/config.service';
|
import { ConfigurationService } from './config/config.service';
|
||||||
import { OpenIdConfiguration } from './config/openid-configuration';
|
import type { OpenIdConfiguration } from './config/openid-configuration';
|
||||||
import { AuthResult } from './flows/callback-context';
|
import type { AuthResult } from './flows/callback-context';
|
||||||
import { FlowsDataService } from './flows/flows-data.service';
|
import { FlowsDataService } from './flows/flows-data.service';
|
||||||
import { CheckSessionService } from './iframe/check-session.service';
|
import { CheckSessionService } from './iframe/check-session.service';
|
||||||
import { LoginResponse } from './login/login-response';
|
import type { LoginResponse } from './login/login-response';
|
||||||
import { LoginService } from './login/login.service';
|
import { LoginService } from './login/login.service';
|
||||||
import { PopupOptions } from './login/popup/popup-options';
|
import type { PopupOptions } from './login/popup/popup-options';
|
||||||
import { LogoffRevocationService } from './logoff-revoke/logoff-revocation.service';
|
import { LogoffRevocationService } from './logoff-revoke/logoff-revocation.service';
|
||||||
import { UserService } from './user-data/user.service';
|
import { UserService } from './user-data/user.service';
|
||||||
import { UserDataResult } from './user-data/userdata-result';
|
import type { UserDataResult } from './user-data/userdata-result';
|
||||||
import { TokenHelperService } from './utils/tokenHelper/token-helper.service';
|
import { TokenHelperService } from './utils/tokenHelper/token-helper.service';
|
||||||
import { UrlService } from './utils/url/url.service';
|
import { UrlService } from './utils/url/url.service';
|
||||||
import { toSignal } from 'injection-js/rxjs-interop';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OidcSecurityService {
|
export class OidcSecurityService {
|
||||||
@@ -355,10 +355,17 @@ export class OidcSecurityService {
|
|||||||
* @param configId The configId to perform the action in behalf of. If not passed, the first configs will be taken
|
* @param configId The configId to perform the action in behalf of. If not passed, the first configs will be taken
|
||||||
* @param authOptions The custom options for the the authentication request.
|
* @param authOptions The custom options for the the authentication request.
|
||||||
*/
|
*/
|
||||||
authorize(configId?: string, authOptions?: AuthOptions): void {
|
authorize(configId?: string, authOptions?: AuthOptions): Observable<void> {
|
||||||
this.configurationService
|
const result$ = this.configurationService
|
||||||
.getOpenIDConfiguration(configId)
|
.getOpenIDConfiguration(configId)
|
||||||
.subscribe((config) => this.loginService.login(config, authOptions));
|
.pipe(
|
||||||
|
map((config) => this.loginService.login(config, authOptions)),
|
||||||
|
shareReplay(1)
|
||||||
|
);
|
||||||
|
|
||||||
|
result$.subscribe();
|
||||||
|
|
||||||
|
return result$;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -471,24 +478,34 @@ export class OidcSecurityService {
|
|||||||
*
|
*
|
||||||
* @param configId The configId to perform the action in behalf of. If not passed, the first configs will be taken
|
* @param configId The configId to perform the action in behalf of. If not passed, the first configs will be taken
|
||||||
*/
|
*/
|
||||||
logoffLocal(configId?: string): void {
|
logoffLocal(configId?: string): Observable<void> {
|
||||||
this.configurationService
|
const result$ = this.configurationService
|
||||||
.getOpenIDConfigurations(configId)
|
.getOpenIDConfigurations(configId)
|
||||||
.subscribe(({ allConfigs, currentConfig }) =>
|
.pipe(
|
||||||
this.logoffRevocationService.logoffLocal(currentConfig, allConfigs)
|
map(({ allConfigs, currentConfig }) =>
|
||||||
|
this.logoffRevocationService.logoffLocal(currentConfig, allConfigs)
|
||||||
|
),
|
||||||
|
shareReplay(1)
|
||||||
);
|
);
|
||||||
|
result$.subscribe();
|
||||||
|
return result$;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the user out of the application for all configs without logging them out of the server.
|
* Logs the user out of the application for all configs without logging them out of the server.
|
||||||
* Use this method if you have _multiple_ configs enabled.
|
* Use this method if you have _multiple_ configs enabled.
|
||||||
*/
|
*/
|
||||||
logoffLocalMultiple(): void {
|
logoffLocalMultiple(): Observable<void> {
|
||||||
this.configurationService
|
const result$ = this.configurationService.getOpenIDConfigurations().pipe(
|
||||||
.getOpenIDConfigurations()
|
map(({ allConfigs }) =>
|
||||||
.subscribe(({ allConfigs }) =>
|
|
||||||
this.logoffRevocationService.logoffLocalMultiple(allConfigs)
|
this.logoffRevocationService.logoffLocalMultiple(allConfigs)
|
||||||
);
|
),
|
||||||
|
shareReplay(1)
|
||||||
|
);
|
||||||
|
|
||||||
|
result$.subscribe();
|
||||||
|
|
||||||
|
return result$;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { APP_INITIALIZER } from '@angular/core';
|
import { TestBed, createSpyObj } from '@/testing';
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { mockProvider } from '@/testing/mock';
|
||||||
|
import { APP_INITIALIZER } from 'oidc-client-rx';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { mockProvider } from '../test/auto-mock';
|
|
||||||
import { PASSED_CONFIG } from './auth-config';
|
import { PASSED_CONFIG } from './auth-config';
|
||||||
import { ConfigurationService } from './config/config.service';
|
import { ConfigurationService } from './config/config.service';
|
||||||
import {
|
import {
|
||||||
@@ -14,14 +14,14 @@ import { provideAuth, withAppInitializerAuthCheck } from './provide-auth';
|
|||||||
|
|
||||||
describe('provideAuth', () => {
|
describe('provideAuth', () => {
|
||||||
describe('APP_CONFIG', () => {
|
describe('APP_CONFIG', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
provideAuth({ config: { authority: 'something' } }),
|
provideAuth({ config: { authority: 'something' } }),
|
||||||
mockProvider(ConfigurationService),
|
mockProvider(ConfigurationService),
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should provide config', () => {
|
it('should provide config', () => {
|
||||||
const config = TestBed.inject(PASSED_CONFIG);
|
const config = TestBed.inject(PASSED_CONFIG);
|
||||||
@@ -37,8 +37,8 @@ describe('provideAuth', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('StsConfigHttpLoader', () => {
|
describe('StsConfigHttpLoader', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
provideAuth({
|
provideAuth({
|
||||||
loader: {
|
loader: {
|
||||||
@@ -49,7 +49,7 @@ describe('provideAuth', () => {
|
|||||||
mockProvider(ConfigurationService),
|
mockProvider(ConfigurationService),
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should create StsConfigStaticLoader if config is passed', () => {
|
it('should create StsConfigStaticLoader if config is passed', () => {
|
||||||
const configLoader = TestBed.inject(StsConfigLoader);
|
const configLoader = TestBed.inject(StsConfigLoader);
|
||||||
@@ -59,14 +59,14 @@ describe('provideAuth', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('features', () => {
|
describe('features', () => {
|
||||||
let oidcSecurityServiceMock: jasmine.SpyObj<OidcSecurityService>;
|
let oidcSecurityServiceMock: OidcSecurityService;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
oidcSecurityServiceMock = jasmine.createSpyObj<OidcSecurityService>(
|
oidcSecurityServiceMock = createSpyObj<OidcSecurityService>(
|
||||||
'OidcSecurityService',
|
'OidcSecurityService',
|
||||||
['checkAuthMultiple']
|
['checkAuthMultiple']
|
||||||
);
|
);
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
provideAuth(
|
provideAuth(
|
||||||
{ config: { authority: 'something' } },
|
{ config: { authority: 'something' } },
|
||||||
@@ -79,14 +79,15 @@ describe('provideAuth', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should provide APP_INITIALIZER config', () => {
|
it('should provide APP_INITIALIZER config', () => {
|
||||||
const config = TestBed.inject(APP_INITIALIZER);
|
const config = TestBed.inject(APP_INITIALIZER);
|
||||||
|
|
||||||
expect(config.length)
|
expect(
|
||||||
.withContext('Expected an APP_INITIALIZER to be registered')
|
config.length,
|
||||||
.toBe(1);
|
'Expected an APP_INITIALIZER to be registered'
|
||||||
|
).toBe(1);
|
||||||
expect(oidcSecurityServiceMock.checkAuthMultiple).toHaveBeenCalledTimes(
|
expect(oidcSecurityServiceMock.checkAuthMultiple).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
|
import type { Provider } from 'injection-js';
|
||||||
import {
|
import {
|
||||||
APP_INITIALIZER,
|
|
||||||
EnvironmentProviders,
|
|
||||||
makeEnvironmentProviders,
|
|
||||||
Provider,
|
|
||||||
} from 'injection-js';
|
|
||||||
import {
|
|
||||||
createStaticLoader,
|
|
||||||
PASSED_CONFIG,
|
PASSED_CONFIG,
|
||||||
PassedInitialConfig,
|
type PassedInitialConfig,
|
||||||
|
createStaticLoader,
|
||||||
} from './auth-config';
|
} from './auth-config';
|
||||||
import { StsConfigLoader } from './config/loader/config-loader';
|
import { StsConfigLoader } from './config/loader/config-loader';
|
||||||
|
import { APP_INITIALIZER } from './injection';
|
||||||
import { AbstractLoggerService } from './logging/abstract-logger.service';
|
import { AbstractLoggerService } from './logging/abstract-logger.service';
|
||||||
import { ConsoleLoggerService } from './logging/console-logger.service';
|
import { ConsoleLoggerService } from './logging/console-logger.service';
|
||||||
import { OidcSecurityService } from './oidc.security.service';
|
import { OidcSecurityService } from './oidc.security.service';
|
||||||
@@ -26,14 +22,14 @@ export interface AuthFeature {
|
|||||||
export function provideAuth(
|
export function provideAuth(
|
||||||
passedConfig: PassedInitialConfig,
|
passedConfig: PassedInitialConfig,
|
||||||
...features: AuthFeature[]
|
...features: AuthFeature[]
|
||||||
): EnvironmentProviders {
|
): Provider[] {
|
||||||
const providers = _provideAuth(passedConfig);
|
const providers = _provideAuth(passedConfig);
|
||||||
|
|
||||||
for (const feature of features) {
|
for (const feature of features) {
|
||||||
providers.push(...feature.ɵproviders);
|
providers.push(...feature.ɵproviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeEnvironmentProviders(providers);
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _provideAuth(passedConfig: PassedInitialConfig): Provider[] {
|
export function _provideAuth(passedConfig: PassedInitialConfig): Provider[] {
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
|
// biome-ignore lint/nursery/noEnum: <explanation>
|
||||||
export enum EventTypes {
|
export enum EventTypes {
|
||||||
/**
|
/**
|
||||||
* This only works in the AppModule Constructor
|
* This only works in the AppModule Constructor
|
||||||
*/
|
*/
|
||||||
ConfigLoaded,
|
ConfigLoaded = 0,
|
||||||
CheckingAuth,
|
CheckingAuth = 1,
|
||||||
CheckingAuthFinished,
|
CheckingAuthFinished = 2,
|
||||||
CheckingAuthFinishedWithError,
|
CheckingAuthFinishedWithError = 3,
|
||||||
ConfigLoadingFailed,
|
ConfigLoadingFailed = 4,
|
||||||
CheckSessionReceived,
|
CheckSessionReceived = 5,
|
||||||
UserDataChanged,
|
UserDataChanged = 6,
|
||||||
NewAuthenticationResult,
|
NewAuthenticationResult = 7,
|
||||||
TokenExpired,
|
TokenExpired = 8,
|
||||||
IdTokenExpired,
|
IdTokenExpired = 9,
|
||||||
SilentRenewStarted,
|
SilentRenewStarted = 10,
|
||||||
SilentRenewFailed,
|
SilentRenewFailed = 11,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { EventTypes } from './event-types';
|
import { EventTypes } from './event-types';
|
||||||
import { PublicEventsService } from './public-events.service';
|
import { PublicEventsService } from './public-events.service';
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ describe('Events Service', () => {
|
|||||||
expect(eventsService).toBeTruthy();
|
expect(eventsService).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('registering to single event with one event emit works', waitForAsync(() => {
|
it('registering to single event with one event emit works', async () => {
|
||||||
eventsService.registerForEvents().subscribe((firedEvent) => {
|
eventsService.registerForEvents().subscribe((firedEvent) => {
|
||||||
expect(firedEvent).toBeTruthy();
|
expect(firedEvent).toBeTruthy();
|
||||||
expect(firedEvent).toEqual({
|
expect(firedEvent).toEqual({
|
||||||
@@ -29,9 +30,9 @@ describe('Events Service', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
eventsService.fireEvent(EventTypes.ConfigLoaded, { myKey: 'myValue' });
|
eventsService.fireEvent(EventTypes.ConfigLoaded, { myKey: 'myValue' });
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('registering to single event with multiple same event emit works', waitForAsync(() => {
|
it('registering to single event with multiple same event emit works', async () => {
|
||||||
const spy = jasmine.createSpy('spy');
|
const spy = jasmine.createSpy('spy');
|
||||||
|
|
||||||
eventsService.registerForEvents().subscribe((firedEvent) => {
|
eventsService.registerForEvents().subscribe((firedEvent) => {
|
||||||
@@ -50,9 +51,9 @@ describe('Events Service', () => {
|
|||||||
type: EventTypes.ConfigLoaded,
|
type: EventTypes.ConfigLoaded,
|
||||||
value: { myKey: 'myValue2' },
|
value: { myKey: 'myValue2' },
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('registering to single event with multiple emit works', waitForAsync(() => {
|
it('registering to single event with multiple emit works', async () => {
|
||||||
eventsService
|
eventsService
|
||||||
.registerForEvents()
|
.registerForEvents()
|
||||||
.pipe(filter((x) => x.type === EventTypes.ConfigLoaded))
|
.pipe(filter((x) => x.type === EventTypes.ConfigLoaded))
|
||||||
@@ -65,5 +66,5 @@ describe('Events Service', () => {
|
|||||||
});
|
});
|
||||||
eventsService.fireEvent(EventTypes.ConfigLoaded, { myKey: 'myValue' });
|
eventsService.fireEvent(EventTypes.ConfigLoaded, { myKey: 'myValue' });
|
||||||
eventsService.fireEvent(EventTypes.NewAuthenticationResult, true);
|
eventsService.fireEvent(EventTypes.NewAuthenticationResult, true);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
27
src/router/index.ts
Normal file
27
src/router/index.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
export type RouteData = {
|
||||||
|
[key: string | symbol]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface ActivatedRouteSnapshot {
|
||||||
|
data: RouteData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RouterStateSnapshot {
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class AbstractRouter {
|
||||||
|
navigateByUrl(url: string): void {
|
||||||
|
// TODO
|
||||||
|
// Implementation of navigating to a URL
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentNavigation(): any {
|
||||||
|
// TODO
|
||||||
|
// Implementation of getting the current navigation
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
parseUrl(url: string) {}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockClass, mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
import { LoggerService } from '../logging/logger.service';
|
import { LoggerService } from '../logging/logger.service';
|
||||||
|
import { mockClass, mockProvider } from '../testing/mock';
|
||||||
import { AbstractSecurityStorage } from './abstract-security-storage';
|
import { AbstractSecurityStorage } from './abstract-security-storage';
|
||||||
import { BrowserStorageService } from './browser-storage.service';
|
import { BrowserStorageService } from './browser-storage.service';
|
||||||
import { DefaultSessionStorageService } from './default-sessionstorage.service';
|
import { DefaultSessionStorageService } from './default-sessionstorage.service';
|
||||||
@@ -34,7 +35,7 @@ describe('BrowserStorageService', () => {
|
|||||||
it('returns null if there is no storage', () => {
|
it('returns null if there is no storage', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(false);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(false);
|
||||||
|
|
||||||
expect(service.read('anything', config)).toBeNull();
|
expect(service.read('anything', config)).toBeNull();
|
||||||
});
|
});
|
||||||
@@ -42,7 +43,7 @@ describe('BrowserStorageService', () => {
|
|||||||
it('returns null if getItem returns null', () => {
|
it('returns null if getItem returns null', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(true);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(true);
|
||||||
|
|
||||||
const result = service.read('anything', config);
|
const result = service.read('anything', config);
|
||||||
|
|
||||||
@@ -52,10 +53,10 @@ describe('BrowserStorageService', () => {
|
|||||||
it('returns the item if getItem returns an item', () => {
|
it('returns the item if getItem returns an item', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(true);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(true);
|
||||||
const returnValue = `{ "name":"John", "age":30, "city":"New York"}`;
|
const returnValue = `{ "name":"John", "age":30, "city":"New York"}`;
|
||||||
|
|
||||||
spyOn(abstractSecurityStorage, 'read').and.returnValue(returnValue);
|
vi.spyOn(abstractSecurityStorage, 'read').mockReturnValue(returnValue);
|
||||||
const result = service.read('anything', config);
|
const result = service.read('anything', config);
|
||||||
|
|
||||||
expect(result).toEqual(JSON.parse(returnValue));
|
expect(result).toEqual(JSON.parse(returnValue));
|
||||||
@@ -66,24 +67,21 @@ describe('BrowserStorageService', () => {
|
|||||||
it('returns false if there is no storage', () => {
|
it('returns false if there is no storage', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(false);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(false);
|
||||||
|
|
||||||
expect(service.write('anyvalue', config)).toBeFalse();
|
expect(service.write('anyvalue', config)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('writes object correctly with configId', () => {
|
it('writes object correctly with configId', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(true);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(true);
|
||||||
const writeSpy = spyOn(
|
const writeSpy = vi.spyOn(abstractSecurityStorage, 'write')();
|
||||||
abstractSecurityStorage,
|
|
||||||
'write'
|
|
||||||
).and.callThrough();
|
|
||||||
|
|
||||||
const result = service.write({ anyKey: 'anyvalue' }, config);
|
const result = service.write({ anyKey: 'anyvalue' }, config);
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith(
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'configId1',
|
'configId1',
|
||||||
JSON.stringify({ anyKey: 'anyvalue' })
|
JSON.stringify({ anyKey: 'anyvalue' })
|
||||||
);
|
);
|
||||||
@@ -92,18 +90,15 @@ describe('BrowserStorageService', () => {
|
|||||||
it('writes null if item is falsy', () => {
|
it('writes null if item is falsy', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(true);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(true);
|
||||||
|
|
||||||
const writeSpy = spyOn(
|
const writeSpy = vi.spyOn(abstractSecurityStorage, 'write')();
|
||||||
abstractSecurityStorage,
|
|
||||||
'write'
|
|
||||||
).and.callThrough();
|
|
||||||
const somethingFalsy = '';
|
const somethingFalsy = '';
|
||||||
|
|
||||||
const result = service.write(somethingFalsy, config);
|
const result = service.write(somethingFalsy, config);
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith(
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
'configId1',
|
'configId1',
|
||||||
JSON.stringify(null)
|
JSON.stringify(null)
|
||||||
);
|
);
|
||||||
@@ -114,41 +109,35 @@ describe('BrowserStorageService', () => {
|
|||||||
it('returns false if there is no storage', () => {
|
it('returns false if there is no storage', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(false);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(false);
|
||||||
expect(service.remove('anything', config)).toBeFalse();
|
expect(service.remove('anything', config)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if removeItem is called', () => {
|
it('returns true if removeItem is called', () => {
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(true);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(true);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
const setItemSpy = spyOn(
|
const setItemSpy = vi.spyOn(abstractSecurityStorage, 'remove')();
|
||||||
abstractSecurityStorage,
|
|
||||||
'remove'
|
|
||||||
).and.callThrough();
|
|
||||||
|
|
||||||
const result = service.remove('anyKey', config);
|
const result = service.remove('anyKey', config);
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(setItemSpy).toHaveBeenCalledOnceWith('anyKey');
|
expect(setItemSpy).toHaveBeenCalledExactlyOnceWith('anyKey');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('clear', () => {
|
describe('clear', () => {
|
||||||
it('returns false if there is no storage', () => {
|
it('returns false if there is no storage', () => {
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(false);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(false);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
expect(service.clear(config)).toBeFalse();
|
expect(service.clear(config)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if clear is called', () => {
|
it('returns true if clear is called', () => {
|
||||||
spyOn(service as any, 'hasStorage').and.returnValue(true);
|
vi.spyOn(service as any, 'hasStorage').mockReturnValue(true);
|
||||||
|
|
||||||
const setItemSpy = spyOn(
|
const setItemSpy = vi.spyOn(abstractSecurityStorage, 'clear')();
|
||||||
abstractSecurityStorage,
|
|
||||||
'clear'
|
|
||||||
).and.callThrough();
|
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
const result = service.clear(config);
|
const result = service.clear(config);
|
||||||
@@ -161,7 +150,7 @@ describe('BrowserStorageService', () => {
|
|||||||
describe('hasStorage', () => {
|
describe('hasStorage', () => {
|
||||||
it('returns false if there is no storage', () => {
|
it('returns false if there is no storage', () => {
|
||||||
(Storage as any) = undefined;
|
(Storage as any) = undefined;
|
||||||
expect((service as any).hasStorage()).toBeFalse();
|
expect((service as any).hasStorage()).toBeFalsy();
|
||||||
Storage = Storage;
|
Storage = Storage;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { DefaultLocalStorageService } from './default-localstorage.service';
|
import { DefaultLocalStorageService } from './default-localstorage.service';
|
||||||
|
|
||||||
describe('DefaultLocalStorageService', () => {
|
describe('DefaultLocalStorageService', () => {
|
||||||
@@ -20,37 +21,37 @@ describe('DefaultLocalStorageService', () => {
|
|||||||
|
|
||||||
describe('read', () => {
|
describe('read', () => {
|
||||||
it('should call localstorage.getItem', () => {
|
it('should call localstorage.getItem', () => {
|
||||||
const spy = spyOn(localStorage, 'getItem');
|
const spy = vi.spyOn(localStorage, 'getItem');
|
||||||
|
|
||||||
service.read('henlo');
|
service.read('henlo');
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('henlo');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('henlo');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('write', () => {
|
describe('write', () => {
|
||||||
it('should call localstorage.setItem', () => {
|
it('should call localstorage.setItem', () => {
|
||||||
const spy = spyOn(localStorage, 'setItem');
|
const spy = vi.spyOn(localStorage, 'setItem');
|
||||||
|
|
||||||
service.write('henlo', 'furiend');
|
service.write('henlo', 'furiend');
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('henlo', 'furiend');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('henlo', 'furiend');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remove', () => {
|
describe('remove', () => {
|
||||||
it('should call localstorage.removeItem', () => {
|
it('should call localstorage.removeItem', () => {
|
||||||
const spy = spyOn(localStorage, 'removeItem');
|
const spy = vi.spyOn(localStorage, 'removeItem');
|
||||||
|
|
||||||
service.remove('henlo');
|
service.remove('henlo');
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('henlo');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('henlo');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('clear', () => {
|
describe('clear', () => {
|
||||||
it('should call localstorage.clear', () => {
|
it('should call localstorage.clear', () => {
|
||||||
const spy = spyOn(localStorage, 'clear');
|
const spy = vi.spyOn(localStorage, 'clear');
|
||||||
|
|
||||||
service.clear();
|
service.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
|
import { vi } from 'vitest';
|
||||||
import { DefaultSessionStorageService } from './default-sessionstorage.service';
|
import { DefaultSessionStorageService } from './default-sessionstorage.service';
|
||||||
|
|
||||||
describe('DefaultSessionStorageService', () => {
|
describe('DefaultSessionStorageService', () => {
|
||||||
@@ -20,37 +21,37 @@ describe('DefaultSessionStorageService', () => {
|
|||||||
|
|
||||||
describe('read', () => {
|
describe('read', () => {
|
||||||
it('should call sessionstorage.getItem', () => {
|
it('should call sessionstorage.getItem', () => {
|
||||||
const spy = spyOn(sessionStorage, 'getItem');
|
const spy = vi.spyOn(sessionStorage, 'getItem');
|
||||||
|
|
||||||
service.read('henlo');
|
service.read('henlo');
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('henlo');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('henlo');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('write', () => {
|
describe('write', () => {
|
||||||
it('should call sessionstorage.setItem', () => {
|
it('should call sessionstorage.setItem', () => {
|
||||||
const spy = spyOn(sessionStorage, 'setItem');
|
const spy = vi.spyOn(sessionStorage, 'setItem');
|
||||||
|
|
||||||
service.write('henlo', 'furiend');
|
service.write('henlo', 'furiend');
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('henlo', 'furiend');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('henlo', 'furiend');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remove', () => {
|
describe('remove', () => {
|
||||||
it('should call sessionstorage.removeItem', () => {
|
it('should call sessionstorage.removeItem', () => {
|
||||||
const spy = spyOn(sessionStorage, 'removeItem');
|
const spy = vi.spyOn(sessionStorage, 'removeItem');
|
||||||
|
|
||||||
service.remove('henlo');
|
service.remove('henlo');
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledOnceWith('henlo');
|
expect(spy).toHaveBeenCalledExactlyOnceWith('henlo');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('clear', () => {
|
describe('clear', () => {
|
||||||
it('should call sessionstorage.clear', () => {
|
it('should call sessionstorage.clear', () => {
|
||||||
const spy = spyOn(sessionStorage, 'clear');
|
const spy = vi.spyOn(sessionStorage, 'clear');
|
||||||
|
|
||||||
service.clear();
|
service.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@/testing';
|
||||||
import { mockProvider } from '../../test/auto-mock';
|
import { vi } from 'vitest';
|
||||||
|
import { mockProvider } from '../testing/mock';
|
||||||
import { BrowserStorageService } from './browser-storage.service';
|
import { BrowserStorageService } from './browser-storage.service';
|
||||||
import { StoragePersistenceService } from './storage-persistence.service';
|
import { StoragePersistenceService } from './storage-persistence.service';
|
||||||
|
|
||||||
@@ -25,16 +26,16 @@ describe('Storage Persistence Service', () => {
|
|||||||
describe('read', () => {
|
describe('read', () => {
|
||||||
it('reads from oidcSecurityStorage with configId', () => {
|
it('reads from oidcSecurityStorage with configId', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const spy = spyOn(securityStorage, 'read');
|
const spy = vi.spyOn(securityStorage, 'read');
|
||||||
|
|
||||||
service.read('authNonce', config);
|
service.read('authNonce', config);
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authNonce', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authNonce', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns undefined (not throws exception) if key to read is not present on config', () => {
|
it('returns undefined (not throws exception) if key to read is not present on config', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
|
|
||||||
spyOn(securityStorage, 'read').and.returnValue({ some: 'thing' });
|
vi.spyOn(securityStorage, 'read').mockReturnValue({ some: 'thing' });
|
||||||
const result = service.read('authNonce', config);
|
const result = service.read('authNonce', config);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
@@ -44,13 +45,13 @@ describe('Storage Persistence Service', () => {
|
|||||||
describe('write', () => {
|
describe('write', () => {
|
||||||
it('writes to oidcSecurityStorage with correct key and correct config', () => {
|
it('writes to oidcSecurityStorage with correct key and correct config', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const readSpy = spyOn(securityStorage, 'read');
|
const readSpy = vi.spyOn(securityStorage, 'read');
|
||||||
const writeSpy = spyOn(securityStorage, 'write');
|
const writeSpy = vi.spyOn(securityStorage, 'write');
|
||||||
|
|
||||||
service.write('authNonce', 'anyValue', config);
|
service.write('authNonce', 'anyValue', config);
|
||||||
|
|
||||||
expect(readSpy).toHaveBeenCalledOnceWith('authNonce', config);
|
expect(readSpy).toHaveBeenCalledExactlyOnceWith('authNonce', config);
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith(
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith(
|
||||||
{ authNonce: 'anyValue' },
|
{ authNonce: 'anyValue' },
|
||||||
config
|
config
|
||||||
);
|
);
|
||||||
@@ -60,32 +61,32 @@ describe('Storage Persistence Service', () => {
|
|||||||
describe('remove', () => {
|
describe('remove', () => {
|
||||||
it('should remove key from config', () => {
|
it('should remove key from config', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const readSpy = spyOn(securityStorage, 'read').and.returnValue({
|
const readSpy = vi.spyOn(securityStorage, 'read').mockReturnValue({
|
||||||
authNonce: 'anyValue',
|
authNonce: 'anyValue',
|
||||||
});
|
});
|
||||||
const writeSpy = spyOn(securityStorage, 'write');
|
const writeSpy = vi.spyOn(securityStorage, 'write');
|
||||||
|
|
||||||
service.remove('authNonce', config);
|
service.remove('authNonce', config);
|
||||||
|
|
||||||
expect(readSpy).toHaveBeenCalledOnceWith('authNonce', config);
|
expect(readSpy).toHaveBeenCalledExactlyOnceWith('authNonce', config);
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith({}, config);
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith({}, config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not crash when read with configId returns null', () => {
|
it('does not crash when read with configId returns null', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const readSpy = spyOn(securityStorage, 'read').and.returnValue(null);
|
const readSpy = vi.spyOn(securityStorage, 'read').mockReturnValue(null);
|
||||||
const writeSpy = spyOn(securityStorage, 'write');
|
const writeSpy = vi.spyOn(securityStorage, 'write');
|
||||||
|
|
||||||
service.remove('authNonce', config);
|
service.remove('authNonce', config);
|
||||||
|
|
||||||
expect(readSpy).toHaveBeenCalledOnceWith('authNonce', config);
|
expect(readSpy).toHaveBeenCalledExactlyOnceWith('authNonce', config);
|
||||||
expect(writeSpy).toHaveBeenCalledOnceWith({}, config);
|
expect(writeSpy).toHaveBeenCalledExactlyOnceWith({}, config);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('clear', () => {
|
describe('clear', () => {
|
||||||
it('should call oidcSecurityStorage.clear()', () => {
|
it('should call oidcSecurityStorage.clear()', () => {
|
||||||
const clearSpy = spyOn(securityStorage, 'clear');
|
const clearSpy = vi.spyOn(securityStorage, 'clear');
|
||||||
|
|
||||||
service.clear({});
|
service.clear({});
|
||||||
|
|
||||||
@@ -96,49 +97,58 @@ describe('Storage Persistence Service', () => {
|
|||||||
describe('resetStorageFlowData', () => {
|
describe('resetStorageFlowData', () => {
|
||||||
it('resets the correct values', () => {
|
it('resets the correct values', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const spy = spyOn(service, 'remove');
|
const spy = vi.spyOn(service, 'remove');
|
||||||
|
|
||||||
service.resetStorageFlowData(config);
|
service.resetStorageFlowData(config);
|
||||||
|
|
||||||
expect(spy).toHaveBeenCalledTimes(10);
|
expect(spy).toHaveBeenCalledTimes(10);
|
||||||
expect(spy.calls.argsFor(0)).toEqual(['session_state', config]);
|
expect(vi.mocked(spy).mock.calls[0]).toEqual(['session_state', config]);
|
||||||
expect(spy.calls.argsFor(1)).toEqual([
|
expect(vi.mocked(spy).mock.calls[1]).toEqual([
|
||||||
'storageSilentRenewRunning',
|
'storageSilentRenewRunning',
|
||||||
config,
|
config,
|
||||||
]);
|
]);
|
||||||
expect(spy.calls.argsFor(2)).toEqual([
|
expect(vi.mocked(spy).mock.calls[2]).toEqual([
|
||||||
'storageCodeFlowInProgress',
|
'storageCodeFlowInProgress',
|
||||||
config,
|
config,
|
||||||
]);
|
]);
|
||||||
expect(spy.calls.argsFor(3)).toEqual(['codeVerifier', config]);
|
expect(vi.mocked(spy).mock.calls[3]).toEqual(['codeVerifier', config]);
|
||||||
expect(spy.calls.argsFor(4)).toEqual(['userData', config]);
|
expect(vi.mocked(spy).mock.calls[4]).toEqual(['userData', config]);
|
||||||
expect(spy.calls.argsFor(5)).toEqual([
|
expect(vi.mocked(spy).mock.calls[5]).toEqual([
|
||||||
'storageCustomParamsAuthRequest',
|
'storageCustomParamsAuthRequest',
|
||||||
config,
|
config,
|
||||||
]);
|
]);
|
||||||
expect(spy.calls.argsFor(6)).toEqual(['access_token_expires_at', config]);
|
expect(vi.mocked(spy).mock.calls[6]).toEqual([
|
||||||
expect(spy.calls.argsFor(7)).toEqual([
|
'access_token_expires_at',
|
||||||
|
config,
|
||||||
|
]);
|
||||||
|
expect(vi.mocked(spy).mock.calls[7]).toEqual([
|
||||||
'storageCustomParamsRefresh',
|
'storageCustomParamsRefresh',
|
||||||
config,
|
config,
|
||||||
]);
|
]);
|
||||||
expect(spy.calls.argsFor(8)).toEqual([
|
expect(vi.mocked(spy).mock.calls[8]).toEqual([
|
||||||
'storageCustomParamsEndSession',
|
'storageCustomParamsEndSession',
|
||||||
config,
|
config,
|
||||||
]);
|
]);
|
||||||
expect(spy.calls.argsFor(9)).toEqual(['reusable_refresh_token', config]);
|
expect(vi.mocked(spy).mock.calls[9]).toEqual([
|
||||||
|
'reusable_refresh_token',
|
||||||
|
config,
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resetAuthStateInStorage', () => {
|
describe('resetAuthStateInStorage', () => {
|
||||||
it('resets the correct values', () => {
|
it('resets the correct values', () => {
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const spy = spyOn(service, 'remove');
|
const spy = vi.spyOn(service, 'remove');
|
||||||
|
|
||||||
service.resetAuthStateInStorage(config);
|
service.resetAuthStateInStorage(config);
|
||||||
|
|
||||||
expect(spy.calls.argsFor(0)).toEqual(['authzData', config]);
|
expect(vi.mocked(spy).mock.calls[0]).toEqual(['authzData', config]);
|
||||||
expect(spy.calls.argsFor(1)).toEqual(['reusable_refresh_token', config]);
|
expect(vi.mocked(spy).mock.calls[1]).toEqual([
|
||||||
expect(spy.calls.argsFor(2)).toEqual(['authnResult', config]);
|
'reusable_refresh_token',
|
||||||
|
config,
|
||||||
|
]);
|
||||||
|
expect(vi.mocked(spy).mock.calls[2]).toEqual(['authnResult', config]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -146,41 +156,45 @@ describe('Storage Persistence Service', () => {
|
|||||||
it('get calls oidcSecurityStorage.read with correct key and returns the value', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns the value', () => {
|
||||||
const returnValue = { authzData: 'someValue' };
|
const returnValue = { authzData: 'someValue' };
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(returnValue);
|
const spy = vi
|
||||||
|
.spyOn(securityStorage, 'read')
|
||||||
|
.mockReturnValue(returnValue);
|
||||||
const result = service.getAccessToken(config);
|
const result = service.getAccessToken(config);
|
||||||
|
|
||||||
expect(result).toBe('someValue');
|
expect(result).toBe('someValue');
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authzData', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authzData', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(null);
|
const spy = vi.spyOn(securityStorage, 'read').mockReturnValue(null);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getAccessToken(config);
|
const result = service.getAccessToken(config);
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
expect(result).toBeFalsy();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authzData', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authzData', config);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getIdToken', () => {
|
describe('getIdToken', () => {
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns the value', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns the value', () => {
|
||||||
const returnValue = { authnResult: { id_token: 'someValue' } };
|
const returnValue = { authnResult: { id_token: 'someValue' } };
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(returnValue);
|
const spy = vi
|
||||||
|
.spyOn(securityStorage, 'read')
|
||||||
|
.mockReturnValue(returnValue);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getIdToken(config);
|
const result = service.getIdToken(config);
|
||||||
|
|
||||||
expect(result).toBe('someValue');
|
expect(result).toBe('someValue');
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(null);
|
const spy = vi.spyOn(securityStorage, 'read').mockReturnValue(null);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getIdToken(config);
|
const result = service.getIdToken(config);
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
expect(result).toBeFalsy();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -188,32 +202,36 @@ describe('Storage Persistence Service', () => {
|
|||||||
it('get calls oidcSecurityStorage.read with correct key and returns the value', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns the value', () => {
|
||||||
const returnValue = { authnResult: { id_token: 'someValue' } };
|
const returnValue = { authnResult: { id_token: 'someValue' } };
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(returnValue);
|
const spy = vi
|
||||||
|
.spyOn(securityStorage, 'read')
|
||||||
|
.mockReturnValue(returnValue);
|
||||||
const result = service.getAuthenticationResult(config);
|
const result = service.getAuthenticationResult(config);
|
||||||
|
|
||||||
expect(result.id_token).toBe('someValue');
|
expect(result.id_token).toBe('someValue');
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(null);
|
const spy = vi.spyOn(securityStorage, 'read').mockReturnValue(null);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getAuthenticationResult(config);
|
const result = service.getAuthenticationResult(config);
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
expect(result).toBeFalsy();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getRefreshToken', () => {
|
describe('getRefreshToken', () => {
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns the value (refresh token with mandatory rotation - default)', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns the value (refresh token with mandatory rotation - default)', () => {
|
||||||
const returnValue = { authnResult: { refresh_token: 'someValue' } };
|
const returnValue = { authnResult: { refresh_token: 'someValue' } };
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(returnValue);
|
const spy = vi
|
||||||
|
.spyOn(securityStorage, 'read')
|
||||||
|
.mockReturnValue(returnValue);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getRefreshToken(config);
|
const result = service.getRefreshToken(config);
|
||||||
|
|
||||||
expect(result).toBe('someValue');
|
expect(result).toBe('someValue');
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns the value (refresh token without rotation)', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns the value (refresh token without rotation)', () => {
|
||||||
@@ -222,12 +240,12 @@ describe('Storage Persistence Service', () => {
|
|||||||
configId: 'configId1',
|
configId: 'configId1',
|
||||||
allowUnsafeReuseRefreshToken: true,
|
allowUnsafeReuseRefreshToken: true,
|
||||||
};
|
};
|
||||||
const spy = spyOn(securityStorage, 'read');
|
const spy = vi.spyOn(securityStorage, 'read');
|
||||||
|
|
||||||
spy
|
spy
|
||||||
.withArgs('reusable_refresh_token', config)
|
.withArgs('reusable_refresh_token', config)
|
||||||
.and.returnValue(returnValue);
|
.mockReturnValue(returnValue);
|
||||||
spy.withArgs('authnResult', config).and.returnValue(undefined);
|
spy.withArgs('authnResult', config).mockReturnValue(undefined);
|
||||||
const result = service.getRefreshToken(config);
|
const result = service.getRefreshToken(config);
|
||||||
|
|
||||||
expect(result).toBe(returnValue.reusable_refresh_token);
|
expect(result).toBe(returnValue.reusable_refresh_token);
|
||||||
@@ -238,21 +256,23 @@ describe('Storage Persistence Service', () => {
|
|||||||
|
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
||||||
const returnValue = { authnResult: { NO_refresh_token: 'someValue' } };
|
const returnValue = { authnResult: { NO_refresh_token: 'someValue' } };
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(returnValue);
|
const spy = vi
|
||||||
|
.spyOn(securityStorage, 'read')
|
||||||
|
.mockReturnValue(returnValue);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getRefreshToken(config);
|
const result = service.getRefreshToken(config);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
it('get calls oidcSecurityStorage.read with correct key and returns null', () => {
|
||||||
const spy = spyOn(securityStorage, 'read').and.returnValue(null);
|
const spy = vi.spyOn(securityStorage, 'read').mockReturnValue(null);
|
||||||
const config = { configId: 'configId1' };
|
const config = { configId: 'configId1' };
|
||||||
const result = service.getRefreshToken(config);
|
const result = service.getRefreshToken(config);
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
expect(spy).toHaveBeenCalledOnceWith('authnResult', config);
|
expect(spy).toHaveBeenCalledExactlyOnceWith('authnResult', config);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { inject, Injectable } from 'injection-js';
|
import { inject } from 'injection-js';
|
||||||
import { AuthResult } from '../flows/callback-context';
|
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
import type { AuthResult } from '../flows/callback-context';
|
||||||
import { BrowserStorageService } from './browser-storage.service';
|
import { BrowserStorageService } from './browser-storage.service';
|
||||||
|
|
||||||
export type StorageKeys =
|
export type StorageKeys =
|
||||||
@@ -24,7 +24,6 @@ export type StorageKeys =
|
|||||||
| 'jwtKeys'
|
| 'jwtKeys'
|
||||||
| 'popupauth';
|
| 'popupauth';
|
||||||
|
|
||||||
|
|
||||||
export class StoragePersistenceService {
|
export class StoragePersistenceService {
|
||||||
private readonly browserStorageService = inject(BrowserStorageService);
|
private readonly browserStorageService = inject(BrowserStorageService);
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user