Skip to content

Commit

Permalink
Add jenkinsInfoProvider tests (and fix bug :-) )
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Shirley <andrew.shirley@sainsburys.co.uk>
Signed-off-by: blam <ben@blam.sh>
  • Loading branch information
ashirley authored and benjdlambert committed Jul 14, 2021
1 parent b470921 commit 8e9f167
Show file tree
Hide file tree
Showing 2 changed files with 268 additions and 2 deletions.
266 changes: 266 additions & 0 deletions plugins/jenkins-backend/src/service/jenkinsInfoProvider.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
/*
* Copyright 2021 Spotify AB
*
* 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.
*/

import { DefaultJenkinsInfoProvider, JenkinsInfo } from './jenkinsInfoProvider';
import { CatalogClient } from '@backstage/catalog-client';
import { ConfigReader } from '@backstage/config';
import { Entity, EntityName } from '@backstage/catalog-model';

describe('DefaultJenkinsInfoProvider', () => {
const mockCatalog: jest.Mocked<CatalogClient> = ({
getEntityByName: jest.fn(),
} as any) as jest.Mocked<CatalogClient>;

const entityRef: EntityName = {
kind: 'Component',
namespace: 'foo',
name: 'bar',
};

function configureProvider(configData: any, entityData: any) {
const config = new ConfigReader(configData);
mockCatalog.getEntityByName.mockReturnValueOnce(
Promise.resolve(entityData as Entity),
);

return new DefaultJenkinsInfoProvider(mockCatalog, config);
}

it('Handles entity not found', async () => {
const provider = configureProvider({}, undefined);
await expect(provider.getInstance({ entityRef })).rejects.toThrowError();

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
});

it('Reads simple config and annotation', async () => {
const provider = configureProvider(
{
jenkins: {
baseUrl: 'https://jenkins.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
},
{
metadata: {
annotations: {
'jenkins.io/job-slug': 'teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toStrictEqual({
baseUrl: 'https://jenkins.example.com',
headers: {
Authorization:
'Basic YmFja3N0YWdlIC0gYm90OjEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNlZGYwMTI=',
},
jobName: 'teamA/artistLookup-build',
});
});

it('Reads named default config and annotation', async () => {
const provider = configureProvider(
{
jenkins: {
instances: [
{
name: 'default',
baseUrl: 'https://jenkins.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
],
},
},
{
metadata: {
annotations: {
'jenkins.io/job-slug': 'teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toMatchObject({
baseUrl: 'https://jenkins.example.com',
jobName: 'teamA/artistLookup-build',
});
});

it('Reads named default config (amongst named other configs) and annotation', async () => {
const provider = configureProvider(
{
jenkins: {
instances: [
{
name: 'default',
baseUrl: 'https://jenkins.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
{
name: 'other',
baseUrl: 'https://jenkins-other.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
],
},
},
{
metadata: {
annotations: {
'jenkins.io/job-slug': 'teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toMatchObject({
baseUrl: 'https://jenkins.example.com',
jobName: 'teamA/artistLookup-build',
});
});

it('Reads named other config and named annotation', async () => {
const provider = configureProvider(
{
jenkins: {
instances: [
{
name: 'default',
baseUrl: 'https://jenkins.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
{
name: 'other',
baseUrl: 'https://jenkins-other.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
],
},
},
{
metadata: {
annotations: {
'jenkins.io/job-slug': 'other:teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toMatchObject({
baseUrl: 'https://jenkins-other.example.com',
jobName: 'teamA/artistLookup-build',
});
});

it('Reads simple config and default named annotation', async () => {
const provider = configureProvider(
{
jenkins: {
baseUrl: 'https://jenkins.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
},
{
metadata: {
annotations: {
'jenkins.io/job-slug': 'default:teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toMatchObject({
baseUrl: 'https://jenkins.example.com',
jobName: 'teamA/artistLookup-build',
});
});

it('Reads simple config and old annotation', async () => {
const provider = configureProvider(
{
jenkins: {
baseUrl: 'https://jenkins.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
},
{
metadata: {
annotations: {
'jenkins.io/github-folder': 'teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toMatchObject({
baseUrl: 'https://jenkins.example.com',
jobName: 'teamA/artistLookup-build',
});
});

it('Reads named other config (with on default config) and named annotation', async () => {
const provider = configureProvider(
{
jenkins: {
instances: [
{
name: 'other',
baseUrl: 'https://jenkins-other.example.com',
username: 'backstage - bot',
apiKey: '123456789abcdef0123456789abcedf012',
},
],
},
},
{
metadata: {
annotations: {
'jenkins.io/job-slug': 'other:teamA/artistLookup-build',
},
},
},
);
const info: JenkinsInfo = await provider.getInstance({ entityRef });

expect(mockCatalog.getEntityByName).toBeCalledWith(entityRef);
expect(info).toMatchObject({
baseUrl: 'https://jenkins-other.example.com',
jobName: 'teamA/artistLookup-build',
});
});
});
4 changes: 2 additions & 2 deletions plugins/jenkins-backend/src/service/jenkinsInfoProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ export class DefaultJenkinsInfoProvider implements JenkinsInfoProvider {
// (jenkins.baseUrl, jenkins.username, jenkins.apiKey) or
// the entry with default name in jenkins.instances
const namedInstanceConfig = jenkinsConfig
.getConfigArray('instances')
.filter(c => c.getString('name') === DEFAULT_JENKINS_NAME)[0];
.getOptionalConfigArray('instances')
?.filter(c => c.getString('name') === DEFAULT_JENKINS_NAME)[0];
if (namedInstanceConfig) {
return namedInstanceConfig;
}
Expand Down

0 comments on commit 8e9f167

Please sign in to comment.