Skip to content

Commit 7a44dba

Browse files
Merge pull request #1 from SkylineCommunications/InitialDevelopment
Initial Development
2 parents 13668c7 + 8d64f20 commit 7a44dba

19 files changed

+1112
-0
lines changed

.editorconfig

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 4
6+
trim_trailing_whitespace = true
7+
8+
[*.csproj]
9+
indent_size = 2
10+
11+
[*.cs]
12+
dotnet_sort_system_directives_first = true
13+
dotnet_style_predefined_type_for_locals_parameters_members = true
14+
dotnet_style_predefined_type_for_member_access = false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>net48;net8.0</TargetFrameworks>
4+
<ImplicitUsings>disable</ImplicitUsings>
5+
<Nullable>disable</Nullable>
6+
7+
<IsPackable>false</IsPackable>
8+
<IsTestProject>true</IsTestProject>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
14+
<PackageReference Include="MSTest.TestAdapter" Version="3.5.0" />
15+
<PackageReference Include="MSTest.TestFramework" Version="3.5.0" />
16+
<PackageReference Include="coverlet.collector" Version="6.0.2">
17+
<PrivateAssets>all</PrivateAssets>
18+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
19+
</PackageReference>
20+
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
21+
<PackageReference Include="Serilog" Version="4.0.0" />
22+
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
23+
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
24+
</ItemGroup>
25+
26+
<ItemGroup>
27+
<ProjectReference Include="..\Skyline.DataMiner.CICD.Tools.MSTeamsWorkflowWebhookCard.Lib\CICD.Tools.MSTeamsWorkflowWebhookCard.Lib.csproj" />
28+
</ItemGroup>
29+
30+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
namespace CICD.Tools.MSTeamsWorkflowWebhookCard.LibTests
2+
{
3+
using System.Net.Http;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
using CICD.Tools.MSTeamsWorkflowWebhookCard.LibTests.MatchTeamsRequirement;
8+
9+
using Microsoft.Extensions.Logging;
10+
using Microsoft.VisualStudio.TestTools.UnitTesting;
11+
12+
using RichardSzalay.MockHttp;
13+
14+
using Serilog;
15+
16+
using Skyline.DataMiner.CICD.Tools.MSTeamsWorkflowWebhookCard.Lib;
17+
18+
[TestClass]
19+
public class CicdCardTests
20+
{
21+
[TestMethod]
22+
public async Task SendAsyncTest_TestFormatIsValidForTeams()
23+
{
24+
// Arrange
25+
var mockHttp = new MockHttpMessageHandler();
26+
27+
var logConfig = new LoggerConfiguration().WriteTo.Console();
28+
logConfig.MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug);
29+
var seriLog = logConfig.CreateLogger();
30+
31+
using (var loggerFactory = LoggerFactory.Create(builder => builder.AddSerilog(seriLog)))
32+
{
33+
var logger = loggerFactory.CreateLogger("Skyline.DataMiner.CICD.Tools.MSTeamsWorkflowWebhookCard");
34+
35+
const string name = "TestPipeline";
36+
const CicdResult result = CicdResult.Success;
37+
const string details = "Some Details";
38+
const string pathToBuild = "https://skyline.be/skyline/about";
39+
const string iconOfService = "https://skyline.be/skylicons/duotone/SkylineLogo_Duo_Light.png";
40+
const string url = "https://skyline.be/";
41+
42+
var matcher = new TeamsAdaptiveCardMatcher(logger);
43+
var responseContent = new StringContent("OK", Encoding.UTF8, "application/string");
44+
mockHttp.When(HttpMethod.Post, url).With(matcher).Respond(System.Net.HttpStatusCode.OK, responseContent);
45+
46+
using (var client = mockHttp.ToHttpClient())
47+
{
48+
// Act
49+
var card = new CicdCard(logger, client);
50+
card.ApplyConfiguration(name, result, details, pathToBuild, iconOfService);
51+
await card.SendAsync(url);
52+
53+
// Assert
54+
mockHttp.VerifyNoOutstandingExpectation();
55+
}
56+
}
57+
}
58+
59+
[TestMethod, Ignore("For Manual Running. Fill in a valid webhook url to a teams workflow.")]
60+
public async Task SendAsyncTest_IntegrationTest()
61+
{
62+
// Arrange
63+
var logConfig = new LoggerConfiguration().WriteTo.Console();
64+
logConfig.MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug);
65+
var seriLog = logConfig.CreateLogger();
66+
67+
using (var loggerFactory = LoggerFactory.Create(builder => builder.AddSerilog(seriLog)))
68+
{
69+
var logger = loggerFactory.CreateLogger("Skyline.DataMiner.CICD.Tools.MSTeamsWorkflowWebhookCard");
70+
71+
const string name = "IntegrationTestPipeline";
72+
const CicdResult result = CicdResult.Success;
73+
const string details = "This is an integration test running from the testbattery. \r\n This should be on a second line!";
74+
const string pathToBuild = "https://github.com/SkylineCommunications/Skyline.DataMiner.CICD.Tools.MSTeamsWorkflowWebhookCard";
75+
const string iconOfService = "https://skyline.be/skylicons/duotone/SkylineLogo_Duo_Light.png";
76+
const string url = "EnterWebHookFromTeamsChannelHere";
77+
78+
using (HttpClient client = new HttpClient())
79+
{
80+
// Act
81+
var card = new CicdCard(logger, client);
82+
card.ApplyConfiguration(name, result, details, pathToBuild, iconOfService);
83+
await card.SendAsync(url);
84+
85+
// Assert
86+
87+
// Manual Verification of content as this is Graphical Design.
88+
Assert.IsTrue(true);
89+
}
90+
}
91+
}
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
namespace CICD.Tools.MSTeamsWorkflowWebhookCard.LibTests.MatchTeamsRequirement
2+
{
3+
using System.Collections.Generic;
4+
5+
/// <summary>
6+
/// Represents an action in a body element.
7+
/// </summary>
8+
public class Action
9+
{
10+
/// <summary>
11+
/// Gets or sets the title of the action.
12+
/// </summary>
13+
public string Title { get; set; }
14+
15+
/// <summary>
16+
/// Gets or sets the type of the action.
17+
/// </summary>
18+
public string Type { get; set; }
19+
20+
/// <summary>
21+
/// Gets or sets the URL associated with the action.
22+
/// </summary>
23+
public string Url { get; set; }
24+
}
25+
26+
/// <summary>
27+
/// Represents an attachment in a Teams message.
28+
/// </summary>
29+
public class Attachment
30+
{
31+
/// <summary>
32+
/// Gets or sets the content of the attachment.
33+
/// </summary>
34+
public Content Content { get; set; }
35+
36+
/// <summary>
37+
/// Gets or sets the content type of the attachment.
38+
/// </summary>
39+
public string ContentType { get; set; }
40+
}
41+
42+
/// <summary>
43+
/// Represents an element in the body of an attachment content.
44+
/// </summary>
45+
public class BodyElement
46+
{
47+
/// <summary>
48+
/// Gets or sets the list of actions in the body element.
49+
/// </summary>
50+
public List<Action> Actions { get; set; }
51+
52+
/// <summary>
53+
/// Gets or sets the alternative text for the body element.
54+
/// </summary>
55+
public string AltText { get; set; }
56+
57+
/// <summary>
58+
/// Gets or sets the list of columns in the body element.
59+
/// </summary>
60+
public List<Column> Columns { get; set; }
61+
62+
/// <summary>
63+
/// Gets or sets the list of facts in the body element.
64+
/// </summary>
65+
public List<Fact> Facts { get; set; }
66+
67+
/// <summary>
68+
/// Gets or sets the list of items in the body element.
69+
/// </summary>
70+
public List<Item> Items { get; set; }
71+
72+
/// <summary>
73+
/// Gets or sets the size of the body element.
74+
/// </summary>
75+
public string Size { get; set; }
76+
77+
/// <summary>
78+
/// Gets or sets the text of the body element.
79+
/// </summary>
80+
public string Text { get; set; }
81+
82+
/// <summary>
83+
/// Gets or sets the type of the body element.
84+
/// </summary>
85+
public string Type { get; set; }
86+
87+
/// <summary>
88+
/// Gets or sets the URL associated with the body element.
89+
/// </summary>
90+
public string Url { get; set; }
91+
92+
/// <summary>
93+
/// Gets or sets the width of the body element.
94+
/// </summary>
95+
public string Width { get; set; }
96+
97+
/// <summary>
98+
/// Gets or sets a value indicating whether the text should wrap.
99+
/// </summary>
100+
public bool Wrap { get; set; }
101+
}
102+
103+
/// <summary>
104+
/// Represents a column in a body element.
105+
/// </summary>
106+
public class Column
107+
{
108+
/// <summary>
109+
/// Gets or sets the list of items in the column.
110+
/// </summary>
111+
public List<Item> Items { get; set; }
112+
113+
/// <summary>
114+
/// Gets or sets the type of the column.
115+
/// </summary>
116+
public string Type { get; set; }
117+
118+
/// <summary>
119+
/// Gets or sets the width of the column.
120+
/// </summary>
121+
public string Width { get; set; }
122+
}
123+
124+
/// <summary>
125+
/// Represents the content of an attachment.
126+
/// </summary>
127+
public class Content
128+
{
129+
/// <summary>
130+
/// Gets or sets the list of body elements in the content.
131+
/// </summary>
132+
public List<BodyElement> Body { get; set; }
133+
134+
/// <summary>
135+
/// Gets or sets the type of the content.
136+
/// </summary>
137+
public string Type { get; set; }
138+
139+
/// <summary>
140+
/// Gets or sets the version of the content.
141+
/// </summary>
142+
public string Version { get; set; }
143+
}
144+
145+
/// <summary>
146+
/// Represents a fact in a body element.
147+
/// </summary>
148+
public class Fact
149+
{
150+
/// <summary>
151+
/// Gets or sets the title of the fact.
152+
/// </summary>
153+
public string Title { get; set; }
154+
155+
/// <summary>
156+
/// Gets or sets the value of the fact.
157+
/// </summary>
158+
public string Value { get; set; }
159+
}
160+
161+
/// <summary>
162+
/// Represents an item in a body element or column.
163+
/// </summary>
164+
public class Item
165+
{
166+
/// <summary>
167+
/// Gets or sets the alternative text for the item.
168+
/// </summary>
169+
public string AltText { get; set; }
170+
171+
/// <summary>
172+
/// Gets or sets the size of the item.
173+
/// </summary>
174+
public string Size { get; set; }
175+
176+
/// <summary>
177+
/// Gets or sets the text of the item.
178+
/// </summary>
179+
public string Text { get; set; }
180+
181+
/// <summary>
182+
/// Gets or sets the type of the item.
183+
/// </summary>
184+
public string Type { get; set; }
185+
186+
/// <summary>
187+
/// Gets or sets the URL associated with the item.
188+
/// </summary>
189+
public string Url { get; set; }
190+
191+
/// <summary>
192+
/// Gets or sets the weight of the item.
193+
/// </summary>
194+
public string Weight { get; set; }
195+
196+
/// <summary>
197+
/// Gets or sets a value indicating whether the text should wrap.
198+
/// </summary>
199+
public bool Wrap { get; set; }
200+
}
201+
202+
/// <summary>
203+
/// Represents a Teams message.
204+
/// </summary>
205+
public class Message
206+
{
207+
/// <summary>
208+
/// Gets or sets the list of attachments in the message.
209+
/// </summary>
210+
public List<Attachment> Attachments { get; set; }
211+
212+
/// <summary>
213+
/// Gets or sets the type of the message.
214+
/// </summary>
215+
public string Type { get; set; }
216+
}
217+
}

0 commit comments

Comments
 (0)