feat: init
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||
import { HttpErrorResponse, HttpHeaders } from '@ngify/http';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
import { createRetriableStream } from '../../../test/create-retriable-stream.helper';
|
||||
import { vi } from 'vitest';
|
||||
import { DataService } from '../../api/data.service';
|
||||
import { LoggerService } from '../../logging/logger.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 { TokenValidationService } from '../../validation/token-validation.service';
|
||||
import { CallbackContext } from '../callback-context';
|
||||
import type { CallbackContext } from '../callback-context';
|
||||
import { FlowsDataService } from '../flows-data.service';
|
||||
import { CodeFlowCallbackHandlerService } from './code-flow-callback-handler.service';
|
||||
|
||||
@@ -46,13 +47,16 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
});
|
||||
|
||||
describe('codeFlowCallback', () => {
|
||||
it('throws error if no state is given', waitForAsync(() => {
|
||||
const getUrlParameterSpy = spyOn(
|
||||
urlService,
|
||||
'getUrlParameter'
|
||||
).and.returnValue('params');
|
||||
it('throws error if no state is given', async () => {
|
||||
const getUrlParameterSpy = vi
|
||||
.spyOn(urlService, 'getUrlParameter')
|
||||
.mockReturnValue('params');
|
||||
|
||||
getUrlParameterSpy.withArgs('test-url', 'state').and.returnValue('');
|
||||
mockImplementationWhenArgsEqual(
|
||||
getUrlParameterSpy,
|
||||
['test-url', 'state'],
|
||||
() => ''
|
||||
);
|
||||
|
||||
service
|
||||
.codeFlowCallback('test-url', { configId: 'configId1' })
|
||||
@@ -61,15 +65,14 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('throws error if no code is given', waitForAsync(() => {
|
||||
const getUrlParameterSpy = spyOn(
|
||||
urlService,
|
||||
'getUrlParameter'
|
||||
).and.returnValue('params');
|
||||
it('throws error if no code is given', async () => {
|
||||
const getUrlParameterSpy = vi
|
||||
.spyOn(urlService, 'getUrlParameter')
|
||||
.mockReturnValue('params');
|
||||
|
||||
getUrlParameterSpy.withArgs('test-url', 'code').and.returnValue('');
|
||||
getUrlParameterSpy.withArgs('test-url', 'code').mockReturnValue('');
|
||||
|
||||
service
|
||||
.codeFlowCallback('test-url', { configId: 'configId1' })
|
||||
@@ -78,10 +81,10 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('returns callbackContext if all params are good', waitForAsync(() => {
|
||||
spyOn(urlService, 'getUrlParameter').and.returnValue('params');
|
||||
it('returns callbackContext if all params are good', async () => {
|
||||
vi.spyOn(urlService, 'getUrlParameter').mockReturnValue('params');
|
||||
|
||||
const expectedCallbackContext = {
|
||||
code: 'params',
|
||||
@@ -100,7 +103,7 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
.subscribe((callbackContext) => {
|
||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('codeFlowCodeRequest ', () => {
|
||||
@@ -112,11 +115,11 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
url: 'https://identity-server.test/openid-connect/token',
|
||||
});
|
||||
|
||||
it('throws error if state is not correct', waitForAsync(() => {
|
||||
spyOn(
|
||||
it('throws error if state is not correct', async () => {
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(false);
|
||||
).mockReturnValue(false);
|
||||
|
||||
service
|
||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||
@@ -125,16 +128,18 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('throws error if authWellknownEndpoints is null is given', waitForAsync(() => {
|
||||
spyOn(
|
||||
it('throws error if authWellknownEndpoints is null is given', async () => {
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue(null);
|
||||
).mockReturnValue(true);
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => null
|
||||
);
|
||||
|
||||
service
|
||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||
@@ -143,16 +148,18 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('throws error if tokenendpoint is null is given', waitForAsync(() => {
|
||||
spyOn(
|
||||
it('throws error if tokenendpoint is null is given', async () => {
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ tokenEndpoint: null });
|
||||
).mockReturnValue(true);
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ tokenEndpoint: null })
|
||||
);
|
||||
|
||||
service
|
||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||
@@ -161,34 +168,36 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls dataService if all params are good', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
||||
it('calls dataService if all params are good', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
spyOn(
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
).mockReturnValue(true);
|
||||
|
||||
service
|
||||
.codeFlowCodeRequest({} as CallbackContext, { configId: 'configId1' })
|
||||
.subscribe(() => {
|
||||
expect(postSpy).toHaveBeenCalledOnceWith(
|
||||
expect(postSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
'tokenEndpoint',
|
||||
undefined,
|
||||
{ configId: 'configId1' },
|
||||
jasmine.any(HttpHeaders)
|
||||
expect.any(HttpHeaders)
|
||||
);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls url service with custom token params', waitForAsync(() => {
|
||||
const urlServiceSpy = spyOn(
|
||||
it('calls url service with custom token params', async () => {
|
||||
const urlServiceSpy = vi.spyOn(
|
||||
urlService,
|
||||
'createBodyForCodeFlowCodeRequest'
|
||||
);
|
||||
@@ -197,76 +206,84 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
customParamsCodeRequest: { foo: 'bar' },
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
spyOn(
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
).mockReturnValue(true);
|
||||
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||
|
||||
service
|
||||
.codeFlowCodeRequest({ code: 'foo' } as CallbackContext, config)
|
||||
.subscribe(() => {
|
||||
expect(urlServiceSpy).toHaveBeenCalledOnceWith('foo', config, {
|
||||
expect(urlServiceSpy).toHaveBeenCalledExactlyOnceWith('foo', config, {
|
||||
foo: 'bar',
|
||||
});
|
||||
expect(postSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls dataService with correct headers if all params are good', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
||||
it('calls dataService with correct headers if all params are good', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||
const config = {
|
||||
configId: 'configId1',
|
||||
customParamsCodeRequest: { foo: 'bar' },
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
spyOn(
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
).mockReturnValue(true);
|
||||
|
||||
service
|
||||
.codeFlowCodeRequest({} as CallbackContext, config)
|
||||
.subscribe(() => {
|
||||
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(
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('returns error in case of http error', waitForAsync(() => {
|
||||
spyOn(dataService, 'post').and.returnValue(throwError(() => HTTP_ERROR));
|
||||
it('returns error in case of http error', async () => {
|
||||
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||
throwError(() => HTTP_ERROR)
|
||||
);
|
||||
const config = {
|
||||
configId: 'configId1',
|
||||
customParamsCodeRequest: { foo: 'bar' },
|
||||
authority: 'authority',
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
||||
error: (err) => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('retries request in case of no connection http error and succeeds', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
||||
it('retries request in case of no connection http error and succeeds', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => CONNECTION_ERROR),
|
||||
of({})
|
||||
@@ -278,14 +295,16 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
authority: 'authority',
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
spyOn(
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
).mockReturnValue(true);
|
||||
|
||||
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
||||
next: (res) => {
|
||||
@@ -297,10 +316,10 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(err).toBeFalsy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('retries request in case of no connection http error and fails because of http error afterwards', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
||||
it('retries request in case of no connection http error and fails because of http error afterwards', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => CONNECTION_ERROR),
|
||||
throwError(() => HTTP_ERROR)
|
||||
@@ -312,14 +331,16 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
authority: 'authority',
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
spyOn(
|
||||
vi.spyOn(
|
||||
tokenValidationService,
|
||||
'validateStateFromHashCallback'
|
||||
).and.returnValue(true);
|
||||
).mockReturnValue(true);
|
||||
|
||||
service.codeFlowCodeRequest({} as CallbackContext, config).subscribe({
|
||||
next: (res) => {
|
||||
@@ -331,6 +352,6 @@ describe('CodeFlowCallbackHandlerService', () => {
|
||||
expect(postSpy).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { HttpErrorResponse } from '@ngify/http';
|
||||
import { isNetworkError } from './error-helper';
|
||||
|
||||
describe('error helper', () => {
|
||||
@@ -27,31 +27,31 @@ describe('error helper', () => {
|
||||
});
|
||||
|
||||
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', () => {
|
||||
expect(isNetworkError(UNKNOWN_CONNECTION_ERROR)).toBeTrue();
|
||||
expect(isNetworkError(UNKNOWN_CONNECTION_ERROR)).toBeTruthy();
|
||||
});
|
||||
|
||||
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', () => {
|
||||
expect(isNetworkError(new Error('not a HttpErrorResponse'))).toBeFalse();
|
||||
expect(isNetworkError(new Error('not a HttpErrorResponse'))).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns false on string error', () => {
|
||||
expect(isNetworkError('not a HttpErrorResponse')).toBeFalse();
|
||||
expect(isNetworkError('not a HttpErrorResponse')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns false on undefined', () => {
|
||||
expect(isNetworkError(undefined)).toBeFalse();
|
||||
expect(isNetworkError(undefined)).toBeFalsy();
|
||||
});
|
||||
|
||||
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 { mockProvider } from '../../../test/auto-mock';
|
||||
import { vi } from 'vitest';
|
||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||
import { LoggerService } from '../../logging/logger.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 { AuthResult, CallbackContext } from '../callback-context';
|
||||
import type { AuthResult, CallbackContext } from '../callback-context';
|
||||
import { FlowsDataService } from '../flows-data.service';
|
||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||
import { SigninKeyDataService } from '../signin-key-data.service';
|
||||
@@ -46,9 +47,6 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
mockProvider(ResetAuthDataService),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(HistoryJwtKeysCallbackHandlerService);
|
||||
storagePersistenceService = TestBed.inject(StoragePersistenceService);
|
||||
resetAuthDataService = TestBed.inject(ResetAuthDataService);
|
||||
@@ -62,8 +60,8 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
});
|
||||
|
||||
describe('callbackHistoryAndResetJwtKeys', () => {
|
||||
it('writes authResult into the storage', waitForAsync(() => {
|
||||
const storagePersistenceServiceSpy = spyOn(
|
||||
it('writes authResult into the storage', async () => {
|
||||
const storagePersistenceServiceSpy = vi.spyOn(
|
||||
storagePersistenceService,
|
||||
'write'
|
||||
);
|
||||
@@ -75,86 +73,86 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
const callbackContext = {
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
of({ keys: [] } as JwtKeys)
|
||||
);
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe(() => {
|
||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
||||
['jwtKeys', { keys: [] }, allconfigs[0]],
|
||||
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||
['jwtKeys', { keys: [] }, allConfigs[0]],
|
||||
]);
|
||||
// write authnResult & jwtKeys
|
||||
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 = {
|
||||
refresh_token: 'dummy_refresh_token',
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
|
||||
const storagePersistenceServiceSpy = spyOn(
|
||||
const storagePersistenceServiceSpy = vi.spyOn(
|
||||
storagePersistenceService,
|
||||
'write'
|
||||
);
|
||||
const callbackContext = {
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
of({ keys: [] } as JwtKeys)
|
||||
);
|
||||
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe(() => {
|
||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
||||
['jwtKeys', { keys: [] }, allconfigs[0]],
|
||||
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||
['jwtKeys', { keys: [] }, allConfigs[0]],
|
||||
]);
|
||||
// write authnResult & refresh_token & jwtKeys
|
||||
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 = {
|
||||
refresh_token: 'dummy_refresh_token',
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
|
||||
const storagePersistenceServiceSpy = spyOn(
|
||||
const storagePersistenceServiceSpy = vi.spyOn(
|
||||
storagePersistenceService,
|
||||
'write'
|
||||
);
|
||||
const callbackContext = {
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
@@ -162,27 +160,27 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
of({ keys: [] } as JwtKeys)
|
||||
);
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe(() => {
|
||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
||||
['reusable_refresh_token', 'dummy_refresh_token', allconfigs[0]],
|
||||
['jwtKeys', { keys: [] }, allconfigs[0]],
|
||||
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||
['reusable_refresh_token', 'dummy_refresh_token', allConfigs[0]],
|
||||
['jwtKeys', { keys: [] }, allConfigs[0]],
|
||||
]);
|
||||
// write authnResult & refresh_token & jwtKeys
|
||||
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 = {
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
@@ -190,30 +188,30 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
isRenewProcess: false,
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
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)
|
||||
);
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe(() => {
|
||||
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 = {
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
@@ -222,21 +220,21 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
isRenewProcess: false,
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: false,
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
of({ keys: [{ kty: 'henlo' } as JwtKey] } as JwtKeys)
|
||||
);
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe((result) => {
|
||||
expect(result).toEqual({
|
||||
@@ -245,9 +243,9 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
jwtKeys: { keys: [{ kty: 'henlo' }] },
|
||||
} 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 = {
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
@@ -256,32 +254,32 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
isRenewProcess: false,
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: false,
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
of({} as JwtKeys)
|
||||
);
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: (err) => {
|
||||
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 = {
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
@@ -289,36 +287,36 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
isRenewProcess: false,
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: false,
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
throwError(() => new Error('error'))
|
||||
);
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: (err) => {
|
||||
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 = {
|
||||
authResult: { error: 'someError' },
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
@@ -328,36 +326,36 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: (err) => {
|
||||
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 = {
|
||||
authResult: { error: 'someError' },
|
||||
isRenewProcess: false,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
|
||||
const resetAuthorizationDataSpy = spyOn(
|
||||
const resetAuthorizationDataSpy = vi.spyOn(
|
||||
resetAuthDataService,
|
||||
'resetAuthorizationData'
|
||||
);
|
||||
const setNonceSpy = spyOn(flowsDataService, 'setNonce');
|
||||
const updateAndPublishAuthStateSpy = spyOn(
|
||||
const setNonceSpy = vi.spyOn(flowsDataService, 'setNonce');
|
||||
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'updateAndPublishAuthState'
|
||||
);
|
||||
@@ -365,40 +363,42 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||
expect(setNonceSpy).toHaveBeenCalledTimes(1);
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
||||
expect(
|
||||
updateAndPublishAuthStateSpy
|
||||
).toHaveBeenCalledExactlyOnceWith({
|
||||
isAuthenticated: false,
|
||||
validationResult: ValidationResult.SecureTokenServerError,
|
||||
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 = {
|
||||
authResult: { error: 'login_required' },
|
||||
isRenewProcess: false,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
|
||||
const resetAuthorizationDataSpy = spyOn(
|
||||
const resetAuthorizationDataSpy = vi.spyOn(
|
||||
resetAuthDataService,
|
||||
'resetAuthorizationData'
|
||||
);
|
||||
const setNonceSpy = spyOn(flowsDataService, 'setNonce');
|
||||
const updateAndPublishAuthStateSpy = spyOn(
|
||||
const setNonceSpy = vi.spyOn(flowsDataService, 'setNonce');
|
||||
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'updateAndPublishAuthState'
|
||||
);
|
||||
@@ -406,23 +406,25 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
callbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||
expect(setNonceSpy).toHaveBeenCalledTimes(1);
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
||||
expect(
|
||||
updateAndPublishAuthStateSpy
|
||||
).toHaveBeenCalledExactlyOnceWith({
|
||||
isAuthenticated: false,
|
||||
validationResult: ValidationResult.LoginRequired,
|
||||
isRenewProcess: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should store jwtKeys', waitForAsync(() => {
|
||||
it('should store jwtKeys', async () => {
|
||||
const DUMMY_AUTH_RESULT = {
|
||||
id_token: 'some-id-token',
|
||||
};
|
||||
@@ -430,33 +432,33 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
const initialCallbackContext = {
|
||||
authResult: DUMMY_AUTH_RESULT,
|
||||
} as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
const storagePersistenceServiceSpy = spyOn(
|
||||
const storagePersistenceServiceSpy = vi.spyOn(
|
||||
storagePersistenceService,
|
||||
'write'
|
||||
);
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
of(DUMMY_JWT_KEYS)
|
||||
);
|
||||
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
initialCallbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
next: (callbackContext: CallbackContext) => {
|
||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledTimes(2);
|
||||
expect(storagePersistenceServiceSpy.calls.allArgs()).toEqual([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allconfigs[0]],
|
||||
['jwtKeys', DUMMY_JWT_KEYS, allconfigs[0]],
|
||||
expect(storagePersistenceServiceSpy).toBeCalledWith([
|
||||
['authnResult', DUMMY_AUTH_RESULT, allConfigs[0]],
|
||||
['jwtKeys', DUMMY_JWT_KEYS, allConfigs[0]],
|
||||
]);
|
||||
|
||||
expect(callbackContext.jwtKeys).toEqual(DUMMY_JWT_KEYS);
|
||||
@@ -465,9 +467,9 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
expect(err).toBeFalsy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should not store jwtKeys on error', waitForAsync(() => {
|
||||
it('should not store jwtKeys on error', async () => {
|
||||
const authResult = {
|
||||
id_token: 'some-id-token',
|
||||
access_token: 'some-access-token',
|
||||
@@ -476,26 +478,26 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
authResult,
|
||||
} as CallbackContext;
|
||||
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
const storagePersistenceServiceSpy = spyOn(
|
||||
const storagePersistenceServiceSpy = vi.spyOn(
|
||||
storagePersistenceService,
|
||||
'write'
|
||||
);
|
||||
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
throwError(() => new Error('Error'))
|
||||
);
|
||||
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
initialCallbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
next: (callbackContext: CallbackContext) => {
|
||||
@@ -505,16 +507,18 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
|
||||
// storagePersistenceService.write() should not have been called with jwtKeys
|
||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledOnceWith(
|
||||
expect(
|
||||
storagePersistenceServiceSpy
|
||||
).toHaveBeenCalledExactlyOnceWith(
|
||||
'authnResult',
|
||||
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 = {
|
||||
id_token: 'some-id-token',
|
||||
access_token: 'some-access-token',
|
||||
@@ -523,66 +527,65 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
authResult,
|
||||
} as CallbackContext;
|
||||
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
const storagePersistenceServiceSpy = spyOn(
|
||||
const storagePersistenceServiceSpy = vi.spyOn(
|
||||
storagePersistenceService,
|
||||
'read'
|
||||
);
|
||||
|
||||
storagePersistenceServiceSpy.and.returnValue(DUMMY_JWT_KEYS);
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
storagePersistenceServiceSpy.mockReturnValue(DUMMY_JWT_KEYS);
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
throwError(() => new Error('Error'))
|
||||
);
|
||||
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
initialCallbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
next: (callbackContext: CallbackContext) => {
|
||||
expect(storagePersistenceServiceSpy).toHaveBeenCalledOnceWith(
|
||||
'jwtKeys',
|
||||
allconfigs[0]
|
||||
);
|
||||
expect(
|
||||
storagePersistenceServiceSpy
|
||||
).toHaveBeenCalledExactlyOnceWith('jwtKeys', allConfigs[0]);
|
||||
expect(callbackContext.jwtKeys).toEqual(DUMMY_JWT_KEYS);
|
||||
},
|
||||
error: (err) => {
|
||||
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 = {
|
||||
id_token: 'some-id-token',
|
||||
access_token: 'some-access-token',
|
||||
} as AuthResult;
|
||||
|
||||
const initialCallbackContext = { authResult } as CallbackContext;
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
historyCleanupOff: true,
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(storagePersistenceService, 'read').and.returnValue(null);
|
||||
spyOn(signInKeyDataService, 'getSigningKeys').and.returnValue(
|
||||
vi.spyOn(storagePersistenceService, 'read').mockReturnValue(null);
|
||||
vi.spyOn(signInKeyDataService, 'getSigningKeys').mockReturnValue(
|
||||
throwError(() => new Error('Error'))
|
||||
);
|
||||
|
||||
service
|
||||
.callbackHistoryAndResetJwtKeys(
|
||||
initialCallbackContext,
|
||||
allconfigs[0],
|
||||
allconfigs
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
next: (callbackContext: CallbackContext) => {
|
||||
@@ -592,7 +595,7 @@ describe('HistoryJwtKeysCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('historyCleanUpTurnedOn ', () => {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { DOCUMENT } from '../../dom';
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import { type Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, switchMap, tap } from 'rxjs/operators';
|
||||
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 { StoragePersistenceService } from '../../storage/storage-persistence.service';
|
||||
import { JwtKeys } from '../../validation/jwtkeys';
|
||||
import type { JwtKeys } from '../../validation/jwtkeys';
|
||||
import { ValidationResult } from '../../validation/validation-result';
|
||||
import { CallbackContext } from '../callback-context';
|
||||
import type { CallbackContext } from '../callback-context';
|
||||
import { FlowsDataService } from '../flows-data.service';
|
||||
import { ResetAuthDataService } from '../reset-auth-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 { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
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 { ResetAuthDataService } from '../reset-auth-data.service';
|
||||
import { ImplicitFlowCallbackHandlerService } from './implicit-flow-callback-handler.service';
|
||||
@@ -34,9 +35,6 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(ImplicitFlowCallbackHandlerService);
|
||||
flowsDataService = TestBed.inject(FlowsDataService);
|
||||
resetAuthDataService = TestBed.inject(ResetAuthDataService);
|
||||
@@ -47,46 +45,46 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
||||
});
|
||||
|
||||
describe('implicitFlowCallback', () => {
|
||||
it('calls "resetAuthorizationData" if silent renew is not running', waitForAsync(() => {
|
||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(false);
|
||||
const resetAuthorizationDataSpy = spyOn(
|
||||
it('calls "resetAuthorizationData" if silent renew is not running', async () => {
|
||||
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(false);
|
||||
const resetAuthorizationDataSpy = vi.spyOn(
|
||||
resetAuthDataService,
|
||||
'resetAuthorizationData'
|
||||
);
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
},
|
||||
];
|
||||
|
||||
service
|
||||
.implicitFlowCallback(allconfigs[0], allconfigs, 'any-hash')
|
||||
.implicitFlowCallback(allConfigs[0]!, allConfigs, 'any-hash')
|
||||
.subscribe(() => {
|
||||
expect(resetAuthorizationDataSpy).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('does NOT calls "resetAuthorizationData" if silent renew is running', waitForAsync(() => {
|
||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
||||
const resetAuthorizationDataSpy = spyOn(
|
||||
it('does NOT calls "resetAuthorizationData" if silent renew is running', async () => {
|
||||
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||
const resetAuthorizationDataSpy = vi.spyOn(
|
||||
resetAuthDataService,
|
||||
'resetAuthorizationData'
|
||||
);
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
},
|
||||
];
|
||||
|
||||
service
|
||||
.implicitFlowCallback(allconfigs[0], allconfigs, 'any-hash')
|
||||
.implicitFlowCallback(allConfigs[0]!, allConfigs, 'any-hash')
|
||||
.subscribe(() => {
|
||||
expect(resetAuthorizationDataSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('returns callbackContext if all params are good', waitForAsync(() => {
|
||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
||||
it('returns callbackContext if all params are good', async () => {
|
||||
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||
const expectedCallbackContext = {
|
||||
code: '',
|
||||
refreshToken: '',
|
||||
@@ -99,21 +97,21 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
||||
existingIdToken: null,
|
||||
} as CallbackContext;
|
||||
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
},
|
||||
];
|
||||
|
||||
service
|
||||
.implicitFlowCallback(allconfigs[0], allconfigs, 'anyHash')
|
||||
.implicitFlowCallback(allConfigs[0]!, allConfigs, 'anyHash')
|
||||
.subscribe((callbackContext) => {
|
||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('uses window location hash if no hash is passed', waitForAsync(() => {
|
||||
spyOn(flowsDataService, 'isSilentRenewRunning').and.returnValue(true);
|
||||
it('uses window location hash if no hash is passed', async () => {
|
||||
vi.spyOn(flowsDataService, 'isSilentRenewRunning').mockReturnValue(true);
|
||||
const expectedCallbackContext = {
|
||||
code: '',
|
||||
refreshToken: '',
|
||||
@@ -126,17 +124,17 @@ describe('ImplicitFlowCallbackHandlerService', () => {
|
||||
existingIdToken: null,
|
||||
} as CallbackContext;
|
||||
|
||||
const allconfigs = [
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
},
|
||||
];
|
||||
|
||||
service
|
||||
.implicitFlowCallback(allconfigs[0], allconfigs)
|
||||
.implicitFlowCallback(allConfigs[0]!, allConfigs)
|
||||
.subscribe((callbackContext) => {
|
||||
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 { inject, Injectable } from 'injection-js';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { OpenIdConfiguration } from '../../config/openid-configuration';
|
||||
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 { ResetAuthDataService } from '../reset-auth-data.service';
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
import { TestBed } from '@/testing';
|
||||
import { vi } from 'vitest';
|
||||
import { AuthStateService } from '../../auth-state/auth-state.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 { RefreshSessionCallbackHandlerService } from './refresh-session-callback-handler.service';
|
||||
|
||||
@@ -33,15 +34,15 @@ describe('RefreshSessionCallbackHandlerService', () => {
|
||||
});
|
||||
|
||||
describe('refreshSessionWithRefreshTokens', () => {
|
||||
it('returns callbackContext if all params are good', waitForAsync(() => {
|
||||
spyOn(
|
||||
it('returns callbackContext if all params are good', async () => {
|
||||
vi.spyOn(
|
||||
flowsDataService,
|
||||
'getExistingOrCreateAuthStateControl'
|
||||
).and.returnValue('state-data');
|
||||
spyOn(authStateService, 'getRefreshToken').and.returnValue(
|
||||
).mockReturnValue('state-data');
|
||||
vi.spyOn(authStateService, 'getRefreshToken').mockReturnValue(
|
||||
'henlo-furiend'
|
||||
);
|
||||
spyOn(authStateService, 'getIdToken').and.returnValue('henlo-legger');
|
||||
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('henlo-legger');
|
||||
|
||||
const expectedCallbackContext = {
|
||||
code: '',
|
||||
@@ -60,15 +61,15 @@ describe('RefreshSessionCallbackHandlerService', () => {
|
||||
.subscribe((callbackContext) => {
|
||||
expect(callbackContext).toEqual(expectedCallbackContext);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('throws error if no refresh token is given', waitForAsync(() => {
|
||||
spyOn(
|
||||
it('throws error if no refresh token is given', async () => {
|
||||
vi.spyOn(
|
||||
flowsDataService,
|
||||
'getExistingOrCreateAuthStateControl'
|
||||
).and.returnValue('state-data');
|
||||
spyOn(authStateService, 'getRefreshToken').and.returnValue('');
|
||||
spyOn(authStateService, 'getIdToken').and.returnValue('henlo-legger');
|
||||
).mockReturnValue('state-data');
|
||||
vi.spyOn(authStateService, 'getRefreshToken').mockReturnValue('');
|
||||
vi.spyOn(authStateService, 'getIdToken').mockReturnValue('henlo-legger');
|
||||
|
||||
service
|
||||
.refreshSessionWithRefreshTokens({ configId: 'configId1' })
|
||||
@@ -77,6 +78,6 @@ describe('RefreshSessionCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||
import { HttpErrorResponse, HttpHeaders } from '@ngify/http';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
import { createRetriableStream } from '../../../test/create-retriable-stream.helper';
|
||||
import { vi } from 'vitest';
|
||||
import { DataService } from '../../api/data.service';
|
||||
import { LoggerService } from '../../logging/logger.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 { CallbackContext } from '../callback-context';
|
||||
import type { CallbackContext } from '../callback-context';
|
||||
import { RefreshTokenCallbackHandlerService } from './refresh-token-callback-handler.service';
|
||||
|
||||
describe('RefreshTokenCallbackHandlerService', () => {
|
||||
@@ -46,7 +47,7 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
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)
|
||||
.refreshTokensRequestTokens({} as CallbackContext)
|
||||
.subscribe({
|
||||
@@ -54,41 +55,45 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls data service if all params are good', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
||||
it('calls data service if all params are good', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
service
|
||||
.refreshTokensRequestTokens({} as CallbackContext, {
|
||||
configId: 'configId1',
|
||||
})
|
||||
.subscribe(() => {
|
||||
expect(postSpy).toHaveBeenCalledOnceWith(
|
||||
expect(postSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
'tokenEndpoint',
|
||||
undefined,
|
||||
{ configId: 'configId1' },
|
||||
jasmine.any(HttpHeaders)
|
||||
expect.any(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(
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls data service with correct headers if all params are good', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(of({}));
|
||||
it('calls data service with correct headers if all params are good', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(of({}));
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
service
|
||||
.refreshTokensRequestTokens({} as CallbackContext, {
|
||||
@@ -97,20 +102,24 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
.subscribe(() => {
|
||||
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(
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('returns error in case of http error', waitForAsync(() => {
|
||||
spyOn(dataService, 'post').and.returnValue(throwError(() => HTTP_ERROR));
|
||||
it('returns error in case of http error', async () => {
|
||||
vi.spyOn(dataService, 'post').mockReturnValue(
|
||||
throwError(() => HTTP_ERROR)
|
||||
);
|
||||
const config = { configId: 'configId1', authority: 'authority' };
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
service
|
||||
.refreshTokensRequestTokens({} as CallbackContext, config)
|
||||
@@ -119,10 +128,10 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('retries request in case of no connection http error and succeeds', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
||||
it('retries request in case of no connection http error and succeeds', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => CONNECTION_ERROR),
|
||||
of({})
|
||||
@@ -130,9 +139,11 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
);
|
||||
const config = { configId: 'configId1', authority: 'authority' };
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
service
|
||||
.refreshTokensRequestTokens({} as CallbackContext, config)
|
||||
@@ -146,10 +157,10 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
expect(err).toBeFalsy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('retries request in case of no connection http error and fails because of http error afterwards', waitForAsync(() => {
|
||||
const postSpy = spyOn(dataService, 'post').and.returnValue(
|
||||
it('retries request in case of no connection http error and fails because of http error afterwards', async () => {
|
||||
const postSpy = vi.spyOn(dataService, 'post').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => CONNECTION_ERROR),
|
||||
throwError(() => HTTP_ERROR)
|
||||
@@ -157,9 +168,11 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
);
|
||||
const config = { configId: 'configId1', authority: 'authority' };
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', config)
|
||||
.and.returnValue({ tokenEndpoint: 'tokenEndpoint' });
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', config],
|
||||
() => ({ tokenEndpoint: 'tokenEndpoint' })
|
||||
);
|
||||
|
||||
service
|
||||
.refreshTokensRequestTokens({} as CallbackContext, config)
|
||||
@@ -173,6 +186,6 @@ describe('RefreshTokenCallbackHandlerService', () => {
|
||||
expect(postSpy).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { DOCUMENT } from '../../dom';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { TestBed } from '@/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
import { vi } from 'vitest';
|
||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||
import { DOCUMENT } from '../../dom';
|
||||
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 { ValidationResult } from '../../validation/validation-result';
|
||||
import { CallbackContext } from '../callback-context';
|
||||
import type { CallbackContext } from '../callback-context';
|
||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||
import { StateValidationCallbackHandlerService } from './state-validation-callback-handler.service';
|
||||
|
||||
@@ -56,8 +57,11 @@ describe('StateValidationCallbackHandlerService', () => {
|
||||
});
|
||||
|
||||
describe('callbackStateValidation', () => {
|
||||
it('returns callbackContext with validationResult if validationResult is valid', waitForAsync(() => {
|
||||
spyOn(stateValidationService, 'getValidatedStateResult').and.returnValue(
|
||||
it('returns callbackContext with validationResult if validationResult is valid', async () => {
|
||||
vi.spyOn(
|
||||
stateValidationService,
|
||||
'getValidatedStateResult'
|
||||
).mockReturnValue(
|
||||
of({
|
||||
idToken: 'idTokenJustForTesting',
|
||||
authResponseIsValid: true,
|
||||
@@ -68,7 +72,7 @@ describe('StateValidationCallbackHandlerService', () => {
|
||||
service
|
||||
.callbackStateValidation(
|
||||
{} as CallbackContext,
|
||||
allConfigs[0],
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe((newCallbackContext) => {
|
||||
@@ -79,47 +83,53 @@ describe('StateValidationCallbackHandlerService', () => {
|
||||
},
|
||||
} as CallbackContext);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('logs error in case of an error', waitForAsync(() => {
|
||||
spyOn(stateValidationService, 'getValidatedStateResult').and.returnValue(
|
||||
it('logs error in case of an error', async () => {
|
||||
vi.spyOn(
|
||||
stateValidationService,
|
||||
'getValidatedStateResult'
|
||||
).mockReturnValue(
|
||||
of({
|
||||
authResponseIsValid: false,
|
||||
} as StateValidationResult)
|
||||
);
|
||||
|
||||
const loggerSpy = spyOn(loggerService, 'logWarning');
|
||||
const loggerSpy = vi.spyOn(loggerService, 'logWarning');
|
||||
const allConfigs = [{ configId: 'configId1' }];
|
||||
|
||||
service
|
||||
.callbackStateValidation(
|
||||
{} as CallbackContext,
|
||||
allConfigs[0],
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(loggerSpy).toHaveBeenCalledOnceWith(
|
||||
allConfigs[0],
|
||||
expect(loggerSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
allConfigs[0]!,
|
||||
'authorizedCallback, token(s) validation failed, resetting. Hash: &anyFakeHash'
|
||||
);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls resetAuthDataService.resetAuthorizationData and authStateService.updateAndPublishAuthState in case of an error', waitForAsync(() => {
|
||||
spyOn(stateValidationService, 'getValidatedStateResult').and.returnValue(
|
||||
it('calls resetAuthDataService.resetAuthorizationData and authStateService.updateAndPublishAuthState in case of an error', async () => {
|
||||
vi.spyOn(
|
||||
stateValidationService,
|
||||
'getValidatedStateResult'
|
||||
).mockReturnValue(
|
||||
of({
|
||||
authResponseIsValid: false,
|
||||
state: ValidationResult.LoginRequired,
|
||||
} as StateValidationResult)
|
||||
);
|
||||
|
||||
const resetAuthorizationDataSpy = spyOn(
|
||||
const resetAuthorizationDataSpy = vi.spyOn(
|
||||
resetAuthDataService,
|
||||
'resetAuthorizationData'
|
||||
);
|
||||
const updateAndPublishAuthStateSpy = spyOn(
|
||||
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'updateAndPublishAuthState'
|
||||
);
|
||||
@@ -128,19 +138,21 @@ describe('StateValidationCallbackHandlerService', () => {
|
||||
service
|
||||
.callbackStateValidation(
|
||||
{ isRenewProcess: true } as CallbackContext,
|
||||
allConfigs[0],
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
||||
expect(
|
||||
updateAndPublishAuthStateSpy
|
||||
).toHaveBeenCalledExactlyOnceWith({
|
||||
isAuthenticated: false,
|
||||
validationResult: ValidationResult.LoginRequired,
|
||||
isRenewProcess: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { DOCUMENT } from '../../dom';
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import type { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
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 { StateValidationResult } from '../../validation/state-validation-result';
|
||||
import type { StateValidationResult } from '../../validation/state-validation-result';
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { TestBed } from '@/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
import { vi } from 'vitest';
|
||||
import { AuthStateService } from '../../auth-state/auth-state.service';
|
||||
import { LoggerService } from '../../logging/logger.service';
|
||||
import { mockProvider } from '../../testing/mock';
|
||||
import { UserService } from '../../user-data/user.service';
|
||||
import { StateValidationResult } from '../../validation/state-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 { ResetAuthDataService } from '../reset-auth-data.service';
|
||||
import { UserCallbackHandlerService } from './user-callback-handler.service';
|
||||
@@ -44,7 +45,7 @@ describe('UserCallbackHandlerService', () => {
|
||||
});
|
||||
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -70,17 +71,17 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
||||
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(spy).toHaveBeenCalledOnceWith('mystate', allConfigs[0]);
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith('mystate', allConfigs[0]);
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -104,17 +105,17 @@ describe('UserCallbackHandlerService', () => {
|
||||
autoUserInfo: false,
|
||||
},
|
||||
];
|
||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
||||
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -138,17 +139,17 @@ describe('UserCallbackHandlerService', () => {
|
||||
autoUserInfo: false,
|
||||
},
|
||||
];
|
||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
||||
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
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 callbackContext = {
|
||||
code: '',
|
||||
@@ -168,17 +169,17 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const spy = spyOn(flowsDataService, 'setSessionState');
|
||||
const spy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -204,24 +205,24 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const updateAndPublishAuthStateSpy = spyOn(
|
||||
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'updateAndPublishAuthState'
|
||||
);
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledExactlyOnceWith({
|
||||
isAuthenticated: true,
|
||||
validationResult: ValidationResult.NotSet,
|
||||
isRenewProcess: false,
|
||||
});
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -247,16 +248,17 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const getAndPersistUserDataInStoreSpy = spyOn(
|
||||
userService,
|
||||
'getAndPersistUserDataInStore'
|
||||
).and.returnValue(of({ user: 'some_data' }));
|
||||
const getAndPersistUserDataInStoreSpy = vi
|
||||
.spyOn(userService, 'getAndPersistUserDataInStore')
|
||||
.mockReturnValue(of({ user: 'some_data' }));
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(getAndPersistUserDataInStoreSpy).toHaveBeenCalledOnceWith(
|
||||
allConfigs[0],
|
||||
expect(
|
||||
getAndPersistUserDataInStoreSpy
|
||||
).toHaveBeenCalledExactlyOnceWith(
|
||||
allConfigs[0]!,
|
||||
allConfigs,
|
||||
false,
|
||||
'idtoken',
|
||||
@@ -264,9 +266,9 @@ describe('UserCallbackHandlerService', () => {
|
||||
);
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -293,27 +295,27 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
||||
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||
of({ user: 'some_data' })
|
||||
);
|
||||
const updateAndPublishAuthStateSpy = spyOn(
|
||||
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'updateAndPublishAuthState'
|
||||
);
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledExactlyOnceWith({
|
||||
isAuthenticated: true,
|
||||
validationResult: ValidationResult.MaxOffsetExpired,
|
||||
isRenewProcess: false,
|
||||
});
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -340,23 +342,23 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
||||
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||
of({ user: 'some_data' })
|
||||
);
|
||||
const setSessionStateSpy = spyOn(flowsDataService, 'setSessionState');
|
||||
const setSessionStateSpy = vi.spyOn(flowsDataService, 'setSessionState');
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe((resultCallbackContext) => {
|
||||
expect(setSessionStateSpy).toHaveBeenCalledOnceWith(
|
||||
expect(setSessionStateSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
'mystate',
|
||||
allConfigs[0]
|
||||
);
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -383,19 +385,21 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
||||
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||
of(null)
|
||||
);
|
||||
const updateAndPublishAuthStateSpy = spyOn(
|
||||
const updateAndPublishAuthStateSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'updateAndPublishAuthState'
|
||||
);
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe({
|
||||
error: (err) => {
|
||||
expect(updateAndPublishAuthStateSpy).toHaveBeenCalledOnceWith({
|
||||
expect(
|
||||
updateAndPublishAuthStateSpy
|
||||
).toHaveBeenCalledExactlyOnceWith({
|
||||
isAuthenticated: false,
|
||||
validationResult: ValidationResult.MaxOffsetExpired,
|
||||
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(
|
||||
'accesstoken',
|
||||
'idtoken',
|
||||
@@ -434,16 +438,16 @@ describe('UserCallbackHandlerService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
spyOn(userService, 'getAndPersistUserDataInStore').and.returnValue(
|
||||
vi.spyOn(userService, 'getAndPersistUserDataInStore').mockReturnValue(
|
||||
of(null)
|
||||
);
|
||||
const resetAuthorizationDataSpy = spyOn(
|
||||
const resetAuthorizationDataSpy = vi.spyOn(
|
||||
resetAuthDataService,
|
||||
'resetAuthorizationData'
|
||||
);
|
||||
|
||||
service
|
||||
.callbackUser(callbackContext, allConfigs[0], allConfigs)
|
||||
.callbackUser(callbackContext, allConfigs[0]!, allConfigs)
|
||||
.subscribe({
|
||||
error: (err) => {
|
||||
expect(resetAuthorizationDataSpy).toHaveBeenCalledTimes(1);
|
||||
@@ -452,6 +456,6 @@ describe('UserCallbackHandlerService', () => {
|
||||
);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Observable, of, throwError } from 'rxjs';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import { type Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, switchMap } from 'rxjs/operators';
|
||||
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 { UserService } from '../../user-data/user.service';
|
||||
import { StateValidationResult } from '../../validation/state-validation-result';
|
||||
import { CallbackContext } from '../callback-context';
|
||||
import type { StateValidationResult } from '../../validation/state-validation-result';
|
||||
import type { CallbackContext } from '../callback-context';
|
||||
import { FlowsDataService } from '../flows-data.service';
|
||||
import { ResetAuthDataService } from '../reset-auth-data.service';
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../test/auto-mock';
|
||||
import { TestBed } from '@/testing';
|
||||
import { vi } from 'vitest';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { StoragePersistenceService } from '../storage/storage-persistence.service';
|
||||
import { mockProvider } from '../testing/mock';
|
||||
import { CryptoService } from '../utils/crypto/crypto.service';
|
||||
import { FlowsDataService } from './flows-data.service';
|
||||
import { RandomService } from './random/random.service';
|
||||
@@ -37,12 +38,12 @@ describe('Flows Data Service', () => {
|
||||
|
||||
describe('createNonce', () => {
|
||||
it('createNonce returns nonce and stores it', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
const result = service.createNonce({ configId: 'configId1' });
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
expect(spy).toHaveBeenCalledOnceWith('authNonce', result, {
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith('authNonce', result, {
|
||||
configId: 'configId1',
|
||||
});
|
||||
});
|
||||
@@ -50,32 +51,38 @@ describe('Flows Data Service', () => {
|
||||
|
||||
describe('AuthStateControl', () => {
|
||||
it('getAuthStateControl returns property from store', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'read');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'read');
|
||||
|
||||
service.getAuthStateControl({ configId: 'configId1' });
|
||||
|
||||
expect(spy).toHaveBeenCalledOnceWith('authStateControl', {
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith('authStateControl', {
|
||||
configId: 'configId1',
|
||||
});
|
||||
});
|
||||
|
||||
it('setAuthStateControl saves property in store', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
service.setAuthStateControl('ToSave', { configId: 'configId1' });
|
||||
|
||||
expect(spy).toHaveBeenCalledOnceWith('authStateControl', 'ToSave', {
|
||||
configId: 'configId1',
|
||||
});
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||
'authStateControl',
|
||||
'ToSave',
|
||||
{
|
||||
configId: 'configId1',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getExistingOrCreateAuthStateControl', () => {
|
||||
it('if nothing stored it creates a 40 char one and saves the authStateControl', () => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authStateControl', { configId: 'configId1' })
|
||||
.and.returnValue(null);
|
||||
const setSpy = spyOn(storagePersistenceService, 'write');
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authStateControl', { configId: 'configId1' }],
|
||||
() => null
|
||||
);
|
||||
const setSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
const result = service.getExistingOrCreateAuthStateControl({
|
||||
configId: 'configId1',
|
||||
@@ -83,16 +90,22 @@ describe('Flows Data Service', () => {
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
expect(result.length).toBe(41);
|
||||
expect(setSpy).toHaveBeenCalledOnceWith('authStateControl', result, {
|
||||
configId: 'configId1',
|
||||
});
|
||||
expect(setSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
'authStateControl',
|
||||
result,
|
||||
{
|
||||
configId: 'configId1',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('if stored it returns the value and does NOT Store the value again', () => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authStateControl', { configId: 'configId1' })
|
||||
.and.returnValue('someAuthStateControl');
|
||||
const setSpy = spyOn(storagePersistenceService, 'write');
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authStateControl', { configId: 'configId1' }],
|
||||
() => 'someAuthStateControl'
|
||||
);
|
||||
const setSpy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
const result = service.getExistingOrCreateAuthStateControl({
|
||||
configId: 'configId1',
|
||||
@@ -106,11 +119,11 @@ describe('Flows Data Service', () => {
|
||||
|
||||
describe('setSessionState', () => {
|
||||
it('setSessionState saves the value in the storage', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
service.setSessionState('Genesis', { configId: 'configId1' });
|
||||
|
||||
expect(spy).toHaveBeenCalledOnceWith('session_state', 'Genesis', {
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith('session_state', 'Genesis', {
|
||||
configId: 'configId1',
|
||||
});
|
||||
});
|
||||
@@ -118,7 +131,7 @@ describe('Flows Data Service', () => {
|
||||
|
||||
describe('resetStorageFlowData', () => {
|
||||
it('resetStorageFlowData calls correct method on storagePersistenceService', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'resetStorageFlowData');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'resetStorageFlowData');
|
||||
|
||||
service.resetStorageFlowData({ configId: 'configId1' });
|
||||
|
||||
@@ -128,26 +141,27 @@ describe('Flows Data Service', () => {
|
||||
|
||||
describe('codeVerifier', () => {
|
||||
it('getCodeVerifier returns value from the store', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'read')
|
||||
const spy = vi
|
||||
.spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('codeVerifier', { configId: 'configId1' })
|
||||
.and.returnValue('Genesis');
|
||||
.mockReturnValue('Genesis');
|
||||
|
||||
const result = service.getCodeVerifier({ configId: 'configId1' });
|
||||
|
||||
expect(result).toBe('Genesis');
|
||||
expect(spy).toHaveBeenCalledOnceWith('codeVerifier', {
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith('codeVerifier', {
|
||||
configId: 'configId1',
|
||||
});
|
||||
});
|
||||
|
||||
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' });
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
expect(result.length).toBe(67);
|
||||
expect(setSpy).toHaveBeenCalledOnceWith('codeVerifier', result, {
|
||||
expect(setSpy).toHaveBeenCalledExactlyOnceWith('codeVerifier', result, {
|
||||
configId: 'configId1',
|
||||
});
|
||||
});
|
||||
@@ -165,22 +179,26 @@ describe('Flows Data Service', () => {
|
||||
|
||||
jasmine.clock().mockDate(baseTime);
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('storageCodeFlowInProgress', config)
|
||||
.and.returnValue(true);
|
||||
const spyWrite = spyOn(storagePersistenceService, 'write');
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['storageCodeFlowInProgress', config],
|
||||
() => true
|
||||
);
|
||||
const spyWrite = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
const isCodeFlowInProgressResult = service.isCodeFlowInProgress(config);
|
||||
|
||||
expect(spyWrite).not.toHaveBeenCalled();
|
||||
expect(isCodeFlowInProgressResult).toBeTrue();
|
||||
expect(isCodeFlowInProgressResult).toBeTruthy();
|
||||
});
|
||||
|
||||
it('state object does not exist returns false result', () => {
|
||||
// arrange
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('storageCodeFlowInProgress', { configId: 'configId1' })
|
||||
.and.returnValue(null);
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['storageCodeFlowInProgress', { configId: 'configId1' }],
|
||||
() => null
|
||||
);
|
||||
|
||||
// act
|
||||
const isCodeFlowInProgressResult = service.isCodeFlowInProgress({
|
||||
@@ -188,7 +206,7 @@ describe('Flows Data Service', () => {
|
||||
});
|
||||
|
||||
// assert
|
||||
expect(isCodeFlowInProgressResult).toBeFalse();
|
||||
expect(isCodeFlowInProgressResult).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -200,23 +218,31 @@ describe('Flows Data Service', () => {
|
||||
|
||||
jasmine.clock().mockDate(baseTime);
|
||||
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
service.setCodeFlowInProgress({ configId: 'configId1' });
|
||||
expect(spy).toHaveBeenCalledOnceWith('storageCodeFlowInProgress', true, {
|
||||
configId: 'configId1',
|
||||
});
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||
'storageCodeFlowInProgress',
|
||||
true,
|
||||
{
|
||||
configId: 'configId1',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resetCodeFlowInProgress', () => {
|
||||
it('set resetCodeFlowInProgress to false when called', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
service.resetCodeFlowInProgress({ configId: 'configId1' });
|
||||
expect(spy).toHaveBeenCalledOnceWith('storageCodeFlowInProgress', false, {
|
||||
configId: 'configId1',
|
||||
});
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||
'storageCodeFlowInProgress',
|
||||
false,
|
||||
{
|
||||
configId: 'configId1',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -238,21 +264,21 @@ describe('Flows Data Service', () => {
|
||||
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
vi.spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('storageSilentRenewRunning', config)
|
||||
.and.returnValue(JSON.stringify(storageObject));
|
||||
const spyWrite = spyOn(storagePersistenceService, 'write');
|
||||
.mockReturnValue(JSON.stringify(storageObject));
|
||||
const spyWrite = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
jasmine.clock().tick((config.silentRenewTimeoutInSeconds + 1) * 1000);
|
||||
|
||||
const isSilentRenewRunningResult = service.isSilentRenewRunning(config);
|
||||
|
||||
expect(spyWrite).toHaveBeenCalledOnceWith(
|
||||
expect(spyWrite).toHaveBeenCalledExactlyOnceWith(
|
||||
'storageSilentRenewRunning',
|
||||
'',
|
||||
config
|
||||
);
|
||||
expect(isSilentRenewRunningResult).toBeFalse();
|
||||
expect(isSilentRenewRunningResult).toBeFalsy();
|
||||
});
|
||||
|
||||
it('checks silent renew process and returns result', () => {
|
||||
@@ -272,27 +298,29 @@ describe('Flows Data Service', () => {
|
||||
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
||||
};
|
||||
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
vi.spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('storageSilentRenewRunning', config)
|
||||
.and.returnValue(JSON.stringify(storageObject));
|
||||
const spyWrite = spyOn(storagePersistenceService, 'write');
|
||||
.mockReturnValue(JSON.stringify(storageObject));
|
||||
const spyWrite = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
const isSilentRenewRunningResult = service.isSilentRenewRunning(config);
|
||||
|
||||
expect(spyWrite).not.toHaveBeenCalled();
|
||||
expect(isSilentRenewRunningResult).toBeTrue();
|
||||
expect(isSilentRenewRunningResult).toBeTruthy();
|
||||
});
|
||||
|
||||
it('state object does not exist returns false result', () => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('storageSilentRenewRunning', { configId: 'configId1' })
|
||||
.and.returnValue(null);
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['storageSilentRenewRunning', { configId: 'configId1' }],
|
||||
() => null
|
||||
);
|
||||
|
||||
const isSilentRenewRunningResult = service.isSilentRenewRunning({
|
||||
configId: 'configId1',
|
||||
});
|
||||
|
||||
expect(isSilentRenewRunningResult).toBeFalse();
|
||||
expect(isSilentRenewRunningResult).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -309,10 +337,10 @@ describe('Flows Data Service', () => {
|
||||
dateOfLaunchedProcessUtc: baseTime.toISOString(),
|
||||
};
|
||||
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
service.setSilentRenewRunning({ configId: 'configId1' });
|
||||
expect(spy).toHaveBeenCalledOnceWith(
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||
'storageSilentRenewRunning',
|
||||
JSON.stringify(storageObject),
|
||||
{ configId: 'configId1' }
|
||||
@@ -322,12 +350,16 @@ describe('Flows Data Service', () => {
|
||||
|
||||
describe('resetSilentRenewRunning', () => {
|
||||
it('set resetSilentRenewRunning to empty string when called', () => {
|
||||
const spy = spyOn(storagePersistenceService, 'write');
|
||||
const spy = vi.spyOn(storagePersistenceService, 'write');
|
||||
|
||||
service.resetSilentRenewRunning({ configId: 'configId1' });
|
||||
expect(spy).toHaveBeenCalledOnceWith('storageSilentRenewRunning', '', {
|
||||
configId: 'configId1',
|
||||
});
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith(
|
||||
'storageSilentRenewRunning',
|
||||
'',
|
||||
{
|
||||
configId: 'configId1',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import { LoggerService } from '../logging/logger.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';
|
||||
|
||||
@Injectable()
|
||||
@@ -18,7 +18,7 @@ export class FlowsDataService {
|
||||
createNonce(configuration: OpenIdConfiguration): string {
|
||||
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);
|
||||
|
||||
return nonce;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { TestBed } from '@/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { mockProvider } from '../../test/auto-mock';
|
||||
import { CallbackContext } from './callback-context';
|
||||
import { vi } from 'vitest';
|
||||
import { mockProvider } from '../testing/mock';
|
||||
import type { CallbackContext } from './callback-context';
|
||||
import { CodeFlowCallbackHandlerService } from './callback-handling/code-flow-callback-handler.service';
|
||||
import { HistoryJwtKeysCallbackHandlerService } from './callback-handling/history-jwt-keys-callback-handler.service';
|
||||
import { ImplicitFlowCallbackHandlerService } from './callback-handling/implicit-flow-callback-handler.service';
|
||||
@@ -64,27 +65,25 @@ describe('Flows Service', () => {
|
||||
});
|
||||
|
||||
describe('processCodeFlowCallback', () => {
|
||||
it('calls all methods correctly', waitForAsync(() => {
|
||||
const codeFlowCallbackSpy = spyOn(
|
||||
codeFlowCallbackHandlerService,
|
||||
'codeFlowCallback'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const codeFlowCodeRequestSpy = spyOn(
|
||||
codeFlowCallbackHandlerService,
|
||||
'codeFlowCodeRequest'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = spyOn(
|
||||
stateValidationCallbackHandlerService,
|
||||
'callbackStateValidation'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = spyOn(
|
||||
userCallbackHandlerService,
|
||||
'callbackUser'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
it('calls all methods correctly', async () => {
|
||||
const codeFlowCallbackSpy = vi
|
||||
.spyOn(codeFlowCallbackHandlerService, 'codeFlowCallback')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const codeFlowCodeRequestSpy = vi
|
||||
.spyOn(codeFlowCallbackHandlerService, 'codeFlowCodeRequest')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||
.spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
)
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = vi
|
||||
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = vi
|
||||
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
@@ -92,10 +91,10 @@ describe('Flows Service', () => {
|
||||
];
|
||||
|
||||
service
|
||||
.processCodeFlowCallback('some-url1234', allConfigs[0], allConfigs)
|
||||
.processCodeFlowCallback('some-url1234', allConfigs[0]!, allConfigs)
|
||||
.subscribe((value) => {
|
||||
expect(value).toEqual({} as CallbackContext);
|
||||
expect(codeFlowCallbackSpy).toHaveBeenCalledOnceWith(
|
||||
expect(codeFlowCallbackSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
'some-url1234',
|
||||
allConfigs[0]
|
||||
);
|
||||
@@ -104,27 +103,26 @@ describe('Flows Service', () => {
|
||||
expect(callbackStateValidationSpy).toHaveBeenCalledTimes(1);
|
||||
expect(callbackUserSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('processSilentRenewCodeFlowCallback', () => {
|
||||
it('calls all methods correctly', waitForAsync(() => {
|
||||
const codeFlowCodeRequestSpy = spyOn(
|
||||
codeFlowCallbackHandlerService,
|
||||
'codeFlowCodeRequest'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = spyOn(
|
||||
stateValidationCallbackHandlerService,
|
||||
'callbackStateValidation'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = spyOn(
|
||||
userCallbackHandlerService,
|
||||
'callbackUser'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
it('calls all methods correctly', async () => {
|
||||
const codeFlowCodeRequestSpy = vi
|
||||
.spyOn(codeFlowCallbackHandlerService, 'codeFlowCodeRequest')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||
.spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
)
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = vi
|
||||
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = vi
|
||||
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
@@ -134,7 +132,7 @@ describe('Flows Service', () => {
|
||||
service
|
||||
.processSilentRenewCodeFlowCallback(
|
||||
{} as CallbackContext,
|
||||
allConfigs[0],
|
||||
allConfigs[0]!,
|
||||
allConfigs
|
||||
)
|
||||
.subscribe((value) => {
|
||||
@@ -144,27 +142,26 @@ describe('Flows Service', () => {
|
||||
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
||||
expect(callbackUserSpy).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('processImplicitFlowCallback', () => {
|
||||
it('calls all methods correctly', waitForAsync(() => {
|
||||
const implicitFlowCallbackSpy = spyOn(
|
||||
implicitFlowCallbackHandlerService,
|
||||
'implicitFlowCallback'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = spyOn(
|
||||
stateValidationCallbackHandlerService,
|
||||
'callbackStateValidation'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = spyOn(
|
||||
userCallbackHandlerService,
|
||||
'callbackUser'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
it('calls all methods correctly', async () => {
|
||||
const implicitFlowCallbackSpy = vi
|
||||
.spyOn(implicitFlowCallbackHandlerService, 'implicitFlowCallback')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||
.spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
)
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = vi
|
||||
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = vi
|
||||
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
@@ -172,7 +169,7 @@ describe('Flows Service', () => {
|
||||
];
|
||||
|
||||
service
|
||||
.processImplicitFlowCallback(allConfigs[0], allConfigs, 'any-hash')
|
||||
.processImplicitFlowCallback(allConfigs[0]!, allConfigs, 'any-hash')
|
||||
.subscribe((value) => {
|
||||
expect(value).toEqual({} as CallbackContext);
|
||||
expect(implicitFlowCallbackSpy).toHaveBeenCalled();
|
||||
@@ -180,31 +177,32 @@ describe('Flows Service', () => {
|
||||
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
||||
expect(callbackUserSpy).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('processRefreshToken', () => {
|
||||
it('calls all methods correctly', waitForAsync(() => {
|
||||
const refreshSessionWithRefreshTokensSpy = spyOn(
|
||||
refreshSessionCallbackHandlerService,
|
||||
'refreshSessionWithRefreshTokens'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const refreshTokensRequestTokensSpy = spyOn(
|
||||
refreshTokenCallbackHandlerService,
|
||||
'refreshTokensRequestTokens'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = spyOn(
|
||||
stateValidationCallbackHandlerService,
|
||||
'callbackStateValidation'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = spyOn(
|
||||
userCallbackHandlerService,
|
||||
'callbackUser'
|
||||
).and.returnValue(of({} as CallbackContext));
|
||||
it('calls all methods correctly', async () => {
|
||||
const refreshSessionWithRefreshTokensSpy = vi
|
||||
.spyOn(
|
||||
refreshSessionCallbackHandlerService,
|
||||
'refreshSessionWithRefreshTokens'
|
||||
)
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const refreshTokensRequestTokensSpy = vi
|
||||
.spyOn(refreshTokenCallbackHandlerService, 'refreshTokensRequestTokens')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackHistoryAndResetJwtKeysSpy = vi
|
||||
.spyOn(
|
||||
historyJwtKeysCallbackHandlerService,
|
||||
'callbackHistoryAndResetJwtKeys'
|
||||
)
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackStateValidationSpy = vi
|
||||
.spyOn(stateValidationCallbackHandlerService, 'callbackStateValidation')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const callbackUserSpy = vi
|
||||
.spyOn(userCallbackHandlerService, 'callbackUser')
|
||||
.mockReturnValue(of({} as CallbackContext));
|
||||
const allConfigs = [
|
||||
{
|
||||
configId: 'configId1',
|
||||
@@ -212,7 +210,7 @@ describe('Flows Service', () => {
|
||||
];
|
||||
|
||||
service
|
||||
.processRefreshToken(allConfigs[0], allConfigs)
|
||||
.processRefreshToken(allConfigs[0]!, allConfigs)
|
||||
.subscribe((value) => {
|
||||
expect(value).toEqual({} as CallbackContext);
|
||||
expect(refreshSessionWithRefreshTokensSpy).toHaveBeenCalled();
|
||||
@@ -221,6 +219,6 @@ describe('Flows Service', () => {
|
||||
expect(callbackStateValidationSpy).toHaveBeenCalled();
|
||||
expect(callbackUserSpy).toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { inject, Injectable } from 'injection-js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Injectable, inject } from 'injection-js';
|
||||
import type { Observable } from 'rxjs';
|
||||
import { concatMap } from 'rxjs/operators';
|
||||
import { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import { CallbackContext } from './callback-context';
|
||||
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import type { CallbackContext } from './callback-context';
|
||||
import { CodeFlowCallbackHandlerService } from './callback-handling/code-flow-callback-handler.service';
|
||||
import { HistoryJwtKeysCallbackHandlerService } from './callback-handling/history-jwt-keys-callback-handler.service';
|
||||
import { ImplicitFlowCallbackHandlerService } from './callback-handling/implicit-flow-callback-handler.service';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../../test/auto-mock';
|
||||
import { TestBed } from '@/testing';
|
||||
import { vi } from 'vitest';
|
||||
import { LoggerService } from '../../logging/logger.service';
|
||||
import { mockProvider } from '../../testing/mock';
|
||||
import { CryptoService } from '../../utils/crypto/crypto.service';
|
||||
import { RandomService } from './random.service';
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { mockProvider } from '../../test/auto-mock';
|
||||
import { TestBed } from '@/testing';
|
||||
import { vi } from 'vitest';
|
||||
import { AuthStateService } from '../auth-state/auth-state.service';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { mockProvider } from '../testing/mock';
|
||||
import { UserService } from '../user-data/user.service';
|
||||
import { FlowsDataService } from './flows-data.service';
|
||||
import { ResetAuthDataService } from './reset-auth-data.service';
|
||||
@@ -37,7 +38,7 @@ describe('ResetAuthDataService', () => {
|
||||
|
||||
describe('resetAuthorizationData', () => {
|
||||
it('calls resetUserDataInStore when autoUserInfo is true', () => {
|
||||
const resetUserDataInStoreSpy = spyOn(
|
||||
const resetUserDataInStoreSpy = vi.spyOn(
|
||||
userService,
|
||||
'resetUserDataInStore'
|
||||
);
|
||||
@@ -47,16 +48,16 @@ describe('ResetAuthDataService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
service.resetAuthorizationData(allConfigs[0], allConfigs);
|
||||
service.resetAuthorizationData(allConfigs[0]!, allConfigs);
|
||||
expect(resetUserDataInStoreSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls correct methods', () => {
|
||||
const resetStorageFlowDataSpy = spyOn(
|
||||
const resetStorageFlowDataSpy = vi.spyOn(
|
||||
flowsDataService,
|
||||
'resetStorageFlowData'
|
||||
);
|
||||
const setUnauthorizedAndFireEventSpy = spyOn(
|
||||
const setUnauthorizedAndFireEventSpy = vi.spyOn(
|
||||
authStateService,
|
||||
'setUnauthenticatedAndFireEvent'
|
||||
);
|
||||
@@ -66,7 +67,7 @@ describe('ResetAuthDataService', () => {
|
||||
},
|
||||
];
|
||||
|
||||
service.resetAuthorizationData(allConfigs[0], allConfigs);
|
||||
service.resetAuthorizationData(allConfigs[0]!, allConfigs);
|
||||
|
||||
expect(resetStorageFlowDataSpy).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 { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import type { OpenIdConfiguration } from '../config/openid-configuration';
|
||||
import { LoggerService } from '../logging/logger.service';
|
||||
import { UserService } from '../user-data/user.service';
|
||||
import { FlowsDataService } from './flows-data.service';
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { HttpResponse } from '@angular/common/http';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { TestBed, mockImplementationWhenArgsEqual } from '@/testing';
|
||||
import { HttpResponse } from '@ngify/http';
|
||||
import { isObservable, of, throwError } from 'rxjs';
|
||||
import { mockProvider } from '../../test/auto-mock';
|
||||
import { createRetriableStream } from '../../test/create-retriable-stream.helper';
|
||||
import { vi } from 'vitest';
|
||||
import { DataService } from '../api/data.service';
|
||||
import { LoggerService } from '../logging/logger.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';
|
||||
|
||||
const DUMMY_JWKS = {
|
||||
@@ -53,10 +54,12 @@ describe('Signin Key Data Service', () => {
|
||||
});
|
||||
|
||||
describe('getSigningKeys', () => {
|
||||
it('throws error when no wellKnownEndpoints given', waitForAsync(() => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue(null);
|
||||
it('throws error when no wellKnownEndpoints given', async () => {
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => null
|
||||
);
|
||||
const result = service.getSigningKeys({ configId: 'configId1' });
|
||||
|
||||
result.subscribe({
|
||||
@@ -64,12 +67,14 @@ describe('Signin Key Data Service', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('throws error when no jwksUri given', waitForAsync(() => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ jwksUri: null });
|
||||
it('throws error when no jwksUri given', async () => {
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ jwksUri: null })
|
||||
);
|
||||
const result = service.getSigningKeys({ configId: 'configId1' });
|
||||
|
||||
result.subscribe({
|
||||
@@ -77,30 +82,34 @@ describe('Signin Key Data Service', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('calls dataservice if jwksurl is given', waitForAsync(() => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ jwksUri: 'someUrl' });
|
||||
const spy = spyOn(dataService, 'get').and.callFake(() => of());
|
||||
it('calls dataservice if jwksurl is given', async () => {
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ jwksUri: 'someUrl' })
|
||||
);
|
||||
const spy = vi.spyOn(dataService, 'get').mockImplementation(() => of());
|
||||
|
||||
const result = service.getSigningKeys({ configId: 'configId1' });
|
||||
|
||||
result.subscribe({
|
||||
complete: () => {
|
||||
expect(spy).toHaveBeenCalledOnceWith('someUrl', {
|
||||
expect(spy).toHaveBeenCalledExactlyOnceWith('someUrl', {
|
||||
configId: 'configId1',
|
||||
});
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should retry once', waitForAsync(() => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ jwksUri: 'someUrl' });
|
||||
spyOn(dataService, 'get').and.returnValue(
|
||||
it('should retry once', async () => {
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ jwksUri: 'someUrl' })
|
||||
);
|
||||
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => new Error('Error')),
|
||||
of(DUMMY_JWKS)
|
||||
@@ -113,13 +122,15 @@ describe('Signin Key Data Service', () => {
|
||||
expect(res).toEqual(DUMMY_JWKS);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should retry twice', waitForAsync(() => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ jwksUri: 'someUrl' });
|
||||
spyOn(dataService, 'get').and.returnValue(
|
||||
it('should retry twice', async () => {
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ jwksUri: 'someUrl' })
|
||||
);
|
||||
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => new Error('Error')),
|
||||
throwError(() => new Error('Error')),
|
||||
@@ -133,13 +144,15 @@ describe('Signin Key Data Service', () => {
|
||||
expect(res).toEqual(DUMMY_JWKS);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should fail after three tries', waitForAsync(() => {
|
||||
spyOn(storagePersistenceService, 'read')
|
||||
.withArgs('authWellKnownEndPoints', { configId: 'configId1' })
|
||||
.and.returnValue({ jwksUri: 'someUrl' });
|
||||
spyOn(dataService, 'get').and.returnValue(
|
||||
it('should fail after three tries', async () => {
|
||||
mockImplementationWhenArgsEqual(
|
||||
vi.spyOn(storagePersistenceService, 'read'),
|
||||
['authWellKnownEndPoints', { configId: 'configId1' }],
|
||||
() => ({ jwksUri: 'someUrl' })
|
||||
);
|
||||
vi.spyOn(dataService, 'get').mockReturnValue(
|
||||
createRetriableStream(
|
||||
throwError(() => new Error('Error')),
|
||||
throwError(() => new Error('Error')),
|
||||
@@ -153,21 +166,21 @@ describe('Signin Key Data Service', () => {
|
||||
expect(err).toBeTruthy();
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleErrorGetSigningKeys', () => {
|
||||
it('keeps observable if error is catched', waitForAsync(() => {
|
||||
it('keeps observable if error is catched', async () => {
|
||||
const result = (service as any).handleErrorGetSigningKeys(
|
||||
new HttpResponse()
|
||||
);
|
||||
const hasTypeObservable = isObservable(result);
|
||||
|
||||
expect(hasTypeObservable).toBeTrue();
|
||||
}));
|
||||
expect(hasTypeObservable).toBeTruthy();
|
||||
});
|
||||
|
||||
it('logs error if error is response', waitForAsync(() => {
|
||||
const logSpy = spyOn(loggerService, 'logError');
|
||||
it('logs error if error is response', async () => {
|
||||
const logSpy = vi.spyOn(loggerService, 'logError');
|
||||
|
||||
(service as any)
|
||||
.handleErrorGetSigningKeys(
|
||||
@@ -176,31 +189,31 @@ describe('Signin Key Data Service', () => {
|
||||
)
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(logSpy).toHaveBeenCalledOnceWith(
|
||||
expect(logSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
{ configId: 'configId1' },
|
||||
'400 - nono {}'
|
||||
);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('logs error if error is not a response', waitForAsync(() => {
|
||||
const logSpy = spyOn(loggerService, 'logError');
|
||||
it('logs error if error is not a response', async () => {
|
||||
const logSpy = vi.spyOn(loggerService, 'logError');
|
||||
|
||||
(service as any)
|
||||
.handleErrorGetSigningKeys('Just some Error', { configId: 'configId1' })
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(logSpy).toHaveBeenCalledOnceWith(
|
||||
expect(logSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
{ configId: 'configId1' },
|
||||
'Just some Error'
|
||||
);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('logs error if error with message property is not a response', waitForAsync(() => {
|
||||
const logSpy = spyOn(loggerService, 'logError');
|
||||
it('logs error if error with message property is not a response', async () => {
|
||||
const logSpy = vi.spyOn(loggerService, 'logError');
|
||||
|
||||
(service as any)
|
||||
.handleErrorGetSigningKeys(
|
||||
@@ -209,12 +222,12 @@ describe('Signin Key Data Service', () => {
|
||||
)
|
||||
.subscribe({
|
||||
error: () => {
|
||||
expect(logSpy).toHaveBeenCalledOnceWith(
|
||||
expect(logSpy).toHaveBeenCalledExactlyOnceWith(
|
||||
{ configId: 'configId1' },
|
||||
'Just some Error'
|
||||
);
|
||||
},
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user