Update prepare test

This commit is contained in:
Johan Haals
2021-01-27 11:26:59 +01:00
parent 7e7e24c61c
commit 46211fa5be
4 changed files with 99 additions and 292 deletions
@@ -14,21 +14,13 @@
* limitations under the License.
*/
jest.doMock('fs-extra', () => ({
promises: {
mkdtemp: jest.fn(dir => `${dir}-static`),
},
}));
import fs from 'fs-extra';
import { BitbucketPreparer } from './bitbucket';
import {
TemplateEntityV1alpha1,
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import { getVoidLogger, Git } from '@backstage/backend-common';
jest.mock('fs-extra');
describe('BitbucketPreparer', () => {
let mockEntity: TemplateEntityV1alpha1;
const logger = getVoidLogger();
const mockGitClient = {
clone: jest.fn(),
@@ -38,44 +30,6 @@ describe('BitbucketPreparer', () => {
beforeEach(() => {
jest.clearAllMocks();
mockEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Template',
metadata: {
annotations: {
[LOCATION_ANNOTATION]:
'bitbucket:https://bitbucket.org/backstage-project/backstage-repo',
},
name: 'graphql-starter',
title: 'GraphQL Service',
description:
'A GraphQL starter template for backstage to get you up and running\nthe best pracices with GraphQL\n',
uid: '9cf16bad-16e0-4213-b314-c4eec773c50b',
etag: 'ZTkxMjUxMjUtYWY3Yi00MjU2LWFkYWMtZTZjNjU5ZjJhOWM2',
generation: 1,
},
spec: {
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
required: ['storePath', 'owner'],
properties: {
owner: {
type: 'string',
title: 'Owner',
description: 'Who is going to own this component',
},
storePath: {
type: 'string',
title: 'Store path',
description: 'GitHub store path in org/repo format',
},
},
},
},
};
});
const preparer = BitbucketPreparer.fromConfig({
@@ -84,12 +38,20 @@ describe('BitbucketPreparer', () => {
appPassword: 'fake-password',
});
const prepareOptions = {
url: 'https://bitbucket.org/backstage-project/backstage-repo',
logger,
workspacePath: '/tmp',
};
it('calls the clone command with the correct arguments for a repository', async () => {
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
await preparer.prepare(prepareOptions);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://bitbucket.org/backstage-project/backstage-repo',
dir: expect.any(String),
dir: '/tmp/checkout',
});
expect(fs.move).toHaveBeenCalledWith('/tmp/checkout', '/tmp/template');
expect(fs.rmdir).toHaveBeenCalledWith('/tmp/template/.git');
});
it('calls the clone command with the correct arguments if an app password is provided for a repository', async () => {
@@ -98,7 +60,7 @@ describe('BitbucketPreparer', () => {
username: 'fake-user',
appPassword: 'fake-password',
});
await preparer.prepare(mockEntity, { logger });
await preparer.prepare(prepareOptions);
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
@@ -108,22 +70,22 @@ describe('BitbucketPreparer', () => {
});
it('calls the clone command with the correct arguments for a repository when no path is provided', async () => {
delete mockEntity.spec.path;
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
await preparer.prepare(prepareOptions);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://bitbucket.org/backstage-project/backstage-repo',
dir: expect.any(String),
dir: '/tmp/checkout',
});
});
it('return the temp directory with the path to the folder if it is specified', async () => {
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
logger: getVoidLogger(),
it('moves a template subdirectory to checkout if specified', async () => {
await preparer.prepare({
url: 'https://bitbucket.org/foo/bar/src/master/1/2/3',
logger,
workspacePath: '/tmp',
});
expect(response.split('\\').join('/')).toMatch(
/\/template\/test\/1\/2\/3$/,
expect(fs.move).toHaveBeenCalledWith(
'/tmp/checkout/1/2/3',
'/tmp/template',
);
});
@@ -133,7 +95,7 @@ describe('BitbucketPreparer', () => {
token: 'fake-token',
});
await preparer.prepare(mockEntity, { logger });
await preparer.prepare(prepareOptions);
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
@@ -141,16 +103,4 @@ describe('BitbucketPreparer', () => {
password: 'fake-token',
});
});
it('return the working directory with the path to the folder if it is specified', async () => {
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
workingDirectory: '/workDir',
logger: getVoidLogger(),
});
expect(response.split('\\').join('/')).toMatch(
/\/workDir\/graphql-starter-static\/template\/test\/1\/2\/3$/,
);
});
});
@@ -14,57 +14,34 @@
* limitations under the License.
*/
import os from 'os';
import fs from 'fs-extra';
import YAML from 'yaml';
import { FilePreparer } from './file';
import path from 'path';
import {
TemplateEntityV1alpha1,
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import { getVoidLogger } from '@backstage/backend-common';
import fs from 'fs-extra';
import { FilePreparer } from './file';
const setupTest = async (fixturePath: string) => {
const locationForTemplateYaml = path.resolve(
path.dirname(
require.resolve('@backstage/plugin-scaffolder-backend/package'),
),
'fixtures',
fixturePath,
);
const [parsedDocument] = YAML.parseAllDocuments(
await fs.readFile(locationForTemplateYaml, 'utf-8'),
);
const template: TemplateEntityV1alpha1 = parsedDocument.toJSON();
template.metadata.annotations = {
[LOCATION_ANNOTATION]: `file:${locationForTemplateYaml}`,
};
const filePreparer = new FilePreparer();
const resultDir = await filePreparer.prepare(template, {
logger: getVoidLogger(),
workingDirectory: os.tmpdir(),
});
return { filePreparer, template, resultDir };
};
jest.mock('fs-extra');
describe('File preparer', () => {
it('excludes the yaml file from the temp folder', async () => {
const { resultDir } = await setupTest('test-simple-template/template.yaml');
expect(fs.existsSync(`${resultDir}/template.yaml`)).toBe(false);
});
const logger = getVoidLogger();
const preparer = new FilePreparer();
it('prepares templates from a file path', async () => {
await preparer.prepare({
url: 'file:///path/to/template',
logger,
workspacePath: '/tmp',
});
expect(fs.copy).toHaveBeenCalledWith('/path/to/template', '/tmp/checkout', {
recursive: true,
});
expect(fs.ensureDir).toHaveBeenCalledWith('/tmp/checkout');
it('resolves relative path from the template', async () => {
const { resultDir } = await setupTest('test-simple-template/template.yaml');
expect(fs.existsSync(`${resultDir}/expected_file.ts`)).toBe(true);
});
it('resolves relative path from the nested template', async () => {
const { resultDir } = await setupTest('test-nested-template/template.yaml');
expect(fs.existsSync(`${resultDir}/expected_file.ts`)).toBe(true);
await expect(
preparer.prepare({
url: 'file://not/full/path',
logger,
workspacePath: '/tmp',
}),
).rejects.toThrow(
"Wrong location protocol, should be 'file', file://not/full/path",
);
});
});
@@ -14,12 +14,7 @@
* limitations under the License.
*/
jest.doMock('fs-extra', () => ({
promises: {
mkdtemp: jest.fn(dir => `${dir}-static`),
},
}));
import fs from 'fs-extra';
import { GithubPreparer } from './github';
import {
TemplateEntityV1alpha1,
@@ -27,6 +22,8 @@ import {
} from '@backstage/catalog-model';
import { getVoidLogger, Git } from '@backstage/backend-common';
jest.mock('fs-extra');
describe('GitHubPreparer', () => {
let mockEntity: TemplateEntityV1alpha1;
const mockGitClient = {
@@ -38,44 +35,6 @@ describe('GitHubPreparer', () => {
beforeEach(() => {
jest.clearAllMocks();
mockEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Template',
metadata: {
annotations: {
[LOCATION_ANNOTATION]:
'github:https://github.com/benjdlambert/backstage-graphql-template/blob/master/template.yaml',
},
name: 'graphql-starter',
title: 'GraphQL Service',
description:
'A GraphQL starter template for backstage to get you up and running\nthe best pracices with GraphQL\n',
uid: '9cf16bad-16e0-4213-b314-c4eec773c50b',
etag: 'ZTkxMjUxMjUtYWY3Yi00MjU2LWFkYWMtZTZjNjU5ZjJhOWM2',
generation: 1,
},
spec: {
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
required: ['storePath', 'owner'],
properties: {
owner: {
type: 'string',
title: 'Owner',
description: 'Who is going to own this component',
},
storePath: {
type: 'string',
title: 'Store path',
description: 'GitHub store path in org/repo format',
},
},
},
},
};
});
const preparer = GithubPreparer.fromConfig({
@@ -84,58 +43,47 @@ describe('GitHubPreparer', () => {
});
it('calls the clone command with the correct arguments for a repository', async () => {
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
await preparer.prepare({
url:
'https://github.com/benjdlambert/backstage-graphql-template/blob/master/templates/graphql-starter/template',
logger,
workspacePath: '/tmp',
});
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://github.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
});
expect(fs.move).toHaveBeenCalledWith(
'/tmp/checkout/templates/graphql-starter/template',
'/tmp/template',
);
expect(fs.rmdir).toHaveBeenCalledWith('/tmp/template/.git');
});
it('calls the clone command with the correct arguments for a repository when no path is provided', async () => {
delete mockEntity.spec.path;
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
await preparer.prepare({
url:
'https://github.com/benjdlambert/backstage-graphql-template/blob/master',
logger,
workspacePath: '/tmp',
});
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://github.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
});
});
it('return the temp directory with the path to the folder if it is specified', async () => {
const preparer = GithubPreparer.fromConfig({
host: 'github.com',
token: 'fake-token',
});
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
logger: getVoidLogger(),
});
expect(response.split('\\').join('/')).toMatch(
/\/template\/test\/1\/2\/3$/,
);
});
it('return the working directory with the path to the folder if it is specified', async () => {
const preparer = GithubPreparer.fromConfig({
host: 'github.com',
token: 'fake-token',
});
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
workingDirectory: '/workDir',
logger: getVoidLogger(),
});
expect(response.split('\\').join('/')).toMatch(
/\/workDir\/graphql-starter-static\/template\/test\/1\/2\/3$/,
);
expect(fs.move).toHaveBeenCalledWith('/tmp/checkout', '/tmp/template');
expect(fs.rmdir).toHaveBeenCalledWith('/tmp/template/.git');
});
it('calls the clone command with token', async () => {
await preparer.prepare(mockEntity, { logger });
await preparer.prepare({
url:
'https://github.com/benjdlambert/backstage-graphql-template/blob/master',
logger,
workspacePath: '/tmp',
});
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
@@ -13,60 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
jest.doMock('fs-extra', () => ({
promises: {
mkdtemp: jest.fn(dir => `${dir}-static`),
},
}));
import fs from 'fs-extra';
import { GitlabPreparer } from './gitlab';
import {
TemplateEntityV1alpha1,
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import { getVoidLogger, Git } from '@backstage/backend-common';
const mockTemplate = (): TemplateEntityV1alpha1 => ({
apiVersion: 'backstage.io/v1alpha1',
kind: 'Template',
metadata: {
annotations: {
[LOCATION_ANNOTATION]:
'url:https://gitlab.com/benjdlambert/backstage-graphql-template/-/blob/master/template.yaml',
},
name: 'graphql-starter',
title: 'GraphQL Service',
description:
'A GraphQL starter template for backstage to get you up and running\nthe best practices with GraphQL\n',
uid: '9cf16bad-16e0-4213-b314-c4eec773c50b',
etag: 'ZTkxMjUxMjUtYWY3Yi00MjU2LWFkYWMtZTZjNjU5ZjJhOWM2',
generation: 1,
},
spec: {
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
required: ['storePath', 'owner'],
properties: {
owner: {
type: 'string',
title: 'Owner',
description: 'Who is going to own this component',
},
storePath: {
type: 'string',
title: 'Store path',
description: 'GitHub store path in org/repo format',
},
},
},
},
});
jest.mock('fs-extra');
describe('GitLabPreparer', () => {
let mockEntity: TemplateEntityV1alpha1;
const mockGitClient = {
clone: jest.fn(),
};
@@ -81,61 +34,40 @@ describe('GitLabPreparer', () => {
host: 'gitlab.com',
token: 'fake-token',
});
it(`calls the clone command with the correct arguments for a repository`, async () => {
mockEntity = mockTemplate();
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
it(`calls the clone command with the correct arguments for a repository`, async () => {
await preparer.prepare({
url:
'https://gitlab.com/benjdlambert/backstage-graphql-template/-/blob/master',
logger,
workspacePath: '/tmp',
});
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://gitlab.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
dir: '/tmp/checkout',
});
});
it(`calls the clone command with the correct arguments if an access token is provided in integrations for a repository`, async () => {
mockEntity = mockTemplate();
await preparer.prepare(mockEntity, { logger });
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
username: 'oauth2',
password: 'fake-token',
});
expect(fs.move).toHaveBeenCalledWith('/tmp/checkout', '/tmp/template');
expect(fs.rmdir).toHaveBeenCalledWith('/tmp/template/.git');
});
it(`calls the clone command with the correct arguments for a repository when no path is provided`, async () => {
mockEntity = mockTemplate();
delete mockEntity.spec.path;
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://gitlab.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
it(`clones the template from a sub directory if specified`, async () => {
await preparer.prepare({
url:
'https://gitlab.com/benjdlambert/backstage-graphql-template/-/blob/master/1/2/3',
logger,
workspacePath: '/tmp',
});
});
it(`return the temp directory with the path to the folder if it is specified`, async () => {
mockEntity = mockTemplate();
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
logger: getVoidLogger(),
});
expect(response.split('\\').join('/')).toMatch(
/\/template\/test\/1\/2\/3$/,
);
});
it('return the working directory with the path to the folder if it is specified', async () => {
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
workingDirectory: '/workDir',
logger: getVoidLogger(),
});
expect(response.split('\\').join('/')).toMatch(
/\/workDir\/graphql-starter-static\/template\/test\/1\/2\/3$/,
expect(fs.move).toHaveBeenCalledWith(
'/tmp/checkout/1/2/3',
'/tmp/template',
);
});
});