Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ADotNet/ADotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Xeption" Version="1.7.0" />
<PackageReference Include="YamlDotNet" Version="11.2.1" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xeptions;

namespace ADotNet.Models.Pipelines.Releases.GithubPipelines.Exceptions
{
public class NullReleasePathException : Xeption
{
public NullReleasePathException()
: base(message: "Release path is null.")
{ }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using Xeptions;

namespace ADotNet.Models.Pipelines.Releases.GithubPipelines.Exceptions
{
public class NullReleasePipelineException : Xeption
{
public NullReleasePipelineException()
: base(message: "Release pipeline is null.")
{ }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xeptions;

namespace ADotNet.Models.Pipelines.Releases.GithubPipelines.Exceptions
{
public class ReleaseValidationException : Xeption
{
public ReleaseValidationException(Xeption innerException)
: base(message: "Release validation error occurred, fix the errors and try again.",
innerException)
{ }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

namespace ADotNet.Models.Pipelines.Releases.GithubPipelines
{
public class GithubReleasePipeline
{
}
}
13 changes: 13 additions & 0 deletions ADotNet/Services/Releases/IReleaseService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

namespace ADotNet.Services.Releases
{
public interface IReleaseService
{
void SerializeWriteToFile(string path, object releasePipeline);
}
}
31 changes: 31 additions & 0 deletions ADotNet/Services/Releases/ReleaseService.Exceptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using ADotNet.Models.Pipelines.Releases.GithubPipelines.Exceptions;

namespace ADotNet.Services.Releases
{
public partial class ReleaseService
{
private delegate void ReturningNothingFunction();

private void TryCatch(ReturningNothingFunction returningNothingFunction)
{
try
{
returningNothingFunction();
}
catch (NullReleasePathException nullReleasePathException)
{
throw new ReleaseValidationException(nullReleasePathException);
}
catch (NullReleasePipelineException nullReleasePipelineException)
{
throw new ReleaseValidationException(nullReleasePipelineException);
}
}
}
}
26 changes: 26 additions & 0 deletions ADotNet/Services/Releases/ReleaseService.Validations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using ADotNet.Models.Pipelines.Releases.GithubPipelines;
using ADotNet.Models.Pipelines.Releases.GithubPipelines.Exceptions;

namespace ADotNet.Services.Releases
{
public partial class ReleaseService
{
private static void ValidateInputs(string path, object pipeline)
{
switch(path, pipeline)
{
case (null, _):
throw new NullReleasePathException();

case (_, null):
throw new NullReleasePipelineException();
}
}
}
}
39 changes: 39 additions & 0 deletions ADotNet/Services/Releases/ReleaseService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System;
using ADotNet.Brokers.IOs;
using ADotNet.Brokers.Serializers;

namespace ADotNet.Services.Releases
{
public partial class ReleaseService : IReleaseService
{
private readonly IYamlBroker yamlBroker;
private readonly IFilesBroker filesBroker;

public ReleaseService(
IYamlBroker yamlBroker,
IFilesBroker filesBroker)
{
this.yamlBroker = yamlBroker;
this.filesBroker = filesBroker;
}

public void SerializeWriteToFile(string path, object releasePipeline) =>
TryCatch(() =>
{
ValidateInputs(path, releasePipeline);

string serializedPipeline =
this.yamlBroker.SerializeToYaml(releasePipeline);

this.filesBroker.WriteToFile(
path,
data: serializedPipeline);
});
}
}
2 changes: 1 addition & 1 deletion AdoNet.Tests.Unit/AdoNet.Tests.Unit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0-preview-20211130-02" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="Tynamix.ObjectFiller" Version="1.5.7" />
<PackageReference Include="xunit" Version="2.4.2-pre.12" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using ADotNet.Models.Pipelines.Releases.GithubPipelines;
using Moq;
using Xunit;

namespace AdoNet.Tests.Unit.Services.Foundations.Releases
{
public partial class ReleaseServiceTests
{
[Fact]
public void ShouldSerializeWriteReleasePipeline()
{
// given
string randomSerializedPipeline = CreateRandomString();
string serializedGithubPipeline = randomSerializedPipeline;
string randomPath = CreateRandomString();
string inputPath = randomPath;

GithubReleasePipeline randomGithubReleasePipeline =
CreateRandomReleasePipeline();

GithubReleasePipeline inputGithubReleasePipeline =
randomGithubReleasePipeline;

this.yamlBrokerMock.Setup(broker =>
broker.SerializeToYaml(inputGithubReleasePipeline))
.Returns(serializedGithubPipeline);

// when
this.releaseService.SerializeWriteToFile(
inputPath,
inputGithubReleasePipeline);

// then

this.yamlBrokerMock.Verify(broker =>
broker.SerializeToYaml(inputGithubReleasePipeline),
Times.Once);

this.filesBrokerMock.Verify(broker =>
broker.WriteToFile(inputPath, serializedGithubPipeline),
Times.Once);

this.yamlBrokerMock.VerifyNoOtherCalls();
this.filesBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using System;
using ADotNet.Models.Pipelines.Releases.GithubPipelines;
using ADotNet.Models.Pipelines.Releases.GithubPipelines.Exceptions;
using Moq;
using Xunit;

namespace AdoNet.Tests.Unit.Services.Foundations.Releases
{
public partial class ReleaseServiceTests
{
[Fact]
public void ShouldThrowValidationExceptionOnSerializeWriteIfPathIsNull()
{
// given
string invalidPath = null;

GithubReleasePipeline someReleasePipeline =
CreateRandomReleasePipeline();

var nullReleasePathException =
new NullReleasePathException();

var expectedReleaseValidationException =
new ReleaseValidationException(
nullReleasePathException);

// when
Action serializeWriteAction = () =>
this.releaseService.SerializeWriteToFile(invalidPath, someReleasePipeline);

// then
Assert.Throws<ReleaseValidationException>(serializeWriteAction);

this.yamlBrokerMock.Verify(broker =>
broker.SerializeToYaml(It.IsAny<Object>()),
Times.Never);

this.filesBrokerMock.Verify(broker =>
broker.WriteToFile(It.IsAny<string>(), It.IsAny<string>()),
Times.Never);

this.yamlBrokerMock.VerifyNoOtherCalls();
this.filesBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowValidationExceptionOnSerializeWriteIfPipelineIsNull()
{
// given
GithubReleasePipeline invalidGithubReleasePipeline = null;
string somePath = CreateRandomString();

var nullReleasePipelineException =
new NullReleasePipelineException();

var expectedReleaseValidationException =
new ReleaseValidationException(
nullReleasePipelineException);

// when
Action serializeWriteAction = () =>
this.releaseService.SerializeWriteToFile(
somePath,
invalidGithubReleasePipeline);

// then
Assert.Throws<ReleaseValidationException>(serializeWriteAction);

this.yamlBrokerMock.Verify(broker =>
broker.SerializeToYaml(It.IsAny<Object>()),
Times.Never);

this.filesBrokerMock.Verify(broker =>
broker.WriteToFile(It.IsAny<string>(), It.IsAny<string>()),
Times.Never);

this.yamlBrokerMock.VerifyNoOtherCalls();
this.filesBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// ---------------------------------------------------------------
// Copyright (c) Hassan Habib All rights reserved.
// Licensed under the MIT License.
// See License.txt in the project root for license information.
// ---------------------------------------------------------------

using ADotNet.Brokers.IOs;
using ADotNet.Brokers.Serializers;
using ADotNet.Models.Pipelines.Releases.GithubPipelines;
using ADotNet.Services.Releases;
using Moq;
using Tynamix.ObjectFiller;

namespace AdoNet.Tests.Unit.Services.Foundations.Releases
{
public partial class ReleaseServiceTests
{
private readonly Mock<IYamlBroker> yamlBrokerMock;
private readonly Mock<IFilesBroker> filesBrokerMock;
private readonly IReleaseService releaseService;

public ReleaseServiceTests()
{
this.yamlBrokerMock = new Mock<IYamlBroker>();
this.filesBrokerMock = new Mock<IFilesBroker>();

this.releaseService = new ReleaseService(
yamlBroker: this.yamlBrokerMock.Object,
filesBroker: this.filesBrokerMock.Object);
}

private static string CreateRandomString() =>
new MnemonicString(wordCount: GetRandomNumber()).GetValue();

private static GithubReleasePipeline CreateRandomReleasePipeline() =>
CreateGithubReleasePipelineFiller().Create();

private static int GetRandomNumber() =>
new IntRange(min: 2, max: 10).GetValue();

private static Filler<GithubReleasePipeline> CreateGithubReleasePipelineFiller() =>
new Filler<GithubReleasePipeline>();
}
}