diff --git a/src/Hooki.IntegrationTests/MicrosoftTeamsTests.cs b/src/Hooki.IntegrationTests/MicrosoftTeamsTests.cs index 342c6dd..d9fa25e 100644 --- a/src/Hooki.IntegrationTests/MicrosoftTeamsTests.cs +++ b/src/Hooki.IntegrationTests/MicrosoftTeamsTests.cs @@ -2,6 +2,7 @@ using IntegrationTests.Enums; using System.Net; using Hooki.MicrosoftTeams.Builders; +using Hooki.MicrosoftTeams.Enums; using Hooki.MicrosoftTeams.Models.Actions; using Hooki.MicrosoftTeams.Models.BuildingBlocks; using Hooki.MicrosoftTeams.Models.Inputs; @@ -215,7 +216,7 @@ public async Task When_Sending_MessageCard_With_ActionCard_With_An_OpenUriAction new OpenUriAction { Name = "Open URI", - Targets = [new Target { OperatingSystem = OperatingSystemTypes.Default, Uri = "https://example.com" }] + Targets = [new Target { OperatingSystem = OperatingSystemType.Default, Uri = "https://example.com" }] } ]) .Build(); diff --git a/src/Hooki.UnitTests/Hooki.UnitTests.csproj b/src/Hooki.UnitTests/Hooki.UnitTests.csproj index 74493bd..cac8f2b 100644 --- a/src/Hooki.UnitTests/Hooki.UnitTests.csproj +++ b/src/Hooki.UnitTests/Hooki.UnitTests.csproj @@ -23,7 +23,7 @@ - + diff --git a/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/SectionBuilderTests.cs b/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/SectionBuilderTests.cs index 60aa02e..5faef9c 100644 --- a/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/SectionBuilderTests.cs +++ b/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/SectionBuilderTests.cs @@ -23,7 +23,7 @@ public class SectionBuilderTests private const string Name = "Fetch"; [Fact] - public void Build_WithAllProperties_ReturnsCorrectSection() + public void Build_With_All_Properties_Returns_Correct_Section() { // Arrange var builder = new SectionBuilder() @@ -66,7 +66,7 @@ public void Build_WithAllProperties_ReturnsCorrectSection() } [Fact] - public void Build_WithMinimumProperties_ReturnsCorrectSection() + public void Build_With_Minimum_Properties_Returns_Correct_Section() { // Arrange var builder = new SectionBuilder() @@ -91,7 +91,7 @@ public void Build_WithMinimumProperties_ReturnsCorrectSection() } [Fact] - public void Build_WithNoProperties_ReturnsEmptySection() + public void Build_With_NoProperties_Returns_Empty_Section() { // Arrange var builder = new SectionBuilder(); diff --git a/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/TargetBuilderTests.cs b/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/TargetBuilderTests.cs index b966179..04f3fb0 100644 --- a/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/TargetBuilderTests.cs +++ b/src/Hooki.UnitTests/MicrosoftTeams/BuilderTests/TargetBuilderTests.cs @@ -1,6 +1,79 @@ +using FluentAssertions; +using Hooki.MicrosoftTeams.Builders; +using Hooki.MicrosoftTeams.Enums; + namespace Hooki.UnitTests.MicrosoftTeams.BuilderTests; public class TargetBuilderTests -{ - -} \ No newline at end of file + { + private const string ValidUri = "https://example.com"; + + private const OperatingSystemType DefaultOperatingSystem = OperatingSystemType.Default; + private const OperatingSystemType CustomOperatingSystem = OperatingSystemType.Android; + + [Fact] + public void Build_With_All_Properties_Returns_Correct_Target() + { + // Arrange + var builder = new TargetBuilder() + .WithOperatingSystem(CustomOperatingSystem) + .WithUri(ValidUri); + + // Act + var result = builder.Build(); + + // Assert + result.Should().NotBeNull(); + result.OperatingSystem.Should().Be(CustomOperatingSystem); + result.Uri.Should().Be(ValidUri); + } + + [Fact] + public void Build_With_Only_Uri_Returns_Target_With_Default_OS() + { + // Arrange + var builder = new TargetBuilder() + .WithUri(ValidUri); + + // Act + var result = builder.Build(); + + // Assert + result.Should().NotBeNull(); + result.OperatingSystem.Should().Be(DefaultOperatingSystem); + result.Uri.Should().Be(ValidUri); + } + + [Fact] + public void Build_Without_Uri_Throws_InvalidOperationException() + { + // Arrange + var builder = new TargetBuilder() + .WithOperatingSystem(CustomOperatingSystem); + + // Act & Assert + builder.Invoking(b => b.Build()) + .Should().Throw() + .WithMessage("Uri is required for Target."); + } + + [Theory] + [InlineData(OperatingSystemType.IOS)] + [InlineData(OperatingSystemType.Android)] + [InlineData(OperatingSystemType.Windows)] + public void Build_With_Different_OS_Types_Returns_Correct_Target(OperatingSystemType osType) + { + // Arrange + var builder = new TargetBuilder() + .WithOperatingSystem(osType) + .WithUri(ValidUri); + + // Act + var result = builder.Build(); + + // Assert + result.Should().NotBeNull(); + result.OperatingSystem.Should().Be(osType); + result.Uri.Should().Be(ValidUri); + } + } \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Builders/ActionBuilderBase.cs b/src/Hooki/MicrosoftTeams/Builders/ActionBuilderBase.cs index 6da6f2f..ecada4c 100644 --- a/src/Hooki/MicrosoftTeams/Builders/ActionBuilderBase.cs +++ b/src/Hooki/MicrosoftTeams/Builders/ActionBuilderBase.cs @@ -1,3 +1,4 @@ +using Hooki.MicrosoftTeams.Enums; using Hooki.MicrosoftTeams.Models.Actions; using Hooki.MicrosoftTeams.Models.BuildingBlocks; using Hooki.MicrosoftTeams.Models.Inputs; @@ -13,7 +14,7 @@ public TBuilder AddOpenUriAction(string name, string uri) PotentialActions.Add(new OpenUriAction { Name = name, - Targets = [new Target { OperatingSystem = OperatingSystemTypes.Default, Uri = uri }] + Targets = [new Target { OperatingSystem = OperatingSystemType.Default, Uri = uri }] }); return (TBuilder)this; } diff --git a/src/Hooki/MicrosoftTeams/Builders/TargetBuilder.cs b/src/Hooki/MicrosoftTeams/Builders/TargetBuilder.cs index 4ed006c..b5b40f9 100644 --- a/src/Hooki/MicrosoftTeams/Builders/TargetBuilder.cs +++ b/src/Hooki/MicrosoftTeams/Builders/TargetBuilder.cs @@ -1,13 +1,14 @@ +using Hooki.MicrosoftTeams.Enums; using Hooki.MicrosoftTeams.Models.BuildingBlocks; namespace Hooki.MicrosoftTeams.Builders; public class TargetBuilder { - private OperatingSystemTypes _operatingSystem; + private OperatingSystemType _operatingSystem; private string? _uri; - public TargetBuilder WithOperatingSystem(OperatingSystemTypes operatingSystem) + public TargetBuilder WithOperatingSystem(OperatingSystemType operatingSystem) { _operatingSystem = operatingSystem; return this; diff --git a/src/Hooki/MicrosoftTeams/Enums/OperatingSystemType.cs b/src/Hooki/MicrosoftTeams/Enums/OperatingSystemType.cs new file mode 100644 index 0000000..9d2db9d --- /dev/null +++ b/src/Hooki/MicrosoftTeams/Enums/OperatingSystemType.cs @@ -0,0 +1,21 @@ +using System.Runtime.Serialization; +using System.Text.Json.Serialization; + +namespace Hooki.MicrosoftTeams.Enums; + +//ToDo: Refactor this in .NET 9 with new attribute: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumMemberNameAttribute.cs +[JsonConverter(typeof(JsonStringEnumMemberConverter))] +public enum OperatingSystemType +{ + [EnumMember(Value = "default")] + Default, + + [EnumMember(Value = "iOS")] + IOS, + + [EnumMember(Value = "android")] + Android, + + [EnumMember(Value = "windows")] + Windows +} \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Models/Actions/InvokeAddInCommandAction.cs b/src/Hooki/MicrosoftTeams/Models/Actions/InvokeAddInCommandAction.cs index 9b17e49..9694756 100644 --- a/src/Hooki/MicrosoftTeams/Models/Actions/InvokeAddInCommandAction.cs +++ b/src/Hooki/MicrosoftTeams/Models/Actions/InvokeAddInCommandAction.cs @@ -7,9 +7,9 @@ public class InvokeAddInCommandAction : ActionBase { public override ActionType Type => ActionType.InvokeAddInCommand; - [JsonPropertyName("addInId")] public string AddInId { get; set; } = default!; + [JsonPropertyName("addInId")] public required string AddInId { get; set; } - [JsonPropertyName("desktopCommandId")] public string DesktopCommandId { get; set; } = default!; + [JsonPropertyName("desktopCommandId")] public required string DesktopCommandId { get; set; } [JsonPropertyName("initializationContext")] public object? InitializationContext { get; set; } } \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Models/Actions/OpenUriAction.cs b/src/Hooki/MicrosoftTeams/Models/Actions/OpenUriAction.cs index b32d8e6..0223692 100644 --- a/src/Hooki/MicrosoftTeams/Models/Actions/OpenUriAction.cs +++ b/src/Hooki/MicrosoftTeams/Models/Actions/OpenUriAction.cs @@ -8,5 +8,5 @@ public class OpenUriAction : ActionBase { public override ActionType Type => ActionType.OpenUri; - [JsonPropertyName("targets")] public List Targets { get; set; } = []; + [JsonPropertyName("targets")] public required List Targets { get; set; } } \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Models/BuildingBlocks/Target.cs b/src/Hooki/MicrosoftTeams/Models/BuildingBlocks/Target.cs index 1c3d5df..d9d85c0 100644 --- a/src/Hooki/MicrosoftTeams/Models/BuildingBlocks/Target.cs +++ b/src/Hooki/MicrosoftTeams/Models/BuildingBlocks/Target.cs @@ -1,28 +1,12 @@ using System.Runtime.Serialization; using System.Text.Json.Serialization; +using Hooki.MicrosoftTeams.Enums; namespace Hooki.MicrosoftTeams.Models.BuildingBlocks; public class Target { - [JsonPropertyName("os")] public required OperatingSystemTypes OperatingSystem { get; set; } = OperatingSystemTypes.Default; + [JsonPropertyName("os")] public required OperatingSystemType OperatingSystem { get; set; } = OperatingSystemType.Default; [JsonPropertyName("uri")] public required string Uri { get; set; } -} - -//ToDo: Refactor this in .NET 9 with new attribute: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumMemberNameAttribute.cs -[JsonConverter(typeof(JsonStringEnumMemberConverter))] -public enum OperatingSystemTypes -{ - [EnumMember(Value = "default")] - Default, - - [EnumMember(Value = "iOS")] - Ios, - - [EnumMember(Value = "android")] - Android, - - [EnumMember(Value = "windows")] - Windows } \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Models/Inputs/Choice.cs b/src/Hooki/MicrosoftTeams/Models/Inputs/Choice.cs index be65e1e..cbaca2e 100644 --- a/src/Hooki/MicrosoftTeams/Models/Inputs/Choice.cs +++ b/src/Hooki/MicrosoftTeams/Models/Inputs/Choice.cs @@ -4,7 +4,7 @@ namespace Hooki.MicrosoftTeams.Models.Inputs; public class Choice { - [JsonPropertyName("display")] public string Display { get; set; } = default!; + [JsonPropertyName("display")] public required string Display { get; set; } - [JsonPropertyName("value")] public string Value { get; set; } = default!; + [JsonPropertyName("value")] public required string Value { get; set; } } \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Models/Inputs/InputBase.cs b/src/Hooki/MicrosoftTeams/Models/Inputs/InputBase.cs index e183ea7..284c8cc 100644 --- a/src/Hooki/MicrosoftTeams/Models/Inputs/InputBase.cs +++ b/src/Hooki/MicrosoftTeams/Models/Inputs/InputBase.cs @@ -9,11 +9,11 @@ public abstract class InputBase { [JsonPropertyName("@type")] public abstract InputType Type { get; } - [JsonPropertyName("id")] public string Id { get; set; } = default!; + [JsonPropertyName("id")] public required string Id { get; set; } [JsonPropertyName("isRequired")] public bool? IsRequired { get; set; } - [JsonPropertyName("title")] public string Title { get; set; } = default!; + [JsonPropertyName("title")] public required string Title { get; set; } - [JsonPropertyName("value")] public string Value { get; set; } = default!; + [JsonPropertyName("value")] public string? Value { get; set; } } \ No newline at end of file diff --git a/src/Hooki/MicrosoftTeams/Models/Inputs/TextInput.cs b/src/Hooki/MicrosoftTeams/Models/Inputs/TextInput.cs index 0795dca..5bddebb 100644 --- a/src/Hooki/MicrosoftTeams/Models/Inputs/TextInput.cs +++ b/src/Hooki/MicrosoftTeams/Models/Inputs/TextInput.cs @@ -7,9 +7,7 @@ public class TextInput : InputBase { public override InputType Type => InputType.TextInput; - [JsonPropertyName("isMultiline")] - public bool? IsMultiline { get; set; } + [JsonPropertyName("isMultiline")] public bool? IsMultiline { get; set; } - [JsonPropertyName("maxLength")] - public int? MaxLength { get; set; } + [JsonPropertyName("maxLength")] public int? MaxLength { get; set; } } \ No newline at end of file