Skip to content

Commit

Permalink
feat(616): Can get a template using template name and tag
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyi committed Jul 19, 2017
1 parent 04be9e0 commit 60bd128
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"screwdriver-artifact-bookend": "^1.0.1",
"screwdriver-build-bookend": "^2.0.1",
"screwdriver-config-parser": "^3.3.0",
"screwdriver-data-schema": "^16.12.1",
"screwdriver-data-schema": "^16.14.1",
"screwdriver-datastore-sequelize": "^2.0.0",
"screwdriver-executor-docker": "^2.2.2",
"screwdriver-executor-k8s": "^10.3.3",
Expand Down
12 changes: 11 additions & 1 deletion plugins/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ server.register({

#### Get single template

`GET /templates/{id}`
You can get a single template by providing the template name and the specific version or the tag.

`GET /templates/{name}/{tag}` or `GET /templates/{name}/{version}`

**Arguments**

'name', 'tag' or 'version'

* `name` - Name of the template
* `tag` - Tag of the template (e.g. `stable`, `latest`, etc)
* `version` - Version of the template

#### Create a template
Create a template will store the template data (`config`, `name`, `version`, `description`, `maintainer`, `labels`) into the datastore.
Expand Down
59 changes: 47 additions & 12 deletions plugins/templates/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,59 @@ const joi = require('joi');
const schema = require('screwdriver-data-schema');
const getSchema = schema.models.template.get;
const baseSchema = schema.models.template.base;
const versionRegex = schema.config.regex.VERSION;
const versionSchema = joi.reach(baseSchema, 'version');

module.exports = () => ({
method: 'GET',
path: '/templates/{name}/{version}',
path: '/templates/{name}/{versionOrTag}',
config: {
description: 'Get a single template',
description: 'Get a single template given template name and version or tag',
notes: 'Returns a template record',
tags: ['api', 'templates'],
handler: (request, reply) => {
const factory = request.server.app.templateFactory;

return factory.getTemplate({
name: request.params.name,
version: request.params.version
}).then((template) => {
if (!template) {
throw boom.notFound('Template does not exist');
const versionOrTag = request.params.versionOrTag;
const templateFactory = request.server.app.templateFactory;

// check if version or tag
const isVersion = versionOrTag.match(versionRegex);

return new Promise((resolve, reject) => {
// if tag, get template tag version
if (!isVersion) {
const templateTagFactory = request.server.app.templateTagFactory;

return templateTagFactory.get({
name: request.params.name,
tag: request.params.versionOrTag
})
.then((templateTag) => {
if (!templateTag) {
return reject(boom.notFound(`Template ${request.params.name} ` +
`does not exist with tag ${request.params.versionOrTag}`));
}

return resolve(templateTag.version);
});
}

return reply(template);
// otherwise just return the version
return resolve(versionOrTag);
})
.then(version =>
// get the template
templateFactory.getTemplate({
name: request.params.name,
version
}).then((template) => {
if (!template) {
throw boom.notFound(`Template ${request.params.name} ` +
`does not exist with version ${version}`);
}

return reply(template);
})
)
.catch(err => reply(boom.wrap(err)));
},
response: {
Expand All @@ -34,7 +66,10 @@ module.exports = () => ({
validate: {
params: {
name: joi.reach(baseSchema, 'name'),
version: joi.reach(baseSchema, 'version')
versionOrTag: joi.alternatives().try(
versionSchema,
joi.reach(schema.models.templateTag.base, 'tag')
)
}
}
}
Expand Down
46 changes: 44 additions & 2 deletions test/plugins/templates.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const getPipelineMocks = (pipelines) => {

describe('template plugin test', () => {
let templateFactoryMock;
let templateTagFactoryMock;
let pipelineFactoryMock;
let plugin;
let server;
Expand All @@ -71,6 +72,9 @@ describe('template plugin test', () => {
list: sinon.stub(),
getTemplate: sinon.stub()
};
templateTagFactoryMock = {
get: sinon.stub()
};
pipelineFactoryMock = {
get: sinon.stub()
};
Expand All @@ -81,6 +85,7 @@ describe('template plugin test', () => {
server = new hapi.Server();
server.app = {
templateFactory: templateFactoryMock,
templateTagFactory: templateTagFactoryMock,
pipelineFactory: pipelineFactoryMock
};
server.connection({
Expand Down Expand Up @@ -147,7 +152,7 @@ describe('template plugin test', () => {
});
});

describe('GET /templates/name/version', () => {
describe('GET /templates/name/versionOrTag', () => {
let options;

beforeEach(() => {
Expand All @@ -157,7 +162,32 @@ describe('template plugin test', () => {
};
});

it('returns 200 and all templates', () => {
it('returns 200 and a template when given the template name and version', () => {
templateFactoryMock.getTemplate.resolves(testtemplate);

return server.inject(options).then((reply) => {
assert.deepEqual(reply.result, testtemplate);
assert.calledWith(templateFactoryMock.getTemplate, {
name: 'screwdriver/build',
version: '1.7.3'
});
assert.equal(reply.statusCode, 200);
});
});

it('returns 200 and a template when given the template name and tag', () => {
const testTagTemplate = {
id: 1,
name: 'template_namespace/nodejs_main',
tag: 'stable',
version: '1.7.3'
};

options = {
method: 'GET',
url: '/templates/screwdriver%2Fbuild/stable'
};
templateTagFactoryMock.get.resolves(testTagTemplate);
templateFactoryMock.getTemplate.resolves(testtemplate);

return server.inject(options).then((reply) => {
Expand All @@ -178,6 +208,18 @@ describe('template plugin test', () => {
});
});

it('returns 404 when template tag does not exist', () => {
options = {
method: 'GET',
url: '/templates/screwdriver%2Fbuild/stable'
};
templateTagFactoryMock.get.resolves(null);

return server.inject(options).then((reply) => {
assert.equal(reply.statusCode, 404);
});
});

it('returns 500 when datastore fails', () => {
templateFactoryMock.getTemplate.rejects(new Error('some error'));

Expand Down

0 comments on commit 60bd128

Please sign in to comment.