Skip to content

Commit 2362e4f

Browse files
gabogEricDahlvang
andauthored
Skill Manifest 2.2 (#6321)
* Created v2.2 folder Updated some URI properties in skill manifest to accept URI-refences Added sample with relative URLs * Added missing files * Add validation for skill manifest examples against skill manifest schemas (#6325) * Add validation for 2.2 skill manifest * Add other skill schemas and manifest versions * Fixed 2.1 and 2.2 manifest validation errors Updated test to read files directly from the skills folder to make them easier to maintain. Updated tests to use NewtonSoft and NJSonSchema validations to provide better comat Co-authored-by: Gabo Gilabert <[email protected]> * Added titles * Fixed versions Co-authored-by: Eric Dahlvang <[email protected]>
1 parent 877a9a6 commit 2362e4f

20 files changed

+1252
-14
lines changed

.gitignore

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@
1212

1313
# Build results
1414
[Dd]ebug/
15+
[Dd]ebugPublic/
16+
[Rr]elease/
17+
[Rr]eleases/
18+
x64/
19+
x86/
20+
bld/
21+
[Bb]in/
22+
[Oo]bj/
23+
ecf/
24+
rcf/
1525

1626
bones/
1727
.vs/
1828
.vscode/
1929
.config/
2030

2131
# Python virtual environments
22-
**/*env/
32+
**/*env/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
6+
<IsPackable>false</IsPackable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
11+
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="16.10.56" />
12+
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" />
13+
<PackageReference Include="NJsonSchema" Version="10.4.4" />
14+
<PackageReference Include="xunit" Version="2.4.1" />
15+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
16+
<PrivateAssets>all</PrivateAssets>
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
</PackageReference>
19+
<PackageReference Include="coverlet.collector" Version="3.0.3">
20+
<PrivateAssets>all</PrivateAssets>
21+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
22+
</PackageReference>
23+
</ItemGroup>
24+
25+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31409.214
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SchemaManifestTests", "SchemaManifestTests.csproj", "{53609E6C-0C2C-4DB2-864C-628BE29495E4}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{53609E6C-0C2C-4DB2-864C-628BE29495E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{53609E6C-0C2C-4DB2-864C-628BE29495E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{53609E6C-0C2C-4DB2-864C-628BE29495E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{53609E6C-0C2C-4DB2-864C-628BE29495E4}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {DB082524-0CE2-4C94-BA0E-A9FFDBE8EE42}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Threading.Tasks;
7+
using Newtonsoft.Json.Linq;
8+
using Newtonsoft.Json.Schema;
9+
using NJsonSchema;
10+
using NJsonSchema.Generation;
11+
using Xunit;
12+
using JsonSchema = NJsonSchema.JsonSchema;
13+
using JsonSchemaResolver = NJsonSchema.Generation.JsonSchemaResolver;
14+
15+
namespace SchemaManifestTests
16+
{
17+
/// <summary>
18+
/// Validates sample manifests against schemas.
19+
/// </summary>
20+
/// <remarks>
21+
/// There are some differences on the validation provided by Newtonsoft and NJsonSchema so we use both libraries in the tests
22+
/// to ensure better compatibility.
23+
/// </remarks>
24+
public class ValidateSchemaTests
25+
{
26+
// List of schema version folders to test.
27+
private static readonly List<string> _schemaVersionFolders = new List<string>
28+
{
29+
"v2.0",
30+
"v2.1",
31+
"v2.2"
32+
};
33+
34+
// Path to the folder containing the schema files and samples (relative to where the test is executing).
35+
private static readonly string _schemasRootFolder = Path.Combine(Directory.GetCurrentDirectory(), "../../../../");
36+
37+
/// <summary>
38+
/// Builds the list of manifest schemas and samples to validate from the file system.
39+
/// </summary>
40+
public static TheoryData<string, string> GetManifestAndSamples()
41+
{
42+
var manifestAndSamples = new TheoryData<string, string>();
43+
44+
foreach (var schemaVersion in _schemaVersionFolders)
45+
{
46+
var schemaFolder = Path.Combine(_schemasRootFolder, schemaVersion);
47+
var samplesFolder = Path.Combine(schemaFolder, "Samples");
48+
var sampleManifestFiles = Directory.GetFileSystemEntries(samplesFolder, "*.json", SearchOption.AllDirectories);
49+
foreach (var manifestFile in sampleManifestFiles)
50+
{
51+
var manifestRelativePath = Path.GetRelativePath(schemaFolder, manifestFile);
52+
manifestAndSamples.Add(schemaVersion, manifestRelativePath);
53+
}
54+
}
55+
56+
return manifestAndSamples;
57+
}
58+
59+
[Theory]
60+
[MemberData(nameof(GetManifestAndSamples))]
61+
public async Task ValidateManifestSamplesAgainstSchemasUsingNJsonSchemaAsync(string schemaVersion, string sampleManifest)
62+
{
63+
// Arrange
64+
var manifestSchemaPath = Path.Combine(_schemasRootFolder, schemaVersion, "skill-manifest.json");
65+
var manifestSchema = await GetSchemaAsync(manifestSchemaPath);
66+
67+
var sampleManifestPath = Path.Combine(_schemasRootFolder, schemaVersion, sampleManifest);
68+
var sampleManifestText = await File.ReadAllTextAsync(sampleManifestPath);
69+
70+
// Act
71+
var validationErrors = manifestSchema.Validate(sampleManifestText);
72+
73+
// Assert
74+
Assert.Empty(validationErrors);
75+
}
76+
77+
[Theory]
78+
[MemberData(nameof(GetManifestAndSamples))]
79+
public async Task ValidateManifestSamplesAgainstSchemasUsingNewtonsoftSchemaAsync(string schemaVersion, string sampleManifest)
80+
{
81+
// Note: you can use https://www.jsonschemavalidator.net/ for an interactive version.
82+
83+
// Arrange
84+
var manifestSchemaPath = Path.Combine(_schemasRootFolder, schemaVersion, "skill-manifest.json");
85+
var manifestSchema = JSchema.Parse(await File.ReadAllTextAsync(manifestSchemaPath), new JSchemaUrlResolver());
86+
87+
var sampleManifestPath = Path.Combine(_schemasRootFolder, schemaVersion, sampleManifest);
88+
var json = JToken.Parse(await File.ReadAllTextAsync(sampleManifestPath));
89+
90+
// Act
91+
json.IsValid(manifestSchema, out IList<ValidationError> validationErrors);
92+
93+
// Assert
94+
Assert.Empty(validationErrors);
95+
}
96+
97+
private static async Task<JsonSchema> GetSchemaAsync(string schemaPath)
98+
{
99+
var rawSchemaText = await File.ReadAllTextAsync(schemaPath);
100+
101+
return await JsonSchema.FromJsonAsync(rawSchemaText, null, x =>
102+
{
103+
var schemaResolver = new JsonSchemaResolver(x, new JsonSchemaGeneratorSettings());
104+
var referenceResolver = new JsonReferenceResolver(schemaResolver);
105+
referenceResolver.AddDocumentReference("http://json-schema.org/draft-07/schema", JsonSchema.CreateAnySchema());
106+
107+
return referenceResolver;
108+
});
109+
}
110+
}
111+
}

schemas/skills/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The skill manifest JSON schema is published at:
1010

1111
Example:
1212

13-
`https://schemas.botframework.com/schemas/skills/v2.1/skill-manifest.json`
13+
`https://schemas.botframework.com/schemas/skills/v2.2/skill-manifest.json`
1414

1515
You should use the published version when referencing this schema.
1616

schemas/skills/v2.1/skill-manifest.json

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$id": "https://schemas.botframework.com/schemas/skills/v2.1/skill-manifest.json",
33
"$schema": "http://json-schema.org/draft-07/schema#",
4-
"$version": "2.1.0",
4+
"$version": "2.1.1",
55
"title": "Skill Manifest Schema",
66
"description": "A schema for Bot Framework skill manifests",
77
"type": "object",
@@ -206,8 +206,11 @@
206206
"properties": {
207207
"type": {
208208
"type": "string",
209+
"title": "Activity Type",
209210
"description": "The activity type",
210-
"const": "event"
211+
"enum": [
212+
"event"
213+
]
211214
},
212215
"name": {
213216
"type": "string",
@@ -245,8 +248,11 @@
245248
"properties": {
246249
"type": {
247250
"type": "string",
251+
"title": "Activity Type",
248252
"description": "The activity type",
249-
"const": "invoke"
253+
"enum": [
254+
"invoke"
255+
]
250256
},
251257
"name": {
252258
"type": "string",
@@ -284,8 +290,9 @@
284290
"type": {
285291
"type": "string",
286292
"description": "The activity type",
287-
"const": "message",
288-
"default": "message"
293+
"enum": [
294+
"message"
295+
]
289296
},
290297
"description": {
291298
"type": "string",
@@ -315,11 +322,8 @@
315322
"type": {
316323
"type": "string",
317324
"title": "Activity Type",
318-
"description": "Contains the activity type (message, event, invoke, etc.)",
325+
"description": "The activity type",
319326
"enum": [
320-
"message",
321-
"event",
322-
"invoke",
323327
"messageReaction",
324328
"endOfConversation",
325329
"handoff",
@@ -332,8 +336,7 @@
332336
"deleteUserData",
333337
"messageUpdate",
334338
"messageDelete"
335-
],
336-
"pattern":"^(?!(message|event|invoke)$)((messageReaction|endOfConversation|handoff|typing|conversationUpdate|trace|installationUpdate|contactRelationUpdate|suggestion|deleteUserData|messageUpdate|messageDelete)$)"
339+
]
337340
}
338341
},
339342
"additionalProperties": true
@@ -369,4 +372,4 @@
369372
"additionalProperties": false
370373
}
371374
}
372-
}
375+
}

0 commit comments

Comments
 (0)