Added VTFS webhooks project with basic modeling of payload
This commit is contained in:
Родитель
1a213d7b9c
Коммит
51b364553d
|
@ -8,6 +8,7 @@
|
|||
<Word>apis</Word>
|
||||
<Word>awaitable</Word>
|
||||
<Word>bitbucket</Word>
|
||||
<Word>changeset</Word>
|
||||
<Word>deployer</Word>
|
||||
<Word>dequeueing</Word>
|
||||
<Word>dequeues</Word>
|
||||
|
@ -17,12 +18,14 @@
|
|||
<Word>git</Word>
|
||||
<Word>instagram</Word>
|
||||
<Word>kudu</Word>
|
||||
<Word>kanban</Word>
|
||||
<Word>mvc</Word>
|
||||
<Word>nuget</Word>
|
||||
<Word>paypal</Word>
|
||||
<Word>salesforce</Word>
|
||||
<Word>trello</Word>
|
||||
<Word>ver</Word>
|
||||
<Word>vsts</Word>
|
||||
<Word>zapier</Word>
|
||||
<Word>zendesk</Word>
|
||||
<Word>你好</Word>
|
||||
|
@ -42,6 +45,7 @@
|
|||
<CasingExceptions>
|
||||
<Acronym>CRM</Acronym>
|
||||
<Acronym>SSO</Acronym>
|
||||
<Acronym>VSTS</Acronym>
|
||||
</CasingExceptions>
|
||||
</Acronyms>
|
||||
</Dictionary>
|
||||
|
|
29
WebHooks.sln
29
WebHooks.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Src", "Src", "{929F44D0-A040-4DC3-A22F-4C5829C05D44}"
|
||||
EndProject
|
||||
|
@ -152,6 +152,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.WebHooks.R
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.WebHooks.Receivers.Zendesk.Test", "test\Microsoft.AspNet.WebHooks.Receivers.Zendesk.Test\Microsoft.AspNet.WebHooks.Receivers.Zendesk.Test.csproj", "{D4AE6D4C-004F-4392-9EE1-772444719449}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.WebHooks.Receivers.VSTS", "src\Microsoft.AspNet.WebHooks.Receivers.VSTS\Microsoft.AspNet.WebHooks.Receivers.VSTS.csproj", "{6B501D55-2AA3-4757-A185-1277BB881DE8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.WebHooks.Receivers.VSTS.Test", "test\Microsoft.AspNet.WebHooks.Receivers.VSTS.Test\Microsoft.AspNet.WebHooks.Receivers.VSTS.Test.csproj", "{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VstsReceiver", "samples\VstsReceiver\VstsReceiver.csproj", "{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeAnalysis|Any CPU = CodeAnalysis|Any CPU
|
||||
|
@ -555,6 +561,24 @@ Global
|
|||
{D4AE6D4C-004F-4392-9EE1-772444719449}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D4AE6D4C-004F-4392-9EE1-772444719449}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D4AE6D4C-004F-4392-9EE1-772444719449}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}.CodeAnalysis|Any CPU.ActiveCfg = CodeAnalysis|Any CPU
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}.CodeAnalysis|Any CPU.Build.0 = CodeAnalysis|Any CPU
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}.CodeAnalysis|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}.CodeAnalysis|Any CPU.Build.0 = Release|Any CPU
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -626,6 +650,9 @@ Global
|
|||
{BD0AB018-7229-42BF-B607-5D46E9F1F2EA} = {E957C8D9-B4A0-488B-838F-BAB4DE080A76}
|
||||
{DCD550FB-FE5E-4684-AA52-C09FE5F8FDDA} = {929F44D0-A040-4DC3-A22F-4C5829C05D44}
|
||||
{D4AE6D4C-004F-4392-9EE1-772444719449} = {9575CB90-BC4B-43BB-8AEA-82C53FDA4187}
|
||||
{6B501D55-2AA3-4757-A185-1277BB881DE8} = {929F44D0-A040-4DC3-A22F-4C5829C05D44}
|
||||
{B27CC8B5-BF38-434B-B5CE-42ACEC40624C} = {9575CB90-BC4B-43BB-8AEA-82C53FDA4187}
|
||||
{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3} = {E957C8D9-B4A0-488B-838F-BAB4DE080A76}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8;packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
using System.Web.Http;
|
||||
|
||||
namespace VstsReceiver
|
||||
{
|
||||
public static class WebApiConfig
|
||||
{
|
||||
public static void Register(HttpConfiguration config)
|
||||
{
|
||||
// Web API configuration and services
|
||||
|
||||
// Web API routes
|
||||
config.MapHttpAttributeRoutes();
|
||||
|
||||
config.Routes.MapHttpRoute(
|
||||
name: "DefaultApi",
|
||||
routeTemplate: "api/{controller}/{id}",
|
||||
defaults: new { id = RouteParameter.Optional }
|
||||
);
|
||||
|
||||
// Initialize Vsts WebHook receiver
|
||||
config.InitializeReceiveVstsWebHooks();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<%@ Application Codebehind="Global.asax.cs" Inherits="VstsReceiver.WebApiApplication" Language="C#" %>
|
|
@ -0,0 +1,12 @@
|
|||
using System.Web.Http;
|
||||
|
||||
namespace VstsReceiver
|
||||
{
|
||||
public class WebApiApplication : System.Web.HttpApplication
|
||||
{
|
||||
protected void Application_Start()
|
||||
{
|
||||
GlobalConfiguration.Configure(WebApiConfig.Register);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("VstsReceivers")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("VststReceivers")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3f9f62dd-c365-4fec-a10e-5314d111ebf5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{88FB9535-BBC9-48FE-AC34-4C3E9A4073F3}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VstsReceiver</RootNamespace>
|
||||
<AssemblyName>VstsReceiver</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNet.WebHooks.Receivers.VSTS">
|
||||
<HintPath>..\..\bin\CodeAnalysis\Microsoft.AspNet.WebHooks.Receivers.VSTS.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
<Reference Include="System.Web.Entity" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http.WebHost, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.2\lib\net45\System.Web.Http.WebHost.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Web.Services" />
|
||||
<Reference Include="System.EnterpriseServices" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Global.asax" />
|
||||
<Content Include="index.html" />
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App_Start\WebApiConfig.cs" />
|
||||
<Compile Include="Global.asax.cs">
|
||||
<DependentUpon>Global.asax</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WebHooks\VstsWebHookHandler.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="packages.config" />
|
||||
<None Include="Web.Debug.config">
|
||||
<DependentUpon>Web.config</DependentUpon>
|
||||
</None>
|
||||
<None Include="Web.Release.config">
|
||||
<DependentUpon>Web.config</DependentUpon>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Src\Microsoft.AspNet.WebHooks.Common\Microsoft.AspNet.WebHooks.Common.csproj">
|
||||
<Project>{f7dd0935-6320-4efc-9464-d5a2d2b8c2f7}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Src\Microsoft.AspNet.WebHooks.Receivers\Microsoft.AspNet.WebHooks.Receivers.csproj">
|
||||
<Project>{8ced31fb-32f2-4ffb-9997-452fb9728577}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Receivers</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>15572</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:50009</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--
|
||||
In the example below, the "SetAttributes" transform will change the value of
|
||||
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
|
||||
finds an attribute "name" that has a value of "MyDB".
|
||||
|
||||
<connectionStrings>
|
||||
<add name="MyDB"
|
||||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
|
||||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
|
||||
</connectionStrings>
|
||||
-->
|
||||
<system.web>
|
||||
<!--
|
||||
In the example below, the "Replace" transform will replace the entire
|
||||
<customErrors> section of your web.config file.
|
||||
Note that because there is only one customErrors section under the
|
||||
<system.web> node, there is no need to use the "xdt:Locator" attribute.
|
||||
|
||||
<customErrors defaultRedirect="GenericError.htm"
|
||||
mode="RemoteOnly" xdt:Transform="Replace">
|
||||
<error statusCode="500" redirect="InternalError.htm"/>
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--
|
||||
In the example below, the "SetAttributes" transform will change the value of
|
||||
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
|
||||
finds an attribute "name" that has a value of "MyDB".
|
||||
|
||||
<connectionStrings>
|
||||
<add name="MyDB"
|
||||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
|
||||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
|
||||
</connectionStrings>
|
||||
-->
|
||||
<system.web>
|
||||
<compilation xdt:Transform="RemoveAttributes(debug)" />
|
||||
<!--
|
||||
In the example below, the "Replace" transform will replace the entire
|
||||
<customErrors> section of your web.config file.
|
||||
Note that because there is only one customErrors section under the
|
||||
<system.web> node, there is no need to use the "xdt:Locator" attribute.
|
||||
|
||||
<customErrors defaultRedirect="GenericError.htm"
|
||||
mode="RemoteOnly" xdt:Transform="Replace">
|
||||
<error statusCode="500" redirect="InternalError.htm"/>
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
For more information on how to configure your ASP.NET application, please visit
|
||||
http://go.microsoft.com/fwlink/?LinkId=301879
|
||||
-->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="MS_WebHookReceiverSecret_VSTS" value="83699ec7c1d794c0c780e49a5c72972590571fd8"/>
|
||||
</appSettings>
|
||||
<!--
|
||||
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
|
||||
|
||||
The following attributes can be set on the <httpRuntime> tag.
|
||||
<system.Web>
|
||||
<httpRuntime targetFramework="4.5.1" />
|
||||
</system.Web>
|
||||
-->
|
||||
<system.web>
|
||||
<compilation debug="true" targetFramework="4.5.1"/>
|
||||
<httpRuntime targetFramework="4.5.1"/>
|
||||
</system.web>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-5.2.2.0" newVersion="5.2.2.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
|
||||
<remove name="OPTIONSVerbHandler"/>
|
||||
<remove name="TRACEVerbHandler"/>
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -0,0 +1,95 @@
|
|||
using Microsoft.AspNet.WebHooks;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VstsReceiver.WebHooks
|
||||
{
|
||||
/// <summary>
|
||||
/// This handler processes WebHooks from Visual Studio Team Services and leverages the <see cref="VstsWebHookHandlerBase"/> base handler.
|
||||
/// For details about Visual Studio Team Services WebHooks, see <c>https://www.visualstudio.com/en-us/get-started/integrate/service-hooks/webhooks-and-vso-vs</c>.
|
||||
/// </summary>
|
||||
public class VstsWebHookHandler : VstsWebHookHandlerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="BuildCompletedPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, BuildCompletedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="TeamRoomMessagePostedPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, TeamRoomMessagePostedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="WorkItemCreatedPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, WorkItemCreatedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="WorkItemCommentedOnPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, WorkItemCommentedOnPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="CodeCheckedInPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, CodeCheckedInPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="WorkItemDeletedPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, WorkItemDeletedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="WorkItemRestoredPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, WorkItemRestoredPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the <see cref="WorkItemUpdatedPayload"/> WebHook.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, WorkItemUpdatedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We use <see cref="VstsWebHookHandlerBase"/> so just have to override the methods we want to process WebHooks for.
|
||||
/// This one processes the payload for unknown <c>eventType</c>.
|
||||
/// </summary>
|
||||
public override Task ExecuteAsync(WebHookHandlerContext context, JObject payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Microsoft ASP.NET WebHooks Visual Studio Team Services Receiver</title>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Microsoft ASP.NET WebHooks Visual Studio Team Services Receiver</h1>
|
||||
|
||||
<p>
|
||||
The VSTS WebHook Receiver provides support for receiving WebHooks from Visual Studio Team Services. A sample WebHook URI is:</p>
|
||||
|
||||
<pre>https://<host>/api/webhooks/incoming/vsts?code=83699ec7c1d794c0c780e49a5c72972590571fd8</pre>
|
||||
|
||||
<p>
|
||||
For security reasons the WebHook URI must be an <c>https</c> URI and contain a 'code' query parameter with the
|
||||
same value as configured in the <b>MS_WebHookReceiverSecret_VSTS</b> application setting.
|
||||
The 'code' parameter must be between 32 and 128 characters long. Optionally you can use IDs
|
||||
to differentiate between multiple WebHooks, for example '<c>code0, id1=code1, id2=code2</c>'.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Please see <a href="https://www.visualstudio.com/en-us/get-started/integrate/service-hooks/webhooks-and-vso-vs">Visual Studio Team Services WebHooks</a>
|
||||
for more information.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.AspNet.WebApi" version="5.2.2" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.2" targetFramework="net452" />
|
||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.0" targetFramework="net452" />
|
||||
<package id="Microsoft.Net.Compilers" version="1.0.0" targetFramework="net452" developmentDependency="true" />
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
|
||||
</packages>
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using Microsoft.AspNet.WebHooks.Config;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="HttpConfiguration"/>.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class HttpConfigurationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes support for receiving WebHooks generated by Visual Studio Team Services.
|
||||
///
|
||||
/// A sample WebHook URI is '<c>https://<host>/api/webhooks/incoming/vsts/{id}?code={code}</c>'.
|
||||
/// For security reasons the WebHook URI must be an <c>https</c> URI and contain a 'code' query parameter with the
|
||||
/// same value as configured in the '<c>MS_WebHookReceiverSecret_Tfs</c>' application setting, optionally using IDs
|
||||
/// to differentiate between multiple WebHooks, for example '<c>secret0, id1=secret1, id2=secret2</c>'.
|
||||
/// The 'code' parameter must be between 32 and 128 characters long.
|
||||
/// </summary>
|
||||
/// <param name="config">The current <see cref="HttpConfiguration"/>config.</param>
|
||||
public static void InitializeReceiveVstsWebHooks(this HttpConfiguration config)
|
||||
{
|
||||
WebHooksConfig.Initialize(config);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Microsoft.AspNet.WebHooks.Properties;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base <see cref="IWebHookHandler" /> implementation which can be used to for handling Visual Studio Team Services WebHook
|
||||
/// using strongly-typed payloads. For details about MyGet WebHooks, see <c>https://www.visualstudio.com/en-us/get-started/integrate/service-hooks/webhooks-and-vso-vs</c>.
|
||||
/// </summary>
|
||||
public abstract class VstsWebHookHandlerBase : WebHookHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VstsWebHookHandlerBase"/> class.
|
||||
/// </summary>
|
||||
protected VstsWebHookHandlerBase()
|
||||
{
|
||||
this.Receiver = VstsWebHookReceiver.ReceiverName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ExecuteAsync(string receiver, WebHookHandlerContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
string action = context.Actions.First();
|
||||
JObject data = context.GetDataOrDefault<JObject>();
|
||||
|
||||
// map eventType to corresponding payload
|
||||
switch (action)
|
||||
{
|
||||
case "workitem.updated": return ExecuteAsync(context, data.ToObject<WorkItemUpdatedPayload>());
|
||||
case "workitem.restored": return ExecuteAsync(context, data.ToObject<WorkItemRestoredPayload>());
|
||||
case "workitem.deleted": return ExecuteAsync(context, data.ToObject<WorkItemDeletedPayload>());
|
||||
case "workitem.created": return ExecuteAsync(context, data.ToObject<WorkItemCreatedPayload>());
|
||||
case "workitem.commented": return ExecuteAsync(context, data.ToObject<WorkItemCommentedOnPayload>());
|
||||
case "message.posted": return ExecuteAsync(context, data.ToObject<TeamRoomMessagePostedPayload>());
|
||||
case "tfvc.checkin": return ExecuteAsync(context, data.ToObject<CodeCheckedInPayload>());
|
||||
case "build.complete": return ExecuteAsync(context, data.ToObject<BuildCompletedPayload>());
|
||||
default:
|
||||
string msg = string.Format(CultureInfo.CurrentCulture, VstsReceiverResources.Handler_NonMappedEventType, action);
|
||||
context.RequestContext.Configuration.DependencyResolver.GetLogger().Warn(msg);
|
||||
return ExecuteAsync(context, data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>workitem.updated</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, WorkItemUpdatedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>workitem.restored</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, WorkItemRestoredPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>workitem.deleted</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, WorkItemDeletedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>workitem.created</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, WorkItemCreatedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>workitem.commented</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, WorkItemCommentedOnPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>message.posted</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, TeamRoomMessagePostedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>tfvc.checkin</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, CodeCheckedInPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for event '<c>build.complete</c>'.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">Strong-typed WebHook payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, BuildCompletedPayload payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the incoming WebHook request for unknown event.
|
||||
/// </summary>
|
||||
/// <param name="context">Provides context for the <see cref="IWebHookHandler"/> for further processing the incoming WebHook.</param>
|
||||
/// <param name="payload">JSON payload.</param>
|
||||
public virtual Task ExecuteAsync(WebHookHandlerContext context, JObject payload)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),WebHooks.sln))\tools\WebHooks.settings.targets" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{6B501D55-2AA3-4757-A185-1277BB881DE8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.AspNet.WebHooks</RootNamespace>
|
||||
<AssemblyName>Microsoft.AspNet.WebHooks.Receivers.VSTS</AssemblyName>
|
||||
<DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile>
|
||||
<RunCodeAnalysis>$(CodeAnalysis)</RunCodeAnalysis>
|
||||
<CodeAnalysisAdditionalOptions>/assemblyCompareMode:StrongNameIgnoringVersion</CodeAnalysisAdditionalOptions>
|
||||
<CodeAnalysisRuleSet>..\..\FxCop.ruleset</CodeAnalysisRuleSet>
|
||||
<DefineConstants>$(DefineConstants);ASPNETWEBHOOKS</DefineConstants>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<NuGetPackageImportStamp>b718ef60</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common\CommonAssemblyInfo.cs">
|
||||
<Link>Properties\CommonAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Extensions\HttpConfigurationExtensions.cs" />
|
||||
<Compile Include="Handlers\VstsWebHookHandlerBase.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedDefinition.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedDrop.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedLog.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedQueueDefinition.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedRequest.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedResource.cs" />
|
||||
<Compile Include="Payloads\CodeCheckedInResource.cs" />
|
||||
<Compile Include="Payloads\PayloadMessage.cs" />
|
||||
<Compile Include="Payloads\PayloadResourceContainer.cs" />
|
||||
<Compile Include="Payloads\PayloadResourceContainers.cs" />
|
||||
<Compile Include="Payloads\TeamRoomMessagePostedResource.cs" />
|
||||
<Compile Include="Payloads\WorkItemCommentedOnResource.cs" />
|
||||
<Compile Include="Payloads\WorkItemCreatedResource.cs" />
|
||||
<Compile Include="Payloads\WorkItemDeletedResource.cs" />
|
||||
<Compile Include="Payloads\WorkItemFields.cs" />
|
||||
<Compile Include="Payloads\WorkItemLink.cs" />
|
||||
<Compile Include="Payloads\WorkItemLinks.cs" />
|
||||
<Compile Include="Payloads\WorkItemRestoredResource.cs" />
|
||||
<Compile Include="Payloads\WorkItemUpdatedFieldValue.cs" />
|
||||
<Compile Include="Payloads\WorkItemUpdatedRevision.cs" />
|
||||
<Compile Include="Payloads\WorkItemUpdatedFields.cs" />
|
||||
<Compile Include="Payloads\WorkItemUpdatedResource.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\VstsReceiverResources.Designer.cs">
|
||||
<DependentUpon>VstsReceiverResources.resx</DependentUpon>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="Payloads\BuildCompletedPayload.cs" />
|
||||
<Compile Include="Payloads\CodeCheckedInPayload.cs" />
|
||||
<Compile Include="Payloads\TeamRoomMessagePostedPayload.cs" />
|
||||
<Compile Include="Payloads\BasePayload.cs" />
|
||||
<Compile Include="Payloads\BaseResource.cs" />
|
||||
<Compile Include="Payloads\BaseWorkItemResource.cs" />
|
||||
<Compile Include="Payloads\ResourceUser.cs" />
|
||||
<Compile Include="Payloads\WorkItemCommentedOnPayload.cs" />
|
||||
<Compile Include="Payloads\WorkItemCreatedPayload.cs" />
|
||||
<Compile Include="Payloads\WorkItemRestoredPayload.cs" />
|
||||
<Compile Include="Payloads\WorkItemUpdatedPayload.cs" />
|
||||
<Compile Include="Payloads\WorkItemDeletedPayload.cs" />
|
||||
<Compile Include="WebHooks\VstsWebHookReceiver.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Microsoft.AspNet.WebHooks.Receivers.VSTS.nuspec">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNet.WebHooks.Common\Microsoft.AspNet.WebHooks.Common.csproj">
|
||||
<Project>{f7dd0935-6320-4efc-9464-d5a2d2b8c2f7}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.AspNet.WebHooks.Receivers\Microsoft.AspNet.WebHooks.Receivers.csproj">
|
||||
<Project>{8CED31FB-32F2-4FFB-9997-452FB9728577}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Receivers</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDictionary Include="..\..\CustomDictionary.xml">
|
||||
<Link>CustomDictionary.xml</Link>
|
||||
<SubType>Designer</SubType>
|
||||
</CodeAnalysisDictionary>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\VstsReceiverResources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>VstsReceiverResources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets" Condition="Exists('..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$symversion$</version>
|
||||
<title>Microsoft ASP.NET WebHooks Receiver for Visual Studio Team Services</title>
|
||||
<authors>Microsoft</authors>
|
||||
<owners>Microsoft, aspnet</owners>
|
||||
<licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
||||
<projectUrl>http://go.microsoft.com/fwlink/?LinkId=690277</projectUrl>
|
||||
<iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<description>
|
||||
This package provides support for receiving WebHooks from Visual Studio Team Services. For information about Visual Studio Team Services WebHooks, see "https://www.visualstudio.com/en-us/get-started/integrate/service-hooks/webhooks-and-vso-vs".
|
||||
</description>
|
||||
<releaseNotes></releaseNotes>
|
||||
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
||||
<tags>Microsoft AspNet WebApi AspNetWebApi WebHooks TFS VSTS Visual Studio Team Services</tags>
|
||||
</metadata>
|
||||
</package>
|
|
@ -0,0 +1,81 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Root object of payload sent for all types of events.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of resource within payload which differs depending on '<c>eventType</c>' field</typeparam>
|
||||
public abstract class BasePayload<T> where T : BaseResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the subscription identifier which triggered the event.
|
||||
/// </summary>
|
||||
[JsonProperty("subscriptionId")]
|
||||
public string SubscriptionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the notification identifier within subscription.
|
||||
/// </summary>
|
||||
[JsonProperty("notificationId")]
|
||||
public int NotificationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifier of HTTP request.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the event.
|
||||
/// </summary>
|
||||
[JsonProperty("eventType")]
|
||||
public string EventType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the publisher identifier.
|
||||
/// </summary>
|
||||
[JsonProperty("publisherId")]
|
||||
public string PublisherId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message which describes the event.
|
||||
/// </summary>
|
||||
[JsonProperty("message")]
|
||||
public PayloadMessage Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the detailed message which describes the event.
|
||||
/// </summary>
|
||||
[JsonProperty("detailedMessage")]
|
||||
public PayloadMessage DetailedMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource itself - data associated with corresponding event.
|
||||
/// </summary>
|
||||
[JsonProperty("resource")]
|
||||
public T Resource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource version.
|
||||
/// </summary>
|
||||
[JsonProperty("resourceVersion")]
|
||||
public string ResourceVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource containers.
|
||||
/// </summary>
|
||||
[JsonProperty("resourceContainers")]
|
||||
public PayloadResourceContainers ResourceContainers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date when HTTP request was created.
|
||||
/// </summary>
|
||||
[JsonProperty("createdDate")]
|
||||
public DateTime CreatedDate { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for resource object which describes
|
||||
/// a specific event type.
|
||||
/// </summary>
|
||||
public abstract class BaseResource
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for resource object which describes WorkItem event types.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type which describes fields associated with this kind of WorkItem change</typeparam>
|
||||
public abstract class BaseWorkItemResource<T> : BaseResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier of WorkItem.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revision number.
|
||||
/// </summary>
|
||||
[JsonProperty("rev")]
|
||||
public int RevisionNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets fields associated with the WorkItem.
|
||||
/// </summary>
|
||||
[JsonProperty("fields")]
|
||||
public T Fields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets links associated with the WorkItem.
|
||||
/// </summary>
|
||||
[JsonProperty("_links")]
|
||||
public WorkItemLinks Links { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL of the WorkItem.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes build definition
|
||||
/// </summary>
|
||||
public class BuildCompletedDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the size of the batch.
|
||||
/// </summary>
|
||||
[JsonProperty("batchSize")]
|
||||
public int BatchSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trigger type.
|
||||
/// </summary>
|
||||
[JsonProperty("triggerType")]
|
||||
public string TriggerType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trigger type.
|
||||
/// </summary>
|
||||
[JsonProperty("definitionType")]
|
||||
public string DefinitionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifier of the build definition.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the build definition.
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL of the build definition.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes build drop
|
||||
/// </summary>
|
||||
public class BuildCompletedDrop
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets drop location.
|
||||
/// </summary>
|
||||
[JsonProperty("location")]
|
||||
public string Location { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets drop type.
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
public string DropType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets drop location URL.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets drop location download URL.
|
||||
/// </summary>
|
||||
[JsonProperty("downloadUrl")]
|
||||
public Uri DownloadUrl { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes build log
|
||||
/// </summary>
|
||||
public class BuildCompletedLog
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the log type.
|
||||
/// </summary>
|
||||
[JsonProperty("type")]
|
||||
public string LogType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the log URL.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the log download URL.
|
||||
/// </summary>
|
||||
[JsonProperty("downloadUrl")]
|
||||
public Uri DownloadUrl { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>build.complete</c>'.
|
||||
/// </summary>
|
||||
public class BuildCompletedPayload : BasePayload<BuildCompletedResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the queue of the build.
|
||||
/// </summary>
|
||||
public class BuildCompletedQueueDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type of the queue.
|
||||
/// </summary>
|
||||
[JsonProperty("queueType")]
|
||||
public string QueueType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifier of the queue.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the queue.
|
||||
/// </summary>
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL of the queue.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the request of the build.
|
||||
/// </summary>
|
||||
public class BuildCompletedRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier of the request.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL of the request.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user associated with the request.
|
||||
/// </summary>
|
||||
[JsonProperty("requestedFor")]
|
||||
public ResourceUser RequestedFor { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="BuildCompletedPayload"/>
|
||||
/// </summary>
|
||||
public class BuildCompletedResource : BaseResource
|
||||
{
|
||||
private readonly Collection<BuildCompletedRequest> _requests = new Collection<BuildCompletedRequest>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build URI.
|
||||
/// </summary>
|
||||
[JsonProperty("uri")]
|
||||
public Uri Uri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build identifier.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build number.
|
||||
/// </summary>
|
||||
[JsonProperty("buildNumber")]
|
||||
public string BuildNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build URL.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the start time of the build.
|
||||
/// </summary>
|
||||
[JsonProperty("startTime")]
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the finish time of the build.
|
||||
/// </summary>
|
||||
[JsonProperty("finishTime")]
|
||||
public DateTime FinishTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reason which triggered the build.
|
||||
/// </summary>
|
||||
[JsonProperty("reason")]
|
||||
public string Reason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the outcome status of the build.
|
||||
/// </summary>
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build drop location.
|
||||
/// </summary>
|
||||
[JsonProperty("dropLocation")]
|
||||
public string DropLocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build drop.
|
||||
/// </summary>
|
||||
[JsonProperty("drop")]
|
||||
public BuildCompletedDrop Drop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build log.
|
||||
/// </summary>
|
||||
[JsonProperty("log")]
|
||||
public BuildCompletedLog Log { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source version for the build.
|
||||
/// </summary>
|
||||
[JsonProperty("sourceGetVersion")]
|
||||
public string SourceGetVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user which last changed the source.
|
||||
/// </summary>
|
||||
[JsonProperty("lastChangedBy")]
|
||||
public ResourceUser LastChangedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets value indicating whether this build retain indefinitely.
|
||||
/// </summary>
|
||||
[JsonProperty("retainIndefinitely")]
|
||||
public bool RetainIndefinitely { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets value indicating whether this build has diagnostics.
|
||||
/// </summary>
|
||||
[JsonProperty("hasDiagnostics")]
|
||||
public bool HasDiagnostics { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the definition of the build.
|
||||
/// </summary>
|
||||
[JsonProperty("definition")]
|
||||
public BuildCompletedDefinition Definition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build queue.
|
||||
/// </summary>
|
||||
[JsonProperty("queue")]
|
||||
public BuildCompletedQueueDefinition Queue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets build requests.
|
||||
/// </summary>
|
||||
[JsonProperty("requests")]
|
||||
public Collection<BuildCompletedRequest> Requests
|
||||
{
|
||||
get { return _requests; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>tfvc.checkin</c>'.
|
||||
/// </summary>
|
||||
public class CodeCheckedInPayload : BasePayload<CodeCheckedInResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="CodeCheckedInPayload"/>
|
||||
/// </summary>
|
||||
public class CodeCheckedInResource : BaseResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the changeset identifier.
|
||||
/// </summary>
|
||||
[JsonProperty("changesetId")]
|
||||
public int ChangesetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the changeset URL.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the changeset author.
|
||||
/// </summary>
|
||||
[JsonProperty("author")]
|
||||
public ResourceUser Author { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that checked in the changeset.
|
||||
/// </summary>
|
||||
[JsonProperty("checkedInBy")]
|
||||
public ResourceUser CheckedInBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the changeset creation date.
|
||||
/// </summary>
|
||||
[JsonProperty("createdDate")]
|
||||
public DateTime CreatedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the changeset comment.
|
||||
/// </summary>
|
||||
[JsonProperty("comment")]
|
||||
public string Comment { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes payload message.
|
||||
/// </summary>
|
||||
public class PayloadMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the message in plain text.
|
||||
/// </summary>
|
||||
[JsonProperty("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message in HTML format.
|
||||
/// </summary>
|
||||
[JsonProperty("html")]
|
||||
public string Html { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the message in markdown format.
|
||||
/// </summary>
|
||||
[JsonProperty("markdown")]
|
||||
public string Markdown { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes container
|
||||
/// </summary>
|
||||
public class PayloadResourceContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier of container.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes containers containing the resource
|
||||
/// </summary>
|
||||
public class PayloadResourceContainers
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the collection.
|
||||
/// </summary>
|
||||
[JsonProperty("collection")]
|
||||
public PayloadResourceContainer Collection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the account.
|
||||
/// </summary>
|
||||
[JsonProperty("account")]
|
||||
public PayloadResourceContainer Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the project.
|
||||
/// </summary>
|
||||
[JsonProperty("project")]
|
||||
public PayloadResourceContainer Project { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes user entity
|
||||
/// </summary>
|
||||
public class ResourceUser
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier of the user.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user display name.
|
||||
/// </summary>
|
||||
[JsonProperty("displayName")]
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user unique name.
|
||||
/// </summary>
|
||||
[JsonProperty("uniqueName")]
|
||||
public string UniqueName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user URL.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user image URL.
|
||||
/// </summary>
|
||||
[JsonProperty("imageUrl")]
|
||||
public Uri ImageUrl { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>message.posted</c>'.
|
||||
/// </summary>
|
||||
public class TeamRoomMessagePostedPayload : BasePayload<TeamRoomMessagePostedResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="TeamRoomMessagePostedPayload"/>
|
||||
/// </summary>
|
||||
public class TeamRoomMessagePostedResource : BaseResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content of the message.
|
||||
/// </summary>
|
||||
[JsonProperty("content")]
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the message.
|
||||
/// </summary>
|
||||
[JsonProperty("messageType")]
|
||||
public string MessageType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the posted time of the message.
|
||||
/// </summary>
|
||||
[JsonProperty("postedTime")]
|
||||
public DateTime PostedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the room identifier where message was posted.
|
||||
/// </summary>
|
||||
[JsonProperty("postedRoomId")]
|
||||
public int PostedRoomId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user who posted the message.
|
||||
/// </summary>
|
||||
[JsonProperty("postedBy")]
|
||||
public ResourceUser PostedBy { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>workitem.commented</c>'.
|
||||
/// </summary>
|
||||
public class WorkItemCommentedOnPayload : BasePayload<WorkItemCommentedOnResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="WorkItemCommentedOnPayload"/>
|
||||
/// </summary>
|
||||
public class WorkItemCommentedOnResource : BaseWorkItemResource<WorkItemFields>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>workitem.created</c>'.
|
||||
/// </summary>
|
||||
public class WorkItemCreatedPayload : BasePayload<WorkItemCreatedResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="WorkItemCreatedPayload"/>
|
||||
/// </summary>
|
||||
public class WorkItemCreatedResource : BaseWorkItemResource<WorkItemFields>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>workitem.deleted</c>'.
|
||||
/// </summary>
|
||||
public class WorkItemDeletedPayload : BasePayload<WorkItemDeletedResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="WorkItemDeletedPayload"/>
|
||||
/// </summary>
|
||||
public class WorkItemDeletedResource : BaseWorkItemResource<WorkItemFields>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes fields of the WorkItem
|
||||
/// </summary>
|
||||
public class WorkItemFields
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.AreaPath</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.AreaPath")]
|
||||
public string SystemAreaPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.TeamProject</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.TeamProject")]
|
||||
public string SystemTeamProject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.IterationPath</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.IterationPath")]
|
||||
public string SystemIterationPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.WorkItemType</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.WorkItemType")]
|
||||
public string SystemWorkItemType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.State</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.State")]
|
||||
public string SystemState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.Reason</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.Reason")]
|
||||
public string SystemReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.CreatedDate</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.CreatedDate")]
|
||||
public DateTime SystemCreatedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.CreatedBy</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.CreatedBy")]
|
||||
public string SystemCreatedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.ChangedDate</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.ChangedDate")]
|
||||
public DateTime SystemChangedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.ChangedBy</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.ChangedBy")]
|
||||
public string SystemChangedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.Title</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.Title")]
|
||||
public string SystemTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>Microsoft.VSTS.Common.Severity</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("Microsoft.VSTS.Common.Severity")]
|
||||
public string MicrosoftCommonSeverity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column")]
|
||||
public string KanbanColumn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of field <c>System.History</c>.
|
||||
/// </summary>
|
||||
[JsonProperty("System.History")]
|
||||
public string SystemHistory { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the WorkItem's link.
|
||||
/// </summary>
|
||||
public class WorkItemLink
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the URL of WorkItem's link.
|
||||
/// </summary>
|
||||
[JsonProperty("href")]
|
||||
public string Href { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes links of the WorkItem.
|
||||
/// </summary>
|
||||
public class WorkItemLinks
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem itself.
|
||||
/// </summary>
|
||||
[JsonProperty("self")]
|
||||
public WorkItemLink Self { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the parent WorkItem if exists.
|
||||
/// </summary>
|
||||
[JsonProperty("parent")]
|
||||
public WorkItemLink Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem' updates.
|
||||
/// </summary>
|
||||
[JsonProperty("workItemUpdates")]
|
||||
public WorkItemLink WorkItemUpdates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem's revisions.
|
||||
/// </summary>
|
||||
[JsonProperty("workItemRevisions")]
|
||||
public WorkItemLink WorkItemRevisions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem's type.
|
||||
/// </summary>
|
||||
[JsonProperty("workItemType")]
|
||||
public WorkItemLink WorkItemType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem's fields.
|
||||
/// </summary>
|
||||
[JsonProperty("fields")]
|
||||
public WorkItemLink Fields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem's HTML.
|
||||
/// </summary>
|
||||
[JsonProperty("html")]
|
||||
public WorkItemLink Html { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link to the WorkItem's history.
|
||||
/// </summary>
|
||||
[JsonProperty("workItemHistory")]
|
||||
public WorkItemLink WorkItemHistory { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>workitem.restored</c>'.
|
||||
/// </summary>
|
||||
public class WorkItemRestoredPayload : BasePayload<WorkItemRestoredResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="WorkItemRestoredPayload"/>
|
||||
/// </summary>
|
||||
public class WorkItemRestoredResource : BaseWorkItemResource<WorkItemFields>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes change of specific field
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The string-type of the field that is being changed</typeparam>
|
||||
public class WorkItemUpdatedFieldValue<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value of the field before the change.
|
||||
/// </summary>
|
||||
[JsonProperty("oldValue")]
|
||||
public T OldValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the field after the change.
|
||||
/// </summary>
|
||||
[JsonProperty("newValue")]
|
||||
public T NewValue { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes fields of the WorkItem that was updated
|
||||
/// </summary>
|
||||
public class WorkItemUpdatedFields
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.Rev</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.Rev")]
|
||||
public WorkItemUpdatedFieldValue<string> SystemRev { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.AuthorizedDate</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.AuthorizedDate")]
|
||||
public WorkItemUpdatedFieldValue<DateTime> SystemAuthorizedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.RevisedDate</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.RevisedDate")]
|
||||
public WorkItemUpdatedFieldValue<DateTime> SystemRevisedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.State</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.State")]
|
||||
public WorkItemUpdatedFieldValue<string> SystemState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.Reason</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.Reason")]
|
||||
public WorkItemUpdatedFieldValue<string> SystemReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.AssignedTo</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.AssignedTo")]
|
||||
public WorkItemUpdatedFieldValue<string> SystemAssignedTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.ChangedDate</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.ChangedDate")]
|
||||
public WorkItemUpdatedFieldValue<DateTime> SystemChangedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>System.Watermark</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("System.Watermark")]
|
||||
public WorkItemUpdatedFieldValue<string> SystemWatermark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change information for the field '<c>Microsoft.VSTS.Common.Severity</c>'.
|
||||
/// </summary>
|
||||
[JsonProperty("Microsoft.Vsts.Common.Severity")]
|
||||
public WorkItemUpdatedFieldValue<string> MicrosoftCommonSeverity { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the entire payload of event '<c>workitem.updated</c>'.
|
||||
/// </summary>
|
||||
public class WorkItemUpdatedPayload : BasePayload<WorkItemUpdatedResource>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the resource that associated with <see cref="WorkItemUpdatedPayload"/>
|
||||
/// </summary>
|
||||
public class WorkItemUpdatedResource : BaseWorkItemResource<WorkItemUpdatedFields>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets WorkItem identifier.
|
||||
/// </summary>
|
||||
[JsonProperty("workItemId")]
|
||||
public int WorkItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the author of revision.
|
||||
/// </summary>
|
||||
[JsonProperty("revisedBy")]
|
||||
public ResourceUser RevisedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revised date.
|
||||
/// </summary>
|
||||
[JsonProperty("revisedDate")]
|
||||
public DateTime RevisedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revision.
|
||||
/// </summary>
|
||||
[JsonProperty("revision")]
|
||||
public WorkItemUpdatedRevision Revision { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Payloads
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the revision
|
||||
/// </summary>
|
||||
public class WorkItemUpdatedRevision
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the identifier of the revision.
|
||||
/// </summary>
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revision number.
|
||||
/// </summary>
|
||||
[JsonProperty("rev")]
|
||||
public int Rev { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revision fields.
|
||||
/// </summary>
|
||||
[JsonProperty("fields")]
|
||||
public WorkItemFields Fields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the revision URL.
|
||||
/// </summary>
|
||||
[JsonProperty("url")]
|
||||
public Uri Url { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNet.WebHooks.Receivers.TFS.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
|
81
src/Microsoft.AspNet.WebHooks.Receivers.VSTS/Properties/VstsReceiverResources.Designer.cs
сгенерированный
Normal file
81
src/Microsoft.AspNet.WebHooks.Receivers.VSTS/Properties/VstsReceiverResources.Designer.cs
сгенерированный
Normal file
|
@ -0,0 +1,81 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class VstsReceiverResources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal VstsReceiverResources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.WebHooks.Properties.VstsReceiverResources", typeof(VstsReceiverResources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The property 'eventType' contains unmapped value '{0}'..
|
||||
/// </summary>
|
||||
internal static string Handler_NonMappedEventType {
|
||||
get {
|
||||
return ResourceManager.GetString("Handler_NonMappedEventType", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No property 'eventType' was found in root of the object..
|
||||
/// </summary>
|
||||
internal static string Receiver_NoEventType {
|
||||
get {
|
||||
return ResourceManager.GetString("Receiver_NoEventType", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Handler_NonMappedEventType" xml:space="preserve">
|
||||
<value>The property 'eventType' contains unmapped value '{0}'.</value>
|
||||
</data>
|
||||
<data name="Receiver_NoEventType" xml:space="preserve">
|
||||
<value>No property 'eventType' was found in root of the object.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http.Controllers;
|
||||
using Microsoft.AspNet.WebHooks.Properties;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an <see cref="IWebHookReceiver"/> implementation which supports WebHooks generated by Visual Studio Team Services.
|
||||
///
|
||||
/// The corresponding WebHook URI is of the form '<c>https://<host>/api/webhooks/incoming/vsts/{id}?code={code}</c>'.
|
||||
/// For security reasons the WebHook URI must be an <c>https</c> URI and contain a 'code' query parameter with the
|
||||
/// same value as configured in the '<c>MS_WebHookReceiverSecret_Tfs</c>' application setting, optionally using IDs
|
||||
/// to differentiate between multiple WebHooks, for example '<c>secret0, id1=secret1, id2=secret2</c>'.
|
||||
/// The 'code' parameter must be between 32 and 128 characters long.
|
||||
///
|
||||
/// For details about Visual Studio Team Services WebHooks, see <c>https://www.visualstudio.com/en-us/get-started/integrate/service-hooks/webhooks-and-vso-vs</c>.
|
||||
/// </summary>
|
||||
public class VstsWebHookReceiver : WebHookReceiver
|
||||
{
|
||||
internal const string RecName = "vsts";
|
||||
internal const string EventTypeTokenName = "eventType";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the receiver name for this receiver.
|
||||
/// </summary>
|
||||
public static string ReceiverName
|
||||
{
|
||||
get { return RecName; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name
|
||||
{
|
||||
get { return RecName; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<HttpResponseMessage> ReceiveAsync(string id, HttpRequestContext context, HttpRequestMessage request)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
}
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
if (request == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
if (request.Method != HttpMethod.Post)
|
||||
{
|
||||
return CreateBadMethodResponse(request);
|
||||
}
|
||||
|
||||
// Ensure that we use https and have a valid code parameter
|
||||
await EnsureValidCode(request, id);
|
||||
|
||||
// Read the request entity body
|
||||
JObject jsonBody = await ReadAsJsonAsync(request);
|
||||
|
||||
// Read the action from body
|
||||
JToken action;
|
||||
string actionAsString;
|
||||
if (!jsonBody.TryGetValue(EventTypeTokenName, out action))
|
||||
{
|
||||
request.GetConfiguration().DependencyResolver.GetLogger().Error(VstsReceiverResources.Receiver_NoEventType);
|
||||
return request.CreateErrorResponse(HttpStatusCode.BadRequest, VstsReceiverResources.Receiver_NoEventType);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionAsString = action.Value<string>();
|
||||
}
|
||||
|
||||
return await ExecuteWebHookAsync(id, context, request, new[] { actionAsString }, jsonBody);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
|
||||
<package id="StyleCop.MSBuild" version="4.7.49.1" targetFramework="net45" developmentDependency="true" />
|
||||
</packages>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="xunit.parallelizeAssembly" value="true" />
|
||||
</appSettings>
|
||||
<startup>
|
||||
</startup>
|
||||
</configuration>
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
public static DateTime ToDateTime(this string self)
|
||||
{
|
||||
return DateTime.Parse(self, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks.Handlers
|
||||
{
|
||||
public class VstsWebHookHandlerBaseTests
|
||||
{
|
||||
private readonly Mock<VstsWebHookHandlerBase> _handlerMock;
|
||||
private readonly VstsWebHookHandlerBase _handler;
|
||||
|
||||
private WebHookHandlerContext _context;
|
||||
|
||||
public VstsWebHookHandlerBaseTests()
|
||||
{
|
||||
_handlerMock = new Mock<VstsWebHookHandlerBase> { CallBase = true };
|
||||
_handler = _handlerMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VstsWebHookHandlerBase_SetsReceiverName()
|
||||
{
|
||||
Assert.Equal(VstsWebHookReceiver.ReceiverName, _handler.Receiver);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_BuildCompleted()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.build.complete.json", "build.complete");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<BuildCompletedPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_CodeCheckedIn()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.tfvc.checkin.json", "tfvc.checkin");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<CodeCheckedInPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_TeamRoomMessagePosted()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.message.posted.json", "message.posted");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<TeamRoomMessagePostedPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_WorkItemCommentedOn()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.workitem.commented.json", "workitem.commented");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<WorkItemCommentedOnPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_WorkItemCreated()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.workitem.created.json", "workitem.created");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<WorkItemCreatedPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_WorkItemDeleted()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.workitem.deleted.json", "workitem.deleted");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<WorkItemDeletedPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_WorkItemRestored()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.workitem.restored.json", "workitem.restored");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<WorkItemRestoredPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Dispatches_WorkItemUpdated()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.workitem.updated.json", "workitem.updated");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<WorkItemUpdatedPayload>()), Times.Once());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_Handles_UnknownEventType()
|
||||
{
|
||||
// Arrange
|
||||
_context = GetContext("Microsoft.AspNet.WebHooks.Messages.bad.notMappedEventType.json", "unknown");
|
||||
|
||||
// Act
|
||||
await _handler.ExecuteAsync(VstsWebHookReceiver.ReceiverName, _context);
|
||||
|
||||
// Assert
|
||||
_handlerMock.Verify(h => h.ExecuteAsync(_context, It.IsAny<JObject>()), Times.Once());
|
||||
}
|
||||
|
||||
private static WebHookHandlerContext GetContext(string payload, string action)
|
||||
{
|
||||
JObject data = EmbeddedResource.ReadAsJObject(payload);
|
||||
HttpConfiguration httpConfig = new HttpConfiguration();
|
||||
HttpRequestContext requestContext = new HttpRequestContext { Configuration = httpConfig };
|
||||
HttpRequestMessage request = new HttpRequestMessage();
|
||||
request.SetRequestContext(requestContext);
|
||||
IEnumerable<string> actions = new[] { action };
|
||||
return new WebHookHandlerContext(actions)
|
||||
{
|
||||
Data = data,
|
||||
Request = request,
|
||||
RequestContext = requestContext
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 5,
|
||||
"eventType": "unknownType"
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 1,
|
||||
"id": "4a5d99d6-1c75-4e53-91b9-ee80057d4ce3",
|
||||
"eventType": "build.complete",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Build ConsumerAddressModule_20150407.2 succeeded",
|
||||
"html": "Build <a href=\"https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3\">ConsumerAddressModule_20150407.2</a> succeeded",
|
||||
"markdown": "Build [ConsumerAddressModule_20150407.2](https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3) succeeded"
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Build ConsumerAddressModule_20150407.2 succeeded",
|
||||
"html": "Build <a href=\"https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3\">ConsumerAddressModule_20150407.2</a> succeeded",
|
||||
"markdown": "Build [ConsumerAddressModule_20150407.2](https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3) succeeded"
|
||||
},
|
||||
"resource": {
|
||||
"uri": "vstfs:///Build/Build/2",
|
||||
"id": 2,
|
||||
"buildNumber": "ConsumerAddressModule_20150407.1",
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/71777fbc-1cf2-4bd1-9540-128c1c71f766/_apis/build/Builds/2",
|
||||
"startTime": "2015-04-07T18:04:06.83Z",
|
||||
"finishTime": "2015-04-07T18:06:10.69Z",
|
||||
"reason": "manual",
|
||||
"status": "succeeded",
|
||||
"dropLocation": "#/3/drop",
|
||||
"drop": {
|
||||
"location": "#/3/drop",
|
||||
"type": "container",
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/_apis/resources/Containers/3/drop",
|
||||
"downloadUrl": "https://good-company.some.ssl.host/DefaultCollection/_apis/resources/Containers/3/drop?api-version=1.0&$format=zip&downloadFileName=ConsumerAddressModule_20150407.1_drop"
|
||||
},
|
||||
"log": {
|
||||
"type": "container",
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/_apis/resources/Containers/3/logs",
|
||||
"downloadUrl": "https://good-company.some.ssl.host/_apis/resources/Containers/3/logs?api-version=1.0&$format=zip&downloadFileName=ConsumerAddressModule_20150407.1_logs"
|
||||
},
|
||||
"sourceGetVersion": "LG:refs/heads/master:600c52d2d5b655caa111abfd863e5a9bd304bb0e",
|
||||
"lastChangedBy": {
|
||||
"id": "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
"displayName": "John Smith",
|
||||
"uniqueName": "fabrikamfiber16@hotmail.com",
|
||||
"url": "https://good-company.some.ssl.host/_apis/Identities/d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
"imageUrl": "https://good-company.some.ssl.host/DefaultCollection/_api/_common/identityImage?id=d6245f20-2af8-44f4-9451-8107cb2767db"
|
||||
},
|
||||
"retainIndefinitely": false,
|
||||
"hasDiagnostics": true,
|
||||
"definition": {
|
||||
"batchSize": 1,
|
||||
"triggerType": "none",
|
||||
"definitionType": "xaml",
|
||||
"id": 2,
|
||||
"name": "ConsumerAddressModule",
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/71777fbc-1cf2-4bd1-9540-128c1c71f766/_apis/build/Definitions/2"
|
||||
},
|
||||
"queue": {
|
||||
"queueType": "buildController",
|
||||
"id": 4,
|
||||
"name": "Hosted Build Controller",
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/_apis/build/Queues/4"
|
||||
},
|
||||
"requests": [
|
||||
{
|
||||
"id": 1,
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/71777fbc-1cf2-4bd1-9540-128c1c71f766/_apis/build/Requests/1",
|
||||
"requestedFor": {
|
||||
"id": "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
"displayName": "John Smith",
|
||||
"uniqueName": "fabrikamfiber16@hotmail.com",
|
||||
"url": "https://good-company.some.ssl.host/_apis/Identities/d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
"imageUrl": "https://good-company.some.ssl.host/DefaultCollection/_api/_common/identityImage?id=d6245f20-2af8-44f4-9451-8107cb2767db"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:00:39.5893296Z"
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 3,
|
||||
"id": "daae438c-296b-4512-b08e-571910874e9b",
|
||||
"eventType": "message.posted",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello",
|
||||
"html": "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello",
|
||||
"markdown": "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello"
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello",
|
||||
"html": "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room<p>Hello</p>",
|
||||
"markdown": "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello"
|
||||
},
|
||||
"resource": {
|
||||
"id": 0,
|
||||
"content": "Hello",
|
||||
"messageType": "normal",
|
||||
"postedTime": "2014-05-02T19:17:13.3309587Z",
|
||||
"postedRoomId": 1,
|
||||
"postedBy": {
|
||||
"id": "00067FFED5C7AF52@Live.com",
|
||||
"displayName": "Jamal Hartnett",
|
||||
"uniqueName": "Windows Live ID\\fabrikamfiber4@hotmail.com"
|
||||
}
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:13:40.8417653Z"
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 2,
|
||||
"id": "f9b4c23e-88dd-4516-b04d-849787304e32",
|
||||
"eventType": "tfvc.checkin",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "John Smith checked in changeset 18: Dropping in new Java sample",
|
||||
"html": "John Smith checked in changeset <a href=\"https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18\">18</a>: Dropping in new Java sample",
|
||||
"markdown": "John Smith checked in changeset [18](https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18): Dropping in new Java sample"
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "John Smith checked in changeset 18: Dropping in new Java sample",
|
||||
"html": "John Smith checked in changeset <a href=\"https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18\">18</a>: Dropping in new Java sample",
|
||||
"markdown": "John Smith checked in changeset [18](https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18): Dropping in new Java sample"
|
||||
},
|
||||
"resource": {
|
||||
"changesetId": 18,
|
||||
"url": "https://good-company.some.ssl.host/DefaultCollection/_apis/tfvc/changesets/18",
|
||||
"author": {
|
||||
"id": "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
"displayName": "John Smith",
|
||||
"uniqueName": "fabrikamfiber16@hotmail.com"
|
||||
},
|
||||
"checkedInBy": {
|
||||
"id": "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
"displayName": "John Smith",
|
||||
"uniqueName": "fabrikamfiber16@hotmail.com"
|
||||
},
|
||||
"createdDate": "2014-05-12T22:41:16Z",
|
||||
"comment": "Dropping in new Java sample"
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:01:11.7056821Z"
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 4,
|
||||
"id": "fb2617ed-60df-4518-81fa-749faa6c5cd6",
|
||||
"eventType": "workitem.commented",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Bug #5 (Some great new idea!) commented on by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) commented on by Jamal Hartnett.",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) commented on by Jamal Hartnett."
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Bug #5 (Some great new idea!) commented on by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\nThis is a great new idea",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) commented on by Jamal Hartnett.<br/>This is a great new idea",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) commented on by Jamal Hartnett.\r\nThis is a great new idea"
|
||||
},
|
||||
"resource": {
|
||||
"id": 5,
|
||||
"rev": 4,
|
||||
"fields": {
|
||||
"System.AreaPath": "GoodCompanyCloud",
|
||||
"System.TeamProject": "GoodCompanyCloud",
|
||||
"System.IterationPath": "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
"System.WorkItemType": "Bug",
|
||||
"System.State": "New",
|
||||
"System.Reason": "New defect reported",
|
||||
"System.CreatedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.CreatedBy": "Jamal Hartnett",
|
||||
"System.ChangedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.ChangedBy": "Jamal Hartnett",
|
||||
"System.Title": "Some great new idea!",
|
||||
"Microsoft.VSTS.Common.Severity": "3 - Medium",
|
||||
"WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column": "New",
|
||||
"System.History": "This is a great new idea"
|
||||
},
|
||||
"_links": {
|
||||
"self": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
"workItemUpdates": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" },
|
||||
"workItemRevisions": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions" },
|
||||
"workItemType": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
"fields": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" }
|
||||
},
|
||||
"url": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5"
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:15:37.4638247Z"
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 5,
|
||||
"id": "d2d46fb1-dba5-403c-9373-427583f19e8c",
|
||||
"eventType": "workitem.created",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Bug #5 (Some great new idea!) created by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) created by Jamal Hartnett.",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) created by Jamal Hartnett."
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Bug #5 (Some great new idea!) created by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\n\r\n- State: New\r\n- Assigned to: \r\n- Comment: \r\n- Severity: 3 - Medium\r\n",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) created by Jamal Hartnett.<ul>\r\n<li>State: New</li>\r\n<li>Assigned to: </li>\r\n<li>Comment: </li>\r\n<li>Severity: 3 - Medium</li></ul>",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) created by Jamal Hartnett.\r\n\r\n* State: New\r\n* Assigned to: \r\n* Comment: \r\n* Severity: 3 - Medium\r\n"
|
||||
},
|
||||
"resource": {
|
||||
"id": 5,
|
||||
"rev": 1,
|
||||
"fields": {
|
||||
"System.AreaPath": "GoodCompanyCloud",
|
||||
"System.TeamProject": "GoodCompanyCloud",
|
||||
"System.IterationPath": "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
"System.WorkItemType": "Bug",
|
||||
"System.State": "New",
|
||||
"System.Reason": "New defect reported",
|
||||
"System.CreatedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.CreatedBy": "Jamal Hartnett",
|
||||
"System.ChangedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.ChangedBy": "Jamal Hartnett",
|
||||
"System.Title": "Some great new idea!",
|
||||
"Microsoft.VSTS.Common.Severity": "3 - Medium",
|
||||
"WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column": "New"
|
||||
},
|
||||
"_links": {
|
||||
"self": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
"workItemUpdates": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" },
|
||||
"workItemRevisions": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions" },
|
||||
"workItemType": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
"fields": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" }
|
||||
},
|
||||
"url": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5"
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:16:25.6251162Z"
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 6,
|
||||
"id": "72da0ade-0709-40ee-beb7-104287bf7e84",
|
||||
"eventType": "workitem.deleted",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.",
|
||||
"html": "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.",
|
||||
"markdown": "[Bug #5] (Some great new idea!) deleted by Jamal Hartnett."
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.\r\n\r\n- State: New\r\n",
|
||||
"html": "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.<ul>\r\n<li>State: New</li></ul>",
|
||||
"markdown": "[Bug #5] (Some great new idea!) deleted by Jamal Hartnett.\r\n\r\n* State: New\r\n"
|
||||
},
|
||||
"resource": {
|
||||
"id": 5,
|
||||
"rev": 1,
|
||||
"fields": {
|
||||
"System.AreaPath": "GoodCompanyCloud",
|
||||
"System.TeamProject": "GoodCompanyCloud",
|
||||
"System.IterationPath": "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
"System.WorkItemType": "Bug",
|
||||
"System.State": "New",
|
||||
"System.Reason": "New defect reported",
|
||||
"System.CreatedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.CreatedBy": "Jamal Hartnett",
|
||||
"System.ChangedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.ChangedBy": "Jamal Hartnett",
|
||||
"System.Title": "Some great new idea!",
|
||||
"Microsoft.VSTS.Common.Severity": "3 - Medium",
|
||||
"WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column": "New"
|
||||
},
|
||||
"_links": {
|
||||
"self": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/recyclebin/5" },
|
||||
"workItemType": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
"fields": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" }
|
||||
},
|
||||
"url": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/recyclebin/5"
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:17:28.3644564Z"
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 7,
|
||||
"id": "1ca023d6-6cff-49dd-b3d1-302b69311810",
|
||||
"eventType": "workitem.restored",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Bug #5 (Some great new idea!) restored by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) restored by Jamal Hartnett.",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) restored by Jamal Hartnett."
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Bug #5 (Some great new idea!) restored by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\n\r\n- State: New\r\n- Severity: 3 - Medium\r\n",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) restored by Jamal Hartnett.<ul>\r\n<li>State: New</li>Severity: 3 - Medium</li></ul>",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) restored by Jamal Hartnett.\r\n\r\n* State: New\r\n* Severity: 3 - Medium\r\n"
|
||||
},
|
||||
"resource": {
|
||||
"id": 5,
|
||||
"rev": 1,
|
||||
"fields": {
|
||||
"System.AreaPath": "GoodCompanyCloud",
|
||||
"System.TeamProject": "GoodCompanyCloud",
|
||||
"System.IterationPath": "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
"System.WorkItemType": "Bug",
|
||||
"System.State": "New",
|
||||
"System.Reason": "New defect reported",
|
||||
"System.CreatedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.CreatedBy": "Jamal Hartnett",
|
||||
"System.ChangedDate": "2014-07-15T17:42:44.663Z",
|
||||
"System.ChangedBy": "Jamal Hartnett",
|
||||
"System.Title": "Some great new idea!",
|
||||
"Microsoft.VSTS.Common.Severity": "3 - Medium",
|
||||
"WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column": "New"
|
||||
},
|
||||
"_links": {
|
||||
"self": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
"workItemUpdates": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" },
|
||||
"workItemRevisions": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions" },
|
||||
"workItemType": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
"fields": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" },
|
||||
"html": { "href": "https://good-company.some.ssl.host/web/wi.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&id=5" },
|
||||
"workItemHistory": { "href": "https://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/history" }
|
||||
},
|
||||
"url": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5"
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:18:15.5707279Z"
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"subscriptionId": "00000000-0000-0000-0000-000000000000",
|
||||
"notificationId": 8,
|
||||
"id": "27646e0e-b520-4d2b-9411-bba7524947cd",
|
||||
"eventType": "workitem.updated",
|
||||
"publisherId": "tfs",
|
||||
"message": {
|
||||
"text": "Bug #5 (Some great new idea!) updated by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) updated by Jamal Hartnett.",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) updated by Jamal Hartnett."
|
||||
},
|
||||
"detailedMessage": {
|
||||
"text": "Bug #5 (Some great new idea!) updated by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\n\r\n- New State: Approved\r\n",
|
||||
"html": "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) updated by Jamal Hartnett.<ul>\r\n<li>New State: Approved</li></ul>",
|
||||
"markdown": "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) updated by Jamal Hartnett.\r\n\r\n* New State: Approved\r\n"
|
||||
},
|
||||
"resource": {
|
||||
"id": 2,
|
||||
"workItemId": 0,
|
||||
"rev": 2,
|
||||
"revisedBy": null,
|
||||
"revisedDate": "0001-01-01T00:00:00",
|
||||
"fields": {
|
||||
"System.Rev": {
|
||||
"oldValue": "1",
|
||||
"newValue": "2"
|
||||
},
|
||||
"System.AuthorizedDate": {
|
||||
"oldValue": "2014-07-15T16:48:44.663Z",
|
||||
"newValue": "2014-07-15T17:42:44.663Z"
|
||||
},
|
||||
"System.RevisedDate": {
|
||||
"oldValue": "2014-07-15T17:42:44.663Z",
|
||||
"newValue": "9999-01-01T00:00:00Z"
|
||||
},
|
||||
"System.State": {
|
||||
"oldValue": "New",
|
||||
"newValue": "Approved"
|
||||
},
|
||||
"System.Reason": {
|
||||
"oldValue": "New defect reported",
|
||||
"newValue": "Approved by the Product Owner"
|
||||
},
|
||||
"System.AssignedTo": { "newValue": "Jamal Hartnet" },
|
||||
"System.ChangedDate": {
|
||||
"oldValue": "2014-07-15T16:48:44.663Z",
|
||||
"newValue": "2014-07-15T17:42:44.663Z"
|
||||
},
|
||||
"System.Watermark": {
|
||||
"oldValue": "2",
|
||||
"newValue": "5"
|
||||
},
|
||||
"Microsoft.VSTS.Common.Severity": {
|
||||
"oldValue": "3 - Medium",
|
||||
"newValue": "2 - High"
|
||||
}
|
||||
},
|
||||
"_links": {
|
||||
"self": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates/2" },
|
||||
"parent": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
"workItemUpdates": { "href": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" }
|
||||
},
|
||||
"url": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates/2",
|
||||
"revision": {
|
||||
"id": 5,
|
||||
"rev": 2,
|
||||
"fields": {
|
||||
"System.AreaPath": "GoodCompanyCloud",
|
||||
"System.TeamProject": "GoodCompanyCloud",
|
||||
"System.IterationPath": "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
"System.WorkItemType": "Bug",
|
||||
"System.State": "New",
|
||||
"System.Reason": "New defect reported",
|
||||
"System.CreatedDate": "2014-07-15T16:48:44.663Z",
|
||||
"System.CreatedBy": "Jamal Hartnett",
|
||||
"System.ChangedDate": "2014-07-15T16:48:44.663Z",
|
||||
"System.ChangedBy": "Jamal Hartnett",
|
||||
"System.Title": "Some great new idea!",
|
||||
"Microsoft.VSTS.Common.Severity": "3 - Medium",
|
||||
"WEF_EB329F44FE5F4A94ACB1DA153FDF38BA_Kanban.Column": "New"
|
||||
},
|
||||
"url": "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions/2"
|
||||
}
|
||||
},
|
||||
"resourceVersion": "1.0",
|
||||
"resourceContainers": {
|
||||
"collection": { "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
"account": { "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
"project": { "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
"createdDate": "2016-05-02T19:19:12.8836446Z"
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\xunit.runner.visualstudio.2.0.1\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.0.1\build\net20\xunit.runner.visualstudio.props')" />
|
||||
<Import Project="..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" />
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),WebHooks.sln))\tools\WebHooks.settings.targets" />
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{B27CC8B5-BF38-434B-B5CE-42ACEC40624C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.AspNet.WebHooks</RootNamespace>
|
||||
<AssemblyName>Microsoft.AspNet.WebHooks.Receivers.VSTS.Test</AssemblyName>
|
||||
<OutputPath>..\..\bin\$(Configuration)\Test\</OutputPath>
|
||||
<RunCodeAnalysis>$(CodeAnalysis)</RunCodeAnalysis>
|
||||
<CodeAnalysisAdditionalOptions>/assemblyCompareMode:StrongNameIgnoringVersion</CodeAnalysisAdditionalOptions>
|
||||
<CodeAnalysisRuleSet>..\..\FxCopTest.ruleset</CodeAnalysisRuleSet>
|
||||
<DefineConstants>$(DefineConstants);ASPNETWEBHOOKS</DefineConstants>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Moq, Version=4.2.1502.911, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Moq.4.2.1502.0911\lib\net40\Moq.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.2\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="xunit.assert, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="xunit.core, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\common\EmbeddedResource.cs">
|
||||
<Link>Common\EmbeddedResource.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Common\Extensions.cs" />
|
||||
<Compile Include="Handlers\VstsWebHookHandlerBaseTests.cs" />
|
||||
<Compile Include="Payloads\BuildCompletedPayloadTests.cs" />
|
||||
<Compile Include="Payloads\CodeCheckedInPayloadTests.cs" />
|
||||
<Compile Include="Payloads\TeamRoomMessagePostedPayloadTests.cs" />
|
||||
<Compile Include="Payloads\WorkItemCommentedOnPayloadTests.cs" />
|
||||
<Compile Include="Payloads\WorkItemCreatedPayloadTests.cs" />
|
||||
<Compile Include="Payloads\WorkItemDeletedPayloadTests.cs" />
|
||||
<Compile Include="Payloads\WorkItemRestoredPayloadTests.cs" />
|
||||
<Compile Include="Payloads\WorkItemUpdatedPayloadTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WebHooks\VstsWebHookReceiverTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="App.config" />
|
||||
<EmbeddedResource Include="Messages\build.complete.json" />
|
||||
<EmbeddedResource Include="Messages\tfvc.checkin.json" />
|
||||
<EmbeddedResource Include="Messages\workitem.updated.json" />
|
||||
<EmbeddedResource Include="Messages\workitem.restored.json" />
|
||||
<EmbeddedResource Include="Messages\workitem.deleted.json" />
|
||||
<EmbeddedResource Include="Messages\workitem.created.json" />
|
||||
<EmbeddedResource Include="Messages\workitem.commented.json" />
|
||||
<EmbeddedResource Include="Messages\message.posted.json" />
|
||||
<EmbeddedResource Include="Messages\bad.noEventType.json" />
|
||||
<EmbeddedResource Include="Messages\bad.notMappedEventType.json" />
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Src\Microsoft.AspNet.WebHooks.Common\Microsoft.AspNet.WebHooks.Common.csproj">
|
||||
<Project>{f7dd0935-6320-4efc-9464-d5a2d2b8c2f7}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNet.WebHooks.Receivers.VSTS\Microsoft.AspNet.WebHooks.Receivers.VSTS.csproj">
|
||||
<Project>{6b501d55-2aa3-4757-a185-1277bb881de8}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Receivers.VSTS</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Src\Microsoft.AspNet.WebHooks.Receivers\Microsoft.AspNet.WebHooks.Receivers.csproj">
|
||||
<Project>{8ced31fb-32f2-4ffb-9997-452fb9728577}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Receivers</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.AspNet.WebHooks.Receivers.Test\Microsoft.AspNet.WebHooks.Receivers.Test.csproj">
|
||||
<Project>{cb965ed1-1e07-4374-a829-c636db09f567}</Project>
|
||||
<Name>Microsoft.AspNet.WebHooks.Receivers.Test</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Microsoft.TestUtilities\Microsoft.TestUtilities.csproj">
|
||||
<Project>{608b1d09-e4de-4dba-8dbf-7758003988f0}</Project>
|
||||
<Name>Microsoft.TestUtilities</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CodeAnalysisDictionary Include="..\..\CustomDictionary.xml">
|
||||
<Link>CustomDictionary.xml</Link>
|
||||
</CodeAnalysisDictionary>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.0.1\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.0.1\build\net20\xunit.runner.visualstudio.props'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets" Condition="Exists('..\..\packages\StyleCop.MSBuild.4.7.49.1\build\StyleCop.MSBuild.Targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class BuildCompletedPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void BuildCompletedPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.build.complete.json");
|
||||
|
||||
var expected = new BuildCompletedPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 1,
|
||||
Id = "4a5d99d6-1c75-4e53-91b9-ee80057d4ce3",
|
||||
EventType = "build.complete",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Build ConsumerAddressModule_20150407.2 succeeded",
|
||||
Html = "Build <a href=\"https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3\">ConsumerAddressModule_20150407.2</a> succeeded",
|
||||
Markdown = "Build [ConsumerAddressModule_20150407.2](https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3) succeeded"
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Build ConsumerAddressModule_20150407.2 succeeded",
|
||||
Html = "Build <a href=\"https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3\">ConsumerAddressModule_20150407.2</a> succeeded",
|
||||
Markdown = "Build [ConsumerAddressModule_20150407.2](https://good-company.some.ssl.host/web/build.aspx?id=5023c10b-bef3-41c3-bf53-686c4e34ee9e&builduri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f3) succeeded"
|
||||
},
|
||||
|
||||
Resource = new BuildCompletedResource
|
||||
{
|
||||
Uri = new Uri("vstfs:///Build/Build/2"),
|
||||
Id = 2,
|
||||
BuildNumber = "ConsumerAddressModule_20150407.1",
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/71777fbc-1cf2-4bd1-9540-128c1c71f766/_apis/build/Builds/2"),
|
||||
StartTime = "2015-04-07T18:04:06.83Z".ToDateTime(),
|
||||
FinishTime = "2015-04-07T18:06:10.69Z".ToDateTime(),
|
||||
Reason = "manual",
|
||||
Status = "succeeded",
|
||||
DropLocation = "#/3/drop",
|
||||
Drop = new BuildCompletedDrop
|
||||
{
|
||||
Location = "#/3/drop",
|
||||
DropType = "container",
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/_apis/resources/Containers/3/drop"),
|
||||
DownloadUrl = new Uri("https://good-company.some.ssl.host/DefaultCollection/_apis/resources/Containers/3/drop?api-version=1.0&$format=zip&downloadFileName=ConsumerAddressModule_20150407.1_drop")
|
||||
},
|
||||
Log = new BuildCompletedLog
|
||||
{
|
||||
LogType = "container",
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/_apis/resources/Containers/3/logs"),
|
||||
DownloadUrl = new Uri("https://good-company.some.ssl.host/_apis/resources/Containers/3/logs?api-version=1.0&$format=zip&downloadFileName=ConsumerAddressModule_20150407.1_logs")
|
||||
},
|
||||
SourceGetVersion = "LG:refs/heads/master:600c52d2d5b655caa111abfd863e5a9bd304bb0e",
|
||||
LastChangedBy = new ResourceUser
|
||||
{
|
||||
Id = "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
DisplayName = "John Smith",
|
||||
UniqueName = "fabrikamfiber16@hotmail.com",
|
||||
Url = new Uri("https://good-company.some.ssl.host/_apis/Identities/d6245f20-2af8-44f4-9451-8107cb2767db"),
|
||||
ImageUrl = new Uri("https://good-company.some.ssl.host/DefaultCollection/_api/_common/identityImage?id=d6245f20-2af8-44f4-9451-8107cb2767db")
|
||||
},
|
||||
RetainIndefinitely = false,
|
||||
HasDiagnostics = true,
|
||||
Definition = new BuildCompletedDefinition
|
||||
{
|
||||
BatchSize = 1,
|
||||
TriggerType = "none",
|
||||
DefinitionType = "xaml",
|
||||
Id = 2,
|
||||
Name = "ConsumerAddressModule",
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/71777fbc-1cf2-4bd1-9540-128c1c71f766/_apis/build/Definitions/2")
|
||||
},
|
||||
Queue = new BuildCompletedQueueDefinition
|
||||
{
|
||||
QueueType = "buildController",
|
||||
Id = 4,
|
||||
Name = "Hosted Build Controller",
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/_apis/build/Queues/4")
|
||||
}
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:00:39.5893296Z".ToDateTime()
|
||||
};
|
||||
expected.Resource.Requests.Add(new BuildCompletedRequest
|
||||
{
|
||||
Id = 1,
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/71777fbc-1cf2-4bd1-9540-128c1c71f766/_apis/build/Requests/1"),
|
||||
RequestedFor = new ResourceUser
|
||||
{
|
||||
Id = "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
DisplayName = "John Smith",
|
||||
UniqueName = "fabrikamfiber16@hotmail.com",
|
||||
Url = new Uri("https://good-company.some.ssl.host/_apis/Identities/d6245f20-2af8-44f4-9451-8107cb2767db"),
|
||||
ImageUrl = new Uri("https://good-company.some.ssl.host/DefaultCollection/_api/_common/identityImage?id=d6245f20-2af8-44f4-9451-8107cb2767db")
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<BuildCompletedPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class CodeCheckedInPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void CodeCheckedInPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.tfvc.checkin.json");
|
||||
var expected = new CodeCheckedInPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 2,
|
||||
Id = "f9b4c23e-88dd-4516-b04d-849787304e32",
|
||||
EventType = "tfvc.checkin",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "John Smith checked in changeset 18: Dropping in new Java sample",
|
||||
Html = "John Smith checked in changeset <a href=\"https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18\">18</a>: Dropping in new Java sample",
|
||||
Markdown = "John Smith checked in changeset [18](https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18): Dropping in new Java sample"
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "John Smith checked in changeset 18: Dropping in new Java sample",
|
||||
Html = "John Smith checked in changeset <a href=\"https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18\">18</a>: Dropping in new Java sample",
|
||||
Markdown = "John Smith checked in changeset [18](https://good-company.some.ssl.host/web/cs.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&cs=18): Dropping in new Java sample"
|
||||
},
|
||||
Resource = new CodeCheckedInResource
|
||||
{
|
||||
ChangesetId = 18,
|
||||
Url = new Uri("https://good-company.some.ssl.host/DefaultCollection/_apis/tfvc/changesets/18"),
|
||||
Author = new ResourceUser
|
||||
{
|
||||
Id = "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
DisplayName = "John Smith",
|
||||
UniqueName = "fabrikamfiber16@hotmail.com"
|
||||
},
|
||||
CheckedInBy = new ResourceUser
|
||||
{
|
||||
Id = "d6245f20-2af8-44f4-9451-8107cb2767db",
|
||||
DisplayName = "John Smith",
|
||||
UniqueName = "fabrikamfiber16@hotmail.com"
|
||||
},
|
||||
CreatedDate = "2014-05-12T22:41:16Z".ToDateTime(),
|
||||
Comment = "Dropping in new Java sample"
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:01:11.7056821Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<CodeCheckedInPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class TeamRoomMessagePostedPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void TeamRoomMessagePostedPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.message.posted.json");
|
||||
var expected = new TeamRoomMessagePostedPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 3,
|
||||
Id = "daae438c-296b-4512-b08e-571910874e9b",
|
||||
EventType = "message.posted",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello",
|
||||
Html = "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello",
|
||||
Markdown = "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello"
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello",
|
||||
Html = "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room<p>Hello</p>",
|
||||
Markdown = "Jamal Hartnett posted a message to Northward-Fiber-Git Team Room\r\nHello"
|
||||
},
|
||||
Resource = new TeamRoomMessagePostedResource
|
||||
{
|
||||
Id = 0,
|
||||
Content = "Hello",
|
||||
MessageType = "normal",
|
||||
PostedTime = "2014-05-02T19:17:13.3309587Z".ToDateTime(),
|
||||
PostedRoomId = 1,
|
||||
PostedBy = new ResourceUser
|
||||
{
|
||||
Id = "00067FFED5C7AF52@Live.com",
|
||||
DisplayName = "Jamal Hartnett",
|
||||
UniqueName = "Windows Live ID\\fabrikamfiber4@hotmail.com"
|
||||
}
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:13:40.8417653Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<TeamRoomMessagePostedPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class WorkItemCommentedOnPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void WorkItemCommentedOnPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.workitem.commented.json");
|
||||
var expected = new WorkItemCommentedOnPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 4,
|
||||
Id = "fb2617ed-60df-4518-81fa-749faa6c5cd6",
|
||||
EventType = "workitem.commented",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) commented on by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) commented on by Jamal Hartnett.",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) commented on by Jamal Hartnett."
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) commented on by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\nThis is a great new idea",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) commented on by Jamal Hartnett.<br/>This is a great new idea",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) commented on by Jamal Hartnett.\r\nThis is a great new idea"
|
||||
},
|
||||
Resource = new WorkItemCommentedOnResource
|
||||
{
|
||||
Id = 5,
|
||||
RevisionNumber = 4,
|
||||
Fields = new WorkItemFields
|
||||
{
|
||||
SystemAreaPath = "GoodCompanyCloud",
|
||||
SystemTeamProject = "GoodCompanyCloud",
|
||||
SystemIterationPath = "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
SystemWorkItemType = "Bug",
|
||||
SystemState = "New",
|
||||
SystemReason = "New defect reported",
|
||||
SystemCreatedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemCreatedBy = "Jamal Hartnett",
|
||||
SystemChangedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemChangedBy = "Jamal Hartnett",
|
||||
SystemTitle = "Some great new idea!",
|
||||
MicrosoftCommonSeverity = "3 - Medium",
|
||||
KanbanColumn = "New",
|
||||
SystemHistory = "This is a great new idea"
|
||||
},
|
||||
Links = new WorkItemLinks
|
||||
{
|
||||
Self = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
WorkItemUpdates = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" },
|
||||
WorkItemRevisions = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions" },
|
||||
WorkItemType = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
Fields = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" }
|
||||
},
|
||||
Url = new Uri("http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5")
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:15:37.4638247Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<WorkItemCommentedOnPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class WorkItemCreatedPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void WorkItemCreatedPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.workitem.created.json");
|
||||
var expected = new WorkItemCreatedPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 5,
|
||||
Id = "d2d46fb1-dba5-403c-9373-427583f19e8c",
|
||||
EventType = "workitem.created",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) created by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) created by Jamal Hartnett.",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) created by Jamal Hartnett."
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) created by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\n\r\n- State: New\r\n- Assigned to: \r\n- Comment: \r\n- Severity: 3 - Medium\r\n",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) created by Jamal Hartnett.<ul>\r\n<li>State: New</li>\r\n<li>Assigned to: </li>\r\n<li>Comment: </li>\r\n<li>Severity: 3 - Medium</li></ul>",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) created by Jamal Hartnett.\r\n\r\n* State: New\r\n* Assigned to: \r\n* Comment: \r\n* Severity: 3 - Medium\r\n"
|
||||
},
|
||||
Resource = new WorkItemCreatedResource
|
||||
{
|
||||
Id = 5,
|
||||
RevisionNumber = 1,
|
||||
Fields = new WorkItemFields
|
||||
{
|
||||
SystemAreaPath = "GoodCompanyCloud",
|
||||
SystemTeamProject = "GoodCompanyCloud",
|
||||
SystemIterationPath = "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
SystemWorkItemType = "Bug",
|
||||
SystemState = "New",
|
||||
SystemReason = "New defect reported",
|
||||
SystemCreatedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemCreatedBy = "Jamal Hartnett",
|
||||
SystemChangedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemChangedBy = "Jamal Hartnett",
|
||||
SystemTitle = "Some great new idea!",
|
||||
MicrosoftCommonSeverity = "3 - Medium",
|
||||
KanbanColumn = "New"
|
||||
},
|
||||
Links = new WorkItemLinks
|
||||
{
|
||||
Self = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
WorkItemUpdates = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" },
|
||||
WorkItemRevisions = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions" },
|
||||
WorkItemType = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
Fields = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" }
|
||||
},
|
||||
Url = new Uri("http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5")
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:16:25.6251162Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<WorkItemCreatedPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class WorkItemDeletedPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void WorkItemDeletedPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.workitem.deleted.json");
|
||||
var expected = new WorkItemDeletedPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 6,
|
||||
Id = "72da0ade-0709-40ee-beb7-104287bf7e84",
|
||||
EventType = "workitem.deleted",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.",
|
||||
Html = "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.",
|
||||
Markdown = "[Bug #5] (Some great new idea!) deleted by Jamal Hartnett."
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.\r\n\r\n- State: New\r\n",
|
||||
Html = "Bug #5 (Some great new idea!) deleted by Jamal Hartnett.<ul>\r\n<li>State: New</li></ul>",
|
||||
Markdown = "[Bug #5] (Some great new idea!) deleted by Jamal Hartnett.\r\n\r\n* State: New\r\n"
|
||||
},
|
||||
Resource = new WorkItemDeletedResource
|
||||
{
|
||||
Id = 5,
|
||||
RevisionNumber = 1,
|
||||
Fields = new WorkItemFields
|
||||
{
|
||||
SystemAreaPath = "GoodCompanyCloud",
|
||||
SystemTeamProject = "GoodCompanyCloud",
|
||||
SystemIterationPath = "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
SystemWorkItemType = "Bug",
|
||||
SystemState = "New",
|
||||
SystemReason = "New defect reported",
|
||||
SystemCreatedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemCreatedBy = "Jamal Hartnett",
|
||||
SystemChangedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemChangedBy = "Jamal Hartnett",
|
||||
SystemTitle = "Some great new idea!",
|
||||
MicrosoftCommonSeverity = "3 - Medium",
|
||||
KanbanColumn = "New"
|
||||
},
|
||||
Links = new WorkItemLinks
|
||||
{
|
||||
Self = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/recyclebin/5" },
|
||||
WorkItemType = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
Fields = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" }
|
||||
},
|
||||
Url = new Uri("http://good-company.some.ssl.host/DefaultCollection/_apis/wit/recyclebin/5")
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:17:28.3644564Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<WorkItemDeletedPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class WorkItemRestoredPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void WorkItemRestoredPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.workitem.restored.json");
|
||||
var expected = new WorkItemRestoredPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 7,
|
||||
Id = "1ca023d6-6cff-49dd-b3d1-302b69311810",
|
||||
EventType = "workitem.restored",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) restored by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) restored by Jamal Hartnett.",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) restored by Jamal Hartnett."
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) restored by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\n\r\n- State: New\r\n- Severity: 3 - Medium\r\n",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) restored by Jamal Hartnett.<ul>\r\n<li>State: New</li>Severity: 3 - Medium</li></ul>",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) restored by Jamal Hartnett.\r\n\r\n* State: New\r\n* Severity: 3 - Medium\r\n"
|
||||
},
|
||||
Resource = new WorkItemRestoredResource
|
||||
{
|
||||
Id = 5,
|
||||
RevisionNumber = 1,
|
||||
Fields = new WorkItemFields
|
||||
{
|
||||
SystemAreaPath = "GoodCompanyCloud",
|
||||
SystemTeamProject = "GoodCompanyCloud",
|
||||
SystemIterationPath = "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
SystemWorkItemType = "Bug",
|
||||
SystemState = "New",
|
||||
SystemReason = "New defect reported",
|
||||
SystemCreatedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemCreatedBy = "Jamal Hartnett",
|
||||
SystemChangedDate = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
SystemChangedBy = "Jamal Hartnett",
|
||||
SystemTitle = "Some great new idea!",
|
||||
MicrosoftCommonSeverity = "3 - Medium",
|
||||
KanbanColumn = "New"
|
||||
},
|
||||
Links = new WorkItemLinks
|
||||
{
|
||||
Self = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
WorkItemUpdates = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" },
|
||||
WorkItemRevisions = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions" },
|
||||
WorkItemType = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/ea830882-2a3c-4095-a53f-972f9a376f6e/workItemTypes/Bug" },
|
||||
Fields = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/fields" },
|
||||
Html = new WorkItemLink { Href = "https://good-company.some.ssl.host/web/wi.aspx?id=d81542e4-cdfa-4333-b082-1ae2d6c3ad16&id=5" },
|
||||
WorkItemHistory = new WorkItemLink { Href = "https://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/history" }
|
||||
},
|
||||
Url = new Uri("http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5")
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:18:15.5707279Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<WorkItemRestoredPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.WebHooks.Payloads;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class WorkItemUpdatedPayloadTests
|
||||
{
|
||||
[Fact]
|
||||
public void WorkItemUpdatedPayload_Roundtrips()
|
||||
{
|
||||
// Arrange
|
||||
JObject data = EmbeddedResource.ReadAsJObject("Microsoft.AspNet.WebHooks.Messages.workitem.updated.json");
|
||||
var expected = new WorkItemUpdatedPayload
|
||||
{
|
||||
SubscriptionId = "00000000-0000-0000-0000-000000000000",
|
||||
NotificationId = 8,
|
||||
Id = "27646e0e-b520-4d2b-9411-bba7524947cd",
|
||||
EventType = "workitem.updated",
|
||||
PublisherId = "tfs",
|
||||
Message = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) updated by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) updated by Jamal Hartnett.",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) updated by Jamal Hartnett."
|
||||
},
|
||||
DetailedMessage = new PayloadMessage
|
||||
{
|
||||
Text = "Bug #5 (Some great new idea!) updated by Jamal Hartnett.\r\n(http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5)\r\n\r\n- New State: Approved\r\n",
|
||||
Html = "<a href=\"http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5\">Bug #5</a> (Some great new idea!) updated by Jamal Hartnett.<ul>\r\n<li>New State: Approved</li></ul>",
|
||||
Markdown = "[Bug #5](http://good-company.some.ssl.host/web/wi.aspx?id=74e918bf-3376-436d-bd20-8e8c1287f465&id=5) (Some great new idea!) updated by Jamal Hartnett.\r\n\r\n* New State: Approved\r\n"
|
||||
},
|
||||
Resource = new WorkItemUpdatedResource
|
||||
{
|
||||
Id = 2,
|
||||
WorkItemId = 0,
|
||||
RevisionNumber = 2,
|
||||
RevisedBy = null,
|
||||
RevisedDate = "0001-01-01T00:00:00".ToDateTime(),
|
||||
Fields = new WorkItemUpdatedFields
|
||||
{
|
||||
SystemRev = new WorkItemUpdatedFieldValue<string>
|
||||
{
|
||||
OldValue = "1",
|
||||
NewValue = "2"
|
||||
},
|
||||
SystemAuthorizedDate = new WorkItemUpdatedFieldValue<DateTime>
|
||||
{
|
||||
OldValue = "2014-07-15T16:48:44.663Z".ToDateTime(),
|
||||
NewValue = "2014-07-15T17:42:44.663Z".ToDateTime()
|
||||
},
|
||||
SystemRevisedDate = new WorkItemUpdatedFieldValue<DateTime>
|
||||
{
|
||||
OldValue = "2014-07-15T17:42:44.663Z".ToDateTime(),
|
||||
NewValue = "9999-01-01T00:00:00Z".ToDateTime()
|
||||
},
|
||||
SystemState = new WorkItemUpdatedFieldValue<string>
|
||||
{
|
||||
OldValue = "New",
|
||||
NewValue = "Approved"
|
||||
},
|
||||
SystemReason = new WorkItemUpdatedFieldValue<string>
|
||||
{
|
||||
OldValue = "New defect reported",
|
||||
NewValue = "Approved by the Product Owner"
|
||||
},
|
||||
SystemAssignedTo = new WorkItemUpdatedFieldValue<string>
|
||||
{
|
||||
NewValue = "Jamal Hartnet"
|
||||
},
|
||||
SystemChangedDate = new WorkItemUpdatedFieldValue<DateTime>
|
||||
{
|
||||
OldValue = "2014-07-15T16:48:44.663Z".ToDateTime(),
|
||||
NewValue = "2014-07-15T17:42:44.663Z".ToDateTime()
|
||||
},
|
||||
SystemWatermark = new WorkItemUpdatedFieldValue<string>
|
||||
{
|
||||
OldValue = "2",
|
||||
NewValue = "5"
|
||||
},
|
||||
MicrosoftCommonSeverity = new WorkItemUpdatedFieldValue<string>
|
||||
{
|
||||
OldValue = "3 - Medium",
|
||||
NewValue = "2 - High"
|
||||
}
|
||||
},
|
||||
Links = new WorkItemLinks
|
||||
{
|
||||
Self = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates/2" },
|
||||
Parent = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5" },
|
||||
WorkItemUpdates = new WorkItemLink { Href = "http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates" }
|
||||
},
|
||||
Url = new Uri("http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/updates/2"),
|
||||
Revision = new WorkItemUpdatedRevision
|
||||
{
|
||||
Id = 5,
|
||||
Rev = 2,
|
||||
Fields = new WorkItemFields
|
||||
{
|
||||
SystemAreaPath = "GoodCompanyCloud",
|
||||
SystemTeamProject = "GoodCompanyCloud",
|
||||
SystemIterationPath = "GoodCompanyCloud\\Release 1\\Sprint 1",
|
||||
SystemWorkItemType = "Bug",
|
||||
SystemState = "New",
|
||||
SystemReason = "New defect reported",
|
||||
SystemCreatedDate = "2014-07-15T16:48:44.663Z".ToDateTime(),
|
||||
SystemCreatedBy = "Jamal Hartnett",
|
||||
SystemChangedDate = "2014-07-15T16:48:44.663Z".ToDateTime(),
|
||||
SystemChangedBy = "Jamal Hartnett",
|
||||
SystemTitle = "Some great new idea!",
|
||||
MicrosoftCommonSeverity = "3 - Medium",
|
||||
KanbanColumn = "New"
|
||||
},
|
||||
Url = new Uri("http://good-company.some.ssl.host/DefaultCollection/_apis/wit/workItems/5/revisions/2")
|
||||
}
|
||||
},
|
||||
ResourceVersion = "1.0",
|
||||
ResourceContainers = new PayloadResourceContainers
|
||||
{
|
||||
Collection = new PayloadResourceContainer { Id = "c12d0eb8-e382-443b-9f9c-c52cba5014c2" },
|
||||
Account = new PayloadResourceContainer { Id = "f844ec47-a9db-4511-8281-8b63f4eaf94e" },
|
||||
Project = new PayloadResourceContainer { Id = "be9b3917-87e6-42a4-a549-2bc06a7a878f" }
|
||||
},
|
||||
CreatedDate = "2016-05-02T19:19:12.8836446Z".ToDateTime()
|
||||
};
|
||||
|
||||
// Act
|
||||
var actual = data.ToObject<WorkItemUpdatedPayload>();
|
||||
|
||||
// Assert
|
||||
string expectedJson = JsonConvert.SerializeObject(expected);
|
||||
string actualJson = JsonConvert.SerializeObject(actual);
|
||||
Assert.Equal(expectedJson, actualJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using Moq;
|
||||
using Moq.Protected;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.WebHooks
|
||||
{
|
||||
public class VstsWebHookReceiverTests : WebHookReceiverTestsBase<VstsWebHookReceiver>
|
||||
{
|
||||
private const string TestAction = "message.posted";
|
||||
private const string TestId = "";
|
||||
private const string TestSecret = "12345678901234567890123456789012";
|
||||
private const string TestAddress = "https://some.ssl.host?code=" + TestSecret;
|
||||
private HttpRequestMessage _postRequest;
|
||||
|
||||
public static TheoryData<string> InvalidCodeQueries
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<string>
|
||||
{
|
||||
string.Empty,
|
||||
"=",
|
||||
"==",
|
||||
"invalid",
|
||||
"code",
|
||||
"code=",
|
||||
"k1=v1;k2=v2",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReceiverName_IsConsistent()
|
||||
{
|
||||
// Arrange
|
||||
IWebHookReceiver rec = new VstsWebHookReceiver();
|
||||
string expected = "vsts";
|
||||
|
||||
// Act
|
||||
string actual1 = rec.Name;
|
||||
string actual2 = VstsWebHookReceiver.ReceiverName;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, actual1);
|
||||
Assert.Equal(actual1, actual2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReceiveAsync_Throws_IfPostIsNotUsingHttps()
|
||||
{
|
||||
// Arrange
|
||||
Initialize(TestSecret);
|
||||
_postRequest.RequestUri = new Uri("http://some.no.ssl.host");
|
||||
|
||||
// Act
|
||||
HttpResponseException ex = await Assert.ThrowsAsync<HttpResponseException>(() => ReceiverMock.Object.ReceiveAsync(TestId, RequestContext, _postRequest));
|
||||
|
||||
// Assert
|
||||
HttpError error = await ex.Response.Content.ReadAsAsync<HttpError>();
|
||||
Assert.Equal("The WebHook receiver 'VstsWebHookReceiverProxy' requires HTTPS in order to be secure. Please register a WebHook URI of type 'https'.", error.Message);
|
||||
ReceiverMock.Protected()
|
||||
.Verify<Task<HttpResponseMessage>>("ExecuteWebHookAsync", Times.Never(), TestId, RequestContext, _postRequest, ItExpr.IsAny<IEnumerable<string>>(), ItExpr.IsAny<object>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("InvalidCodeQueries")]
|
||||
public async Task ReceiveAsync_Throws_IfPostHasNoCodeParameter(string query)
|
||||
{
|
||||
// Arrange
|
||||
Initialize(TestSecret);
|
||||
_postRequest.RequestUri = new Uri("https://some.no.ssl.host?" + query);
|
||||
|
||||
// Act
|
||||
HttpResponseException ex = await Assert.ThrowsAsync<HttpResponseException>(() => ReceiverMock.Object.ReceiveAsync(TestId, RequestContext, _postRequest));
|
||||
|
||||
// Assert
|
||||
HttpError error = await ex.Response.Content.ReadAsAsync<HttpError>();
|
||||
Assert.Equal("The WebHook verification request must contain a 'code' query parameter.", error.Message);
|
||||
ReceiverMock.Protected()
|
||||
.Verify<Task<HttpResponseMessage>>("ExecuteWebHookAsync", Times.Never(), TestId, RequestContext, _postRequest, ItExpr.IsAny<IEnumerable<string>>(), ItExpr.IsAny<object>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReceiveAsync_Throws_IfPostHasWrongCodeParameter()
|
||||
{
|
||||
// Arrange
|
||||
Initialize(TestSecret);
|
||||
_postRequest.RequestUri = new Uri("https://some.no.ssl.host?code=invalid");
|
||||
|
||||
// Act
|
||||
HttpResponseException ex = await Assert.ThrowsAsync<HttpResponseException>(() => ReceiverMock.Object.ReceiveAsync(TestId, RequestContext, _postRequest));
|
||||
|
||||
// Assert
|
||||
HttpError error = await ex.Response.Content.ReadAsAsync<HttpError>();
|
||||
Assert.Equal("The 'code' query parameter provided in the HTTP request did not match the expected value.", error.Message);
|
||||
ReceiverMock.Protected()
|
||||
.Verify<Task<HttpResponseMessage>>("ExecuteWebHookAsync", Times.Never(), TestId, RequestContext, _postRequest, ItExpr.IsAny<IEnumerable<string>>(), ItExpr.IsAny<object>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("ValidIdData")]
|
||||
public async Task ReceiveAsync_Throws_IfPostIsNotJson(string id)
|
||||
{
|
||||
// Arrange
|
||||
Initialize(GetConfigValue(id, TestSecret));
|
||||
_postRequest.Content = new StringContent("Hello World!", Encoding.UTF8, "text/plain");
|
||||
|
||||
// Act
|
||||
HttpResponseException ex = await Assert.ThrowsAsync<HttpResponseException>(() => ReceiverMock.Object.ReceiveAsync(id, RequestContext, _postRequest));
|
||||
|
||||
// Assert
|
||||
HttpError error = await ex.Response.Content.ReadAsAsync<HttpError>();
|
||||
Assert.Equal("The WebHook request must contain an entity body formatted as JSON.", error.Message);
|
||||
ReceiverMock.Protected()
|
||||
.Verify<Task<HttpResponseMessage>>("ExecuteWebHookAsync", Times.Never(), id, RequestContext, _postRequest, ItExpr.IsAny<IEnumerable<string>>(), ItExpr.IsAny<object>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("ValidIdData")]
|
||||
public async Task ReceiveAsync_ReturnsError_IfPostHasNoEventTypeProperty(string id)
|
||||
{
|
||||
// Arrange
|
||||
Initialize(GetConfigValue(id, TestSecret));
|
||||
_postRequest.Content = CreateRequestContent("Microsoft.AspNet.WebHooks.Messages.bad.noEventType.json");
|
||||
|
||||
// Act
|
||||
HttpResponseMessage actual = await ReceiverMock.Object.ReceiveAsync(id, RequestContext, _postRequest);
|
||||
|
||||
// Assert
|
||||
HttpError error = await actual.Content.ReadAsAsync<HttpError>();
|
||||
Assert.Equal("No property 'eventType' was found in root of the object.", error.Message);
|
||||
ReceiverMock.Protected()
|
||||
.Verify<Task<HttpResponseMessage>>("ExecuteWebHookAsync", Times.Never(), id, RequestContext, _postRequest, ItExpr.IsAny<IEnumerable<string>>(), ItExpr.IsAny<object>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("ValidIdData")]
|
||||
public async Task ReceiveAsync_Succeeds_IfValidPostRequest(string id)
|
||||
{
|
||||
// Arrange
|
||||
Initialize(GetConfigValue(id, TestSecret));
|
||||
List<string> actions = new List<string> { TestAction };
|
||||
ReceiverMock.Protected()
|
||||
.Setup<Task<HttpResponseMessage>>("ExecuteWebHookAsync", id, RequestContext, _postRequest, actions, ItExpr.IsAny<object>())
|
||||
.ReturnsAsync(new HttpResponseMessage())
|
||||
.Verifiable();
|
||||
|
||||
// Act
|
||||
await ReceiverMock.Object.ReceiveAsync(id, RequestContext, _postRequest);
|
||||
|
||||
// Assert
|
||||
ReceiverMock.Verify();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("HEAD")]
|
||||
[InlineData("PATCH")]
|
||||
[InlineData("PUT")]
|
||||
[InlineData("OPTIONS")]
|
||||
public async Task ReceiveAsync_ReturnsError_IfInvalidMethod(string method)
|
||||
{
|
||||
// Arrange
|
||||
Initialize(TestSecret);
|
||||
HttpRequestMessage req = new HttpRequestMessage { Method = new HttpMethod(method) };
|
||||
req.SetRequestContext(RequestContext);
|
||||
|
||||
// Act
|
||||
HttpResponseMessage actual = await ReceiverMock.Object.ReceiveAsync(TestId, RequestContext, req);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.MethodNotAllowed, actual.StatusCode);
|
||||
ReceiverMock.Protected()
|
||||
.Verify<Task<HttpResponseMessage>>("ExecuteWebHookAsync", Times.Never(), TestId, RequestContext, req, ItExpr.IsAny<IEnumerable<string>>(), ItExpr.IsAny<object>());
|
||||
}
|
||||
|
||||
public override void Initialize(string config)
|
||||
{
|
||||
base.Initialize(config);
|
||||
HttpConfig.InitializeReceiveVstsWebHooks();
|
||||
|
||||
_postRequest = new HttpRequestMessage(HttpMethod.Post, TestAddress);
|
||||
_postRequest.SetRequestContext(RequestContext);
|
||||
_postRequest.Content = CreateRequestContent("Microsoft.AspNet.WebHooks.Messages.message.posted.json");
|
||||
}
|
||||
|
||||
private HttpContent CreateRequestContent(string payload)
|
||||
{
|
||||
string content = EmbeddedResource.ReadAsString(payload);
|
||||
return new StringContent(content, Encoding.UTF8, "application/json");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net45" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net45" />
|
||||
<package id="Moq" version="4.2.1502.0911" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
|
||||
<package id="StyleCop.MSBuild" version="4.7.49.1" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="xunit" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.assert" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.core" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.extensibility.core" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.runner.visualstudio" version="2.0.1" targetFramework="net45" />
|
||||
</packages>
|
|
@ -24,6 +24,7 @@
|
|||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Slack"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Stripe"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Trello"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.VSTS"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.WordPress"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Zendesk"/>
|
||||
|
||||
|
@ -51,6 +52,7 @@
|
|||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Stripe.Test"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Test"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Trello.Test"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.VSTS.Test"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.WordPress.Test"/>
|
||||
<assembly name="Microsoft.AspNet.WebHooks.Receivers.Zendesk.Test"/>
|
||||
<assembly name="Microsoft.TestUtilities"/>
|
||||
|
|
Загрузка…
Ссылка в новой задаче