Skip to content

Commit

Permalink
fix: add unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Denis Golovin <[email protected]>
  • Loading branch information
dgolovin committed Jan 22, 2024
1 parent a81129d commit 51a7aee
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 25 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
},
"scripts": {
"build": "rollup --bundleConfigAsCjs --config rollup.config.js --compact --environment BUILD:production && node ./scripts/build.js",
"watch": "rollup --bundleConfigAsCjs --config rollup.config.js -w"
"watch": "rollup --bundleConfigAsCjs --config rollup.config.js -w",
"test": "vitest run --coverage"
},
"dependencies": {
"@podman-desktop/api": "^0.14.1",
Expand All @@ -39,6 +40,8 @@
"rollup": "^3.20.4",
"tslib": "^2.5.0",
"typescript": "^5.0.4",
"zip-local": "^0.3.5"
"zip-local": "^0.3.5",
"vite": "^5.0.11",
"vitest": "^1.1.1"
}
}
2 changes: 1 addition & 1 deletion src/authentication-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function createServer(config: AuthConfig, nonce: string) {
}

export async function startServer(config: ServerConfig, server: http.Server): Promise<string> {
let portTimer: NodeJS.Timer;
let portTimer: NodeJS.Timeout;

function cancelPortTimer() {
clearTimeout(portTimer);
Expand Down
48 changes: 48 additions & 0 deletions src/authentication-service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

import { afterEach, expect, beforeEach, test, vi, vitest } from 'vitest';
import { convertToSession } from './authentication-service';

vi.mock('@podman-desktop/api', async () => {
return {
EventEmitter: function() {}
};
});

test('An authentication token is converted to a session', () => {
const token = {
account: {
id: 'accountId',
label: 'accountLabel',
},
scope: 'openid',
sessionId: 'sessionId',
refreshToken: 'refreshToken',
accessToken: 'accessToken',
idToken: 'idToken',
expiresAt: Date.now() + 777777777,
expiresIn: 777777,
};
const session = convertToSession(token)
expect(session.id).equals(token.sessionId);
expect(session.accessToken).equals(token.accessToken);
expect(session.idToken).equals(token.idToken);
expect(session.account).equals(token.account);;
expect(session.scopes).contain('openid');
});
44 changes: 22 additions & 22 deletions src/authentication-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ export const onDidChangeSessions = new EventEmitter<AuthenticationProviderAuthen

export const REFRESH_NETWORK_FAILURE = 'Network failure';

/**
* Return a session object without checking for expiry and potentially refreshing.
* @param token The token information.
*/
export function convertToSession(token: IToken): RedHatAuthenticationSession {
return {
id: token.sessionId,
accessToken: token.accessToken!,
idToken: token.idToken,
account: token.account,
scopes: token.scope.split(' '),
};
}

export interface RedHatAuthenticationSession extends AuthenticationSession{
idToken: string | undefined;
readonly id: string;
Expand Down Expand Up @@ -179,7 +193,7 @@ export class RedHatAuthenticationService {
if (!matchesExisting && session.refreshToken) {
try {
const token = await this.refreshToken(session.refreshToken, session.scope, session.id);
added.push(this.convertToSessionSync(token));
added.push(convertToSession(token));
} catch (e: any) {
if (e.message === REFRESH_NETWORK_FAILURE) {
// Ignore, will automatically retry on next poll.
Expand All @@ -197,7 +211,7 @@ export class RedHatAuthenticationService {
);
if (!matchesExisting) {
await this.removeSession(token.sessionId);
removed.push(this.convertToSessionSync(token));
removed.push(convertToSession(token));
}
}),
);
Expand All @@ -206,13 +220,13 @@ export class RedHatAuthenticationService {
} catch (e: any) {
Logger.error(e.message);
// if data is improperly formatted, remove all of it and send change event
removed = this._tokens.map(this.convertToSessionSync);
removed = this._tokens.map(convertToSession);
this.clearSessions();
}
} else {
if (this._tokens.length) {
// Log out all, remove all local data
removed = this._tokens.map(this.convertToSessionSync);
removed = this._tokens.map(convertToSession);
Logger.info('No stored keychain data, clearing local data');

this._tokens = [];
Expand All @@ -230,20 +244,6 @@ export class RedHatAuthenticationService {
}
}

/**
* Return a session object without checking for expiry and potentially refreshing.
* @param token The token information.
*/
private convertToSessionSync(token: IToken): RedHatAuthenticationSession {
return {
id: token.sessionId,
accessToken: token.accessToken!,
idToken: token.idToken,
account: token.account,
scopes: token.scope.split(' '),
};
}

private async convertToSession(token: IToken): Promise<RedHatAuthenticationSession> {
const resolvedTokens = await this.resolveAccessAndIdTokens(token);
return {
Expand Down Expand Up @@ -408,7 +408,7 @@ export class RedHatAuthenticationService {
setTimeout(async () => {
try {
const refreshedToken = await this.refreshToken(token.refreshToken, scope, token.sessionId);
onDidChangeSessions.fire({ added: [], removed: [], changed: [this.convertToSessionSync(refreshedToken)] });
onDidChangeSessions.fire({ added: [], removed: [], changed: [convertToSession(refreshedToken)] });
} catch (e: any) {
if (e.message === REFRESH_NETWORK_FAILURE) {
const didSucceedOnRetry = await this.handleRefreshNetworkError(
Expand All @@ -421,7 +421,7 @@ export class RedHatAuthenticationService {
}
} else {
await this.removeSession(token.sessionId);
onDidChangeSessions.fire({ added: [], removed: [this.convertToSessionSync(token)], changed: [] });
onDidChangeSessions.fire({ added: [], removed: [convertToSession(token)], changed: [] });
}
}
}, 1000 * (token.expiresIn - 30)),
Expand Down Expand Up @@ -514,7 +514,7 @@ export class RedHatAuthenticationService {
const token = this._tokens.find(token => token.sessionId === sessionId);
if (token) {
token.accessToken = undefined;
onDidChangeSessions.fire({ added: [], removed: [], changed: [this.convertToSessionSync(token)] });
onDidChangeSessions.fire({ added: [], removed: [], changed: [convertToSession(token)] });
}
}

Expand All @@ -541,7 +541,7 @@ export class RedHatAuthenticationService {
const token = this.removeInMemorySessionData(sessionId);
let session: RedHatAuthenticationSession | undefined;
if (token) {
session = this.convertToSessionSync(token);
session = convertToSession(token);
}
if (this._tokens.length === 0) {
await this.keychain.deleteToken();
Expand Down
44 changes: 44 additions & 0 deletions vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**********************************************************************
* Copyright (C) 2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

import path from 'node:path';
import { coverageConfig, testConfig } from '../../vitest-shared-extensions.config';

const PACKAGE_ROOT = __dirname;
const PACKAGE_NAME = 'extensions/kube-context';

/**
* Config for global end-to-end tests
* placed in project root tests folder
* @type {import('vite').UserConfig}
* @see https://vitest.dev/config/
*/

const config = {
test: {
...testConfig(),
...coverageConfig(PACKAGE_ROOT, PACKAGE_NAME),
},
resolve: {
alias: {
'@podman-desktop/api': path.resolve(PACKAGE_ROOT, '../../', '__mocks__/@podman-desktop/api.js'),
},
},
};

export default config;

0 comments on commit 51a7aee

Please sign in to comment.