From 2e60250c7dbecaf6340597a4f4c700823a8d1aa8 Mon Sep 17 00:00:00 2001 From: Ilya Katlinski Date: Tue, 8 Aug 2023 10:58:46 +0200 Subject: [PATCH] test: update unit test for vault plugin api and table Signed-off-by: Ilya Katlinski --- plugins/vault/src/api.test.ts | 34 +++++++++----- .../EntityVaultTable.test.tsx | 44 +++++++++++++++---- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/plugins/vault/src/api.test.ts b/plugins/vault/src/api.test.ts index ec88412303..47d33f2d99 100644 --- a/plugins/vault/src/api.test.ts +++ b/plugins/vault/src/api.test.ts @@ -21,6 +21,9 @@ import { VaultSecret, VaultClient } from './api'; import { UrlPatternDiscovery } from '@backstage/core-app-api'; describe('api', () => { + let api: VaultClient; + let fetchApiSpy: jest.SpyInstance>; + const server = setupServer(); setupRequestMockHandlers(server); @@ -64,37 +67,48 @@ describe('api', () => { ); }; - it('should return secrets', async () => { + beforeEach(() => { setupHandlers(); - const api = new VaultClient({ discoveryApi, fetchApi }); + + api = new VaultClient({ discoveryApi, fetchApi }); + fetchApiSpy = jest.spyOn(fetchApi, 'fetch'); + }); + + it('should return secrets', async () => { expect(await api.listSecrets('test/success')).toEqual( mockSecretsResult.items, ); + expect(fetchApiSpy).toHaveBeenCalledWith( + `${mockBaseUrl}/v1/secrets/test%2Fsuccess?`, + expect.anything(), + ); + }); + + it('should return secrets with custom engine', async () => { + expect(await api.listSecrets('test/success', 'kv')).toEqual( + mockSecretsResult.items, + ); + expect(fetchApiSpy).toHaveBeenCalledWith( + `${mockBaseUrl}/v1/secrets/test%2Fsuccess?engine=kv`, + expect.anything(), + ); }); it('should return empty secret list', async () => { - setupHandlers(); - const api = new VaultClient({ discoveryApi, fetchApi }); expect(await api.listSecrets('test/empty')).toEqual([]); }); it('should return all the secrets if no path defined', async () => { - setupHandlers(); - const api = new VaultClient({ discoveryApi, fetchApi }); expect(await api.listSecrets('')).toEqual(mockSecretsResult.items); }); it('should throw an error if the Vault API responds with an HTTP 404', async () => { - setupHandlers(); - const api = new VaultClient({ discoveryApi, fetchApi }); await expect(api.listSecrets('test/not-found')).rejects.toThrow( "No secrets found in path 'v1/secrets/test%2Fnot-found'", ); }); it('should throw an error if the Vault API responds with a non-successful HTTP status code', async () => { - setupHandlers(); - const api = new VaultClient({ discoveryApi, fetchApi }); await expect(api.listSecrets('test/error')).rejects.toThrow( 'Request failed with 400 Error', ); diff --git a/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx b/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx index e5bd5b43de..4cf5b60026 100644 --- a/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx +++ b/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx @@ -29,23 +29,31 @@ import { VaultSecret, vaultApiRef, VaultClient } from '../../api'; import { rest } from 'msw'; describe('EntityVaultTable', () => { + let vaultClient: VaultClient; + let apis: TestApiRegistry; + let listSecretsSpy: jest.SpyInstance>; + const server = setupServer(); setupRequestMockHandlers(server); - let apis: TestApiRegistry; const mockBaseUrl = 'https://api-vault.com/api/vault'; const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); const fetchApi = new MockFetchApi(); - const entity = (secretPath: string) => { + const entity = (secretPath: string, secretEngine?: string | undefined) => { + const annotations: Record = { + 'vault.io/secrets-path': secretPath, + }; + if (secretEngine) { + annotations['vault.io/secrets-engine'] = secretEngine; + } + return { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', metadata: { name: 'test', description: 'This is the description', - annotations: { - 'vault.io/secrets-path': secretPath, - }, + annotations, }, spec: { lifecycle: 'production', @@ -56,6 +64,7 @@ describe('EntityVaultTable', () => { }; const entityOk = entity('test/success'); + const entityOkWithEngine = entity('test/success', 'kv'); const entityEmpty = entity('test/empty'); const entityNotOk = entity('test/error'); @@ -91,10 +100,9 @@ describe('EntityVaultTable', () => { }; beforeEach(() => { - apis = TestApiRegistry.from([ - vaultApiRef, - new VaultClient({ discoveryApi, fetchApi }), - ]); + vaultClient = new VaultClient({ discoveryApi, fetchApi }); + apis = TestApiRegistry.from([vaultApiRef, vaultClient]); + listSecretsSpy = jest.spyOn(vaultClient, 'listSecrets'); }); it('should render secrets', async () => { @@ -107,6 +115,24 @@ describe('EntityVaultTable', () => { expect(await rendered.findAllByText(/secret::one/)).toBeDefined(); expect(await rendered.findAllByText(/secret::two/)).toBeDefined(); + + expect(listSecretsSpy).toHaveBeenCalledTimes(1); + expect(listSecretsSpy).toHaveBeenCalledWith('test/success', undefined); + }); + + it('should render secrets with custom engine', async () => { + setupHandlers(); + const rendered = await renderInTestApp( + + + , + ); + + expect(await rendered.findAllByText(/secret::one/)).toBeDefined(); + expect(await rendered.findAllByText(/secret::two/)).toBeDefined(); + + expect(listSecretsSpy).toHaveBeenCalledTimes(1); + expect(listSecretsSpy).toHaveBeenCalledWith('test/success', 'kv'); }); it('should render no secrets found', async () => {