Skip to content

Commit

Permalink
test(solace-message-client): separate test aspects into different files
Browse files Browse the repository at this point in the history
  • Loading branch information
danielwiehl authored and Marcarrian committed May 14, 2024
1 parent f82ef2f commit 913467f
Show file tree
Hide file tree
Showing 6 changed files with 2,965 additions and 2,667 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import {AuthenticationScheme, SessionEventCode} from 'solclientjs';
import {SessionFixture} from './testing/session.fixture';
import {provideSession} from './testing/session-provider';
import {TestBed} from '@angular/core/testing';
import {Observable} from 'rxjs';
import {BehaviorSubject, EMPTY, NEVER, Observable, of, Subject} from 'rxjs';
import {inject, Injectable, InjectionToken, NgZone} from '@angular/core';
import {OAuthAccessTokenProvider} from './oauth-access-token-provider';
import {drainMicrotaskQueue, initSolclientFactory} from './testing/testing.utils';
import {SolaceSessionProvider} from './solace-session-provider';

describe('OAuth 2.0', () => {

Expand Down Expand Up @@ -196,4 +197,247 @@ describe('OAuth 2.0', () => {
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);
expect(console.warn).toHaveBeenCalledWith(jasmine.stringMatching(/\[AccessTokenProviderCompletedWarning]/));
});

it('should inject the access token into the Solace session', async () => {
const sessionFixture = new SessionFixture();
const accessToken$ = new Subject<string>();

TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => accessToken$,
}),
provideSession(sessionFixture),
],
});

// WHEN injected the message client
TestBed.inject(SolaceMessageClient);
await drainMicrotaskQueue();

// THEN expect "solclientjs" not to be initialized yet, but only after having emitted the access token
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);

// WHEN emitted the initial access token
accessToken$.next('access-token-1');
await drainMicrotaskQueue();
// THEN
// expect "solclientjs" to be initialized with the "one-time" access time
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledWith(jasmine.objectContaining({
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: 'access-token-1',
}));
// expect the access token not to be updated
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);

sessionFixture.sessionProvider.provide.calls.reset();
sessionFixture.session.updateAuthenticationOnReconnect.calls.reset();

// WHEN emitted a renewed access token
accessToken$.next('access-token-2');
// THEN
// expect "solclientjs" not to be initialized anew
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
// expect the access token to be updated
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledWith(jasmine.objectContaining({accessToken: 'access-token-2'}));

sessionFixture.sessionProvider.provide.calls.reset();
sessionFixture.session.updateAuthenticationOnReconnect.calls.reset();

// WHEN emitted a renewed access token
accessToken$.next('access-token-3');
// THEN
// expect "solclientjs" not to be initialized anew
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
// expect the access token to be updated
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledWith(jasmine.objectContaining({accessToken: 'access-token-3'}));
});

it('should error if not configured an access token or an `OAuthAccessTokenProvider` [NullAccessTokenConfigError]', async () => {
const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await drainMicrotaskQueue();

expect(console.error).toHaveBeenCalledWith(jasmine.stringMatching(/\[SolaceMessageClient]/), jasmine.stringMatching(/\[NullAccessTokenConfigError]/));
expect(TestBed.inject(SolaceSessionProvider).provide).toHaveBeenCalledTimes(0);
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);
});

it('should error if forgotten to register `OAuthAccessTokenProvider` as Angular provider [NullAccessTokenProviderError]', async () => {
// Create a provider, but forget to register it as Angular provider
@Injectable()
class TestAccessTokenProvider implements OAuthAccessTokenProvider {

Check warning on line 284 in projects/solace-message-client/src/lib/oauth-solace-message-client.spec.ts

View workflow job for this annotation

GitHub Actions / Linting

'OAuthAccessTokenProvider' is deprecated. since version 17.1.0; Use `OAuthAccessTokenFn` instead; API will be removed in a future release
public provide$(): Observable<string> {
return NEVER;
}
}

const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: TestAccessTokenProvider,
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await drainMicrotaskQueue();

expect(console.error).toHaveBeenCalledWith(jasmine.stringMatching(/\[SolaceMessageClient]/), jasmine.stringMatching(/\[NullAccessTokenProviderError]/));
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);
});

it('should error when emitting `null` as the initial access token [NullAccessTokenError]', async () => {
const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => of(null! as string),
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await drainMicrotaskQueue();

expect(console.error).toHaveBeenCalledWith(jasmine.stringMatching(/\[SolaceMessageClient]/), jasmine.stringMatching(/\[NullAccessTokenError]/));
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);
});

it('should error when emitting `undefined` as the initial access token [NullAccessTokenError]', async () => {
const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => of(undefined! as string),
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await drainMicrotaskQueue();

expect(console.error).toHaveBeenCalledWith(jasmine.stringMatching(/\[SolaceMessageClient]/), jasmine.stringMatching(/\[NullAccessTokenError]/));
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);
});

it('should error when the access token Observable completes without having having emitted an access token [EmptyAccessTokenError]', async () => {
const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => EMPTY,
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await drainMicrotaskQueue();

expect(console.error).toHaveBeenCalledWith(jasmine.stringMatching(/\[SolaceMessageClient]/), jasmine.stringMatching(/\[EmptyAccessTokenError]/));
expect(sessionFixture.sessionProvider.provide).toHaveBeenCalledTimes(0);
expect(sessionFixture.session.updateAuthenticationOnReconnect).toHaveBeenCalledTimes(0);
});

it('should warn when the access token Observable completes [AccessTokenProviderCompletedWarning] (1/2)', async () => {
const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => of('access token'), // completes after emitted the initial access token,
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await sessionFixture.simulateEvent(SessionEventCode.UP_NOTICE);

expect(console.warn).toHaveBeenCalledWith(jasmine.stringMatching(/\[AccessTokenProviderCompletedWarning]/));
});

it('should warn when the access token Observable completes [AccessTokenProviderCompletedWarning] (2/2)', async () => {
const sessionFixture = new SessionFixture();
TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => of('access token 1', 'access token 2', 'access token 3'), // completes after 3 emissions
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await sessionFixture.simulateEvent(SessionEventCode.UP_NOTICE);

expect(console.warn).toHaveBeenCalledWith(jasmine.stringMatching(/\[AccessTokenProviderCompletedWarning]/));
});

it('should error when emitting `null` as access token [NullAccessTokenError]', async () => {
const sessionFixture = new SessionFixture();
const accessToken$ = new BehaviorSubject<string>('access-token-1');

TestBed.configureTestingModule({
providers: [
provideSolaceMessageClient({
url: 'url',
vpnName: 'vpn',
authenticationScheme: AuthenticationScheme.OAUTH2,
accessToken: () => accessToken$,
}),
provideSession(sessionFixture),
],
});

TestBed.inject(SolaceMessageClient);
await sessionFixture.simulateEvent(SessionEventCode.UP_NOTICE);

accessToken$.next('access-token-2');
accessToken$.next('access-token-3');
expect(console.error).not.toHaveBeenCalledWith(jasmine.stringMatching(/\[NullAccessTokenError]/));

accessToken$.next(null!);
expect(console.error).toHaveBeenCalledWith(jasmine.stringMatching(/\[NullAccessTokenError]/));
});
});
Loading

0 comments on commit 913467f

Please sign in to comment.