Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aws): add schema for alexaSkill #8290

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/deprecations.md
Expand Up @@ -6,6 +6,12 @@ layout: Doc

# Serverless Framework Deprecations

<a name="ALEXA_SKILL_EVENT_WITHOUT_APP_ID"><div>&nbsp;</div></a>

## Support for `alexaSkill` event without `appId` is to be removed

Starting with v3.0.0, support for `alexaSkill` event without `appId` provided will be removed.

<a name="RESOURCES_EXTENSIONS_REFERENCE_TO_NONEXISTENT_RESOURCE"><div>&nbsp;</div></a>

## Defining extensions to nonexistent resources in `resources.extensions`
Expand Down
42 changes: 17 additions & 25 deletions lib/plugins/aws/package/compile/events/alexaSkill/index.js
Expand Up @@ -11,9 +11,19 @@ class AwsCompileAlexaSkillEvents {
'package:compileEvents': this.compileAlexaSkillEvents.bind(this),
};

// TODO: Complete schema, see https://github.com/serverless/serverless/issues/8023
this.serverless.configSchemaHandler.defineFunctionEvent('aws', 'alexaSkill', {
anyOf: [{ type: 'string' }, { type: 'object' }],
anyOf: [
{ $ref: '#/definitions/awsAlexaEventToken' },
{
type: 'object',
properties: {
appId: { $ref: '#/definitions/awsAlexaEventToken' },
enabled: { type: 'boolean' },
},
required: ['appId'],
additionalProperties: false,
},
],
});
}

Expand All @@ -28,34 +38,16 @@ class AwsCompileAlexaSkillEvents {
let enabled = true;
let appId;
if (event === 'alexaSkill') {
const warningMessage = [
"Warning! You are using an old syntax for alexaSkill which doesn't",
' restrict the invocation solely to your skill.',
' Please refer to the documentation for additional information.',
].join('');
this.serverless.cli.log(warningMessage);
this.serverless._logDeprecation(
'ALEXA_SKILL_EVENT_WITHOUT_APP_ID',
'Starting with next major version, support for alexaSkill event without appId specified will be removed.'
);
} else if (typeof event.alexaSkill === 'string') {
appId = event.alexaSkill;
} else if (_.isPlainObject(event.alexaSkill)) {
if (typeof event.alexaSkill.appId !== 'string') {
const errorMessage = [
`Missing "appId" property for alexaSkill event in function ${functionName}`,
' The correct syntax is: appId: amzn1.ask.skill.xx-xx-xx-xx-xx',
' OR an object with "appId" property.',
' Please check the docs for more info.',
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
} else {
appId = event.alexaSkill.appId;
// Parameter `enabled` is optional, hence the explicit non-equal check for false.
enabled = event.alexaSkill.enabled !== false;
} else {
const errorMessage = [
`Alexa Skill event of function "${functionName}" is not an object or string.`,
' The correct syntax is: alexaSkill.',
' Please check the docs for more info.',
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
alexaSkillNumberInFunction++;

Expand Down
71 changes: 0 additions & 71 deletions lib/plugins/aws/package/compile/events/alexaSkill/index.test.js
Expand Up @@ -10,19 +10,11 @@ const Serverless = require('../../../../../../Serverless');
describe('AwsCompileAlexaSkillEvents', () => {
let serverless;
let awsCompileAlexaSkillEvents;
let consolePrinted;

beforeEach(() => {
serverless = new Serverless();
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
serverless.setProvider('aws', new AwsProvider(serverless));
consolePrinted = '';
serverless.cli = {
// serverless.cli isn't available in tests, so we will mimic it.
log: txt => {
consolePrinted += `${txt}\r\n`;
},
};
awsCompileAlexaSkillEvents = new AwsCompileAlexaSkillEvents(serverless);
});

Expand All @@ -35,69 +27,6 @@ describe('AwsCompileAlexaSkillEvents', () => {
});

describe('#compileAlexaSkillEvents()', () => {
it('should show a warning if alexaSkill appId is not specified', () => {
awsCompileAlexaSkillEvents.serverless.service.functions = {
first: {
events: ['alexaSkill'],
},
};

awsCompileAlexaSkillEvents.compileAlexaSkillEvents();

expect(consolePrinted).to.contain.string('old syntax for alexaSkill');

expect(
awsCompileAlexaSkillEvents.serverless.service.provider.compiledCloudFormationTemplate
.Resources.FirstLambdaPermissionAlexaSkill1.Type
).to.equal('AWS::Lambda::Permission');
expect(
awsCompileAlexaSkillEvents.serverless.service.provider.compiledCloudFormationTemplate
.Resources.FirstLambdaPermissionAlexaSkill1.Properties.FunctionName
).to.deep.equal({ 'Fn::GetAtt': ['FirstLambdaFunction', 'Arn'] });
expect(
awsCompileAlexaSkillEvents.serverless.service.provider.compiledCloudFormationTemplate
.Resources.FirstLambdaPermissionAlexaSkill1.Properties.Action
).to.equal('lambda:InvokeFunction');
expect(
awsCompileAlexaSkillEvents.serverless.service.provider.compiledCloudFormationTemplate
.Resources.FirstLambdaPermissionAlexaSkill1.Properties.Principal
).to.equal('alexa-appkit.amazon.com');
expect(
awsCompileAlexaSkillEvents.serverless.service.provider.compiledCloudFormationTemplate
.Resources.FirstLambdaPermissionAlexaSkill1.Properties.EventSourceToken
).to.be.undefined;
});

it('should throw an error if alexaSkill event is not a string or an object', () => {
awsCompileAlexaSkillEvents.serverless.service.functions = {
first: {
events: [
{
alexaSkill: 42,
},
],
},
};

expect(() => awsCompileAlexaSkillEvents.compileAlexaSkillEvents()).to.throw(Error);
});

it('should throw an error if alexaSkill event appId is not a string', () => {
awsCompileAlexaSkillEvents.serverless.service.functions = {
first: {
events: [
{
alexaSkill: {
appId: 42,
},
},
],
},
};

expect(() => awsCompileAlexaSkillEvents.compileAlexaSkillEvents()).to.throw(Error);
});

it('should create corresponding resources when multiple alexaSkill events are provided', () => {
const skillId1 = 'amzn1.ask.skill.xx-xx-xx-xx';
const skillId2 = 'amzn1.ask.skill.yy-yy-yy-yy';
Expand Down