add test for platform

This commit is contained in:
Nik Graf 2017-06-19 17:48:19 +02:00
parent d25eadbcf7
commit ffe36026cf
No known key found for this signature in database
GPG Key ID: 7A97512F916175F1
3 changed files with 162 additions and 37 deletions

View File

@ -10,7 +10,6 @@
"./logs/logs.js",
"./login/login.js",
"./logout/logout.js",
"./platform/platform.js",
"./metrics/metrics.js",
"./remove/remove.js",
"./rollback/index.js",
@ -40,6 +39,7 @@
"./aws/package/compile/events/cognitoUserPool/index.js",
"./aws/deployFunction/index.js",
"./aws/deployList/index.js",
"./aws/invokeLocal/index.js"
"./aws/invokeLocal/index.js",
"./platform/platform.js"
]
}

View File

@ -4,6 +4,7 @@ const path = require('path');
const fs = require('fs');
const gql = require('graphql-tag');
const jwtDecode = require('jwt-decode');
const BbPromise = require('bluebird');
const fsExtra = require('../../utils/fs/fse');
const fetch = require('node-fetch');
const configUtils = require('../../utils/config');
@ -27,23 +28,6 @@ function addReadme(attributes, readmePath) {
return attributes;
}
function publishService(service, client) {
return client
.mutate({
mutation: gql`
mutation publishService($service: ServicePublishInputType!) {
publishService(service: $service) {
name
}
}
`,
variables: {
service,
},
})
.then(response => response.data);
}
function fetchEndpoint(provider, stage, region) {
return provider
.request(
@ -72,33 +56,55 @@ class Platform {
constructor(serverless, options) {
this.serverless = serverless;
this.options = options;
this.hooks = {
'after:deploy:deploy': this.publishService.bind(this),
};
this.provider = this.serverless.getProvider('aws');
// NOTE for the time being we only track services published to AWS
if (this.provider) {
this.hooks = {
'after:deploy:deploy': this.publishService.bind(this),
};
}
}
publishService() {
this.serverless.cli.log('Publish service to Serverless Platform...');
publishServiceRequest(service, client) {
return client
.mutate({
mutation: gql`
mutation publishService($service: ServicePublishInputType!) {
publishService(service: $service) {
name
}
}
`,
variables: { service },
})
.then(response => response.data);
}
getAuthToken() {
const userConfig = configUtils.getConfig();
const currentId = userConfig.userId;
const globalConfig = configUtils.getGlobalConfig();
let authToken;
if (globalConfig.users && globalConfig.users[currentId] && globalConfig.users[currentId].auth) {
authToken = globalConfig.users[currentId].auth.id_token;
return globalConfig.users[currentId].auth.id_token;
}
return null;
}
publishService() {
const authToken = this.getAuthToken();
if (!authToken) {
// NOTE publishService is an opt-in feature and no warning is needed
return undefined;
return BbPromise.resolve();
}
this.serverless.cli.log('Publish service to Serverless Platform...');
const clientWithAuth = createApolloClient(config.GRAPHQL_ENDPOINT_URL, authToken);
const provider = this.serverless.getProvider('aws');
const region = this.serverless.service.provider.region;
const stage = this.serverless.processedInput.options.stage;
return provider.getAccountId().then(accountId => {
fetchEndpoint(provider, stage, region).then(endpoint => {
return this.provider.getAccountId().then(accountId =>
fetchEndpoint(this.provider, stage, region).then(endpoint => {
const funcs = this.serverless.service.getAllFunctions().map(key => {
const arnName = functionInfoUtils.getArnName(key, this.serverless);
let funcAttributes = {
@ -121,7 +127,6 @@ class Platform {
}
return funcAttributes;
});
const serviceData = {
name: this.serverless.service.service,
stage: this.serverless.processedInput.options.stage,
@ -148,8 +153,7 @@ class Platform {
const readmePath = path.join(this.serverless.config.servicePath, 'README.md');
const serviceDataWithReadme = addReadme(serviceData, readmePath);
// publish to platform
publishService(serviceDataWithReadme, clientWithAuth)
return this.publishServiceRequest(serviceDataWithReadme, clientWithAuth)
.then(() => {
const username = jwtDecode(authToken).nickname;
const serviceName = this.serverless.service.service;
@ -162,8 +166,8 @@ class Platform {
error
);
});
});
});
})
);
}
}

View File

@ -1,16 +1,19 @@
'use strict';
const expect = require('chai').expect;
const sinon = require('sinon');
const PlatformPlugin = require('./platform');
const Serverless = require('../../Serverless');
const AwsProvider = require('../aws/provider/awsProvider');
describe('platform', () => {
describe.only('platform', () => {
let serverless;
let plugin;
beforeEach(() => {
serverless = new Serverless();
serverless.init();
serverless.setProvider('aws', new AwsProvider(serverless));
plugin = new PlatformPlugin(serverless);
});
@ -22,5 +25,123 @@ describe('platform', () => {
it('should have a hook after the deploy', () => {
expect(plugin.hooks).to.have.property('after:deploy:deploy');
});
it('should set the provider variable to an instance of AwsProvider', () => {
expect(plugin.provider).to.be.instanceof(AwsProvider);
});
});
describe('#publishService()', () => {
let getAuthTokenStub;
let getAccountIdStub;
let endpointsRequestStub;
let publishServiceRequestStub;
beforeEach(() => {
getAuthTokenStub = sinon.stub(plugin, 'getAuthToken').returns(
// eslint-disable-next-line max-len
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0OTc4ODMwMzMsImV4cCI6MTUyOTQxOTAzMywiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIm5pY2tuYW1lIjoiam9obmRvZSJ9.GD6sqQR3qLirnrvLKKrmOc7vgsHpqZ3TPwyG8ZI69ig'
);
getAccountIdStub = sinon.stub(plugin.provider, 'getAccountId').resolves('acountId123');
endpointsRequestStub = sinon.stub(plugin.provider, 'request').resolves({
Stacks: [
{
Outputs: [{ OutputKey: 'ServiceEndpoint', OutputValue: 'http://service-endpoint' }],
},
],
});
publishServiceRequestStub = sinon.stub(plugin, 'publishServiceRequest').resolves();
});
afterEach(() => {
getAuthTokenStub.restore();
getAccountIdStub.restore();
endpointsRequestStub.restore();
publishServiceRequestStub.restore();
});
it('should send a minimal service request to the platform', () => {
plugin.serverless.service.service = 'new-service-2';
plugin.serverless.service.serviceObject = {
name: 'new-service-2',
};
plugin.serverless.config.servicePath = '/path/to/service';
sinon.spy(plugin.serverless.cli, 'log');
return plugin.publishService().then(() => {
expect(getAuthTokenStub.calledOnce).to.be.equal(true);
expect(getAccountIdStub.calledOnce).to.be.equal(true);
expect(endpointsRequestStub.calledOnce).to.be.equal(true);
expect(publishServiceRequestStub.calledOnce).to.be.equal(true);
const expected = { name: 'new-service-2', stage: undefined, functions: [] };
expect(publishServiceRequestStub.getCall(0).args[0]).to.deep.equal(expected);
const expectedLog =
'Your service is available at https://platform.serverless.com/services/johndoe/new-service-2';
expect(plugin.serverless.cli.log.calledWithExactly(expectedLog)).to.be.equal(true);
});
});
it('should send a full service request to the platform', () => {
plugin.serverless.service.service = 'new-service-2';
plugin.serverless.service.serviceObject = {
name: 'new-service-2',
description: 'test description',
repository: 'https://example.com/repo',
homepage: 'https://example.com',
bugs: 'https://example.com/bugs',
license: 'MIT',
};
plugin.serverless.config.servicePath = '/path/to/service';
plugin.serverless.service.provider.name = 'aws';
plugin.serverless.service.functions = {
hello: {
handler: 'handler.hello',
description: 'test desc',
events: [{ http: { path: 'users/create', method: 'get', integration: 'AWS_PROXY' } }],
name: 'test-service2-dev-hello',
package: {},
vpc: {},
},
};
sinon.spy(plugin.serverless.cli, 'log');
return plugin.publishService().then(() => {
expect(getAuthTokenStub.calledOnce).to.be.equal(true);
expect(getAccountIdStub.calledOnce).to.be.equal(true);
expect(endpointsRequestStub.calledOnce).to.be.equal(true);
expect(publishServiceRequestStub.calledOnce).to.be.equal(true);
const expected = {
name: 'new-service-2',
stage: undefined,
repository: 'https://example.com/repo',
bugs: 'https://example.com/bugs',
description: 'test description',
functions: [
{
description: 'test desc',
endpoints: [
{
method: 'GET',
url: 'http://service-endpoint/users/create',
},
],
memory: 1024,
name: 'hello',
originId: 'arn:aws:lambda:us-east-1:acountId123:function:test-service2-dev-hello',
provider: 'aws',
runtime: 'nodejs4.3',
timeout: 6,
},
],
homepage: 'https://example.com',
license: 'MIT',
};
expect(publishServiceRequestStub.getCall(0).args[0]).to.deep.equal(expected);
const expectedLog =
'Your service is available at https://platform.serverless.com/services/johndoe/new-service-2';
expect(plugin.serverless.cli.log.calledWithExactly(expectedLog)).to.be.equal(true);
});
});
});
});