Skip to content

Commit

Permalink
Added support with Fluent Assertions (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrDave1999 authored Apr 16, 2023
1 parent 4366f54 commit cdf58b9
Show file tree
Hide file tree
Showing 15 changed files with 1,216 additions and 813 deletions.
221 changes: 121 additions & 100 deletions tests/Binder/EnvBinderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,209 +4,228 @@ namespace DotEnv.Core.Tests.Binder;
public class EnvBinderTests
{
[TestMethod]
public void Bind_WhenPropertyNameDoesNotMatchRealKey_ShouldReturnSettingsInstance()
public void Bind_WhenPropertyNameDoesNotMatchRealKey_ShouldReturnsSettingsInstance()
{
// Arrange
var binder = new EnvBinder();
SetEnvironmentVariable("REAL_KEY", "1234D");

var settings = new EnvBinder().Bind<SettingsExample0>();
// Act
var settings = binder.Bind<SettingsExample0>();

Assert.AreEqual(expected: "1234D", actual: settings.RealKey);
// Assert
settings.RealKey.Should().Be("1234D");
}

[TestMethod]
public void Bind_WhenPropertiesAreLinkedToTheDefaultProviderInstance_ShouldReturnSettingsInstance()
public void Bind_WhenPropertiesAreLinkedToTheDefaultProviderInstance_ShouldReturnsSettingsInstance()
{
// Arrange
var binder = new EnvBinder();
SetEnvironmentVariable("BIND_JWT_SECRET", "12example");
SetEnvironmentVariable("BIND_TOKEN_ID", "e32d");
SetEnvironmentVariable("BIND_RACE_TIME", "23");
SetEnvironmentVariable("BindSecretKey", "12example");
SetEnvironmentVariable("BindJwtSecret", "secret123");
SetEnvironmentVariable("COLOR_NAME", "RED");

var settings = new EnvBinder().Bind<AppSettings>();
// Act
var settings = binder.Bind<AppSettings>();

Assert.AreEqual(expected: "12example", actual: settings.JwtSecret);
Assert.AreEqual(expected: "e32d", actual: settings.TokenId);
Assert.AreEqual(expected: 23, actual: settings.RaceTime);
Assert.AreEqual(expected: "12example", actual: settings.BindSecretKey);
Assert.AreEqual(expected: "secret123", actual: settings.BindJwtSecret);
Assert.AreEqual(expected: "Red", actual: settings.ColorName.ToString());
// Asserts
settings.JwtSecret.Should().Be("12example");
settings.TokenId.Should().Be("e32d");
settings.RaceTime.Should().Be(23);
settings.BindSecretKey.Should().Be("12example");
settings.BindJwtSecret.Should().Be("secret123");
settings.ColorName.Should().Be(Colors.Red);
}

[TestMethod]
public void Bind_WhenPropertiesAreLinkedToTheCustomProviderInstance_ShouldReturnSettingsInstance()
public void Bind_WhenPropertiesAreLinkedToTheCustomProviderInstance_ShouldReturnsSettingsInstance()
{
// Arrange
var customProvider = new CustomEnvironmentVariablesProvider();
var binder = new EnvBinder(customProvider);
customProvider["BIND_JWT_SECRET"] = "13example";
customProvider["BIND_TOKEN_ID"] = "e31d";
customProvider["BIND_RACE_TIME"] = "24";
customProvider["BindSecretKey"] = "13example";
customProvider["BindJwtSecret"] = "secret124";
customProvider["COLOR_NAME"] = "RED";

var settings = new EnvBinder(customProvider).Bind<AppSettings>();
// Act
var settings = binder.Bind<AppSettings>();

Assert.AreEqual(expected: "13example", actual: settings.JwtSecret);
Assert.AreEqual(expected: "e31d", actual: settings.TokenId);
Assert.AreEqual(expected: 24, actual: settings.RaceTime);
Assert.AreEqual(expected: "13example", actual: settings.BindSecretKey);
Assert.AreEqual(expected: "secret124", actual: settings.BindJwtSecret);
Assert.AreEqual(expected: "Red", actual: settings.ColorName.ToString());
// Asserts
settings.JwtSecret.Should().Be("13example");
settings.TokenId.Should().Be("e31d");
settings.RaceTime.Should().Be(24);
settings.BindSecretKey.Should().Be("13example");
settings.BindJwtSecret.Should().Be("secret124");
settings.ColorName.Should().Be(Colors.Red);
}

[TestMethod]
public void Bind_WhenPropertyDoesNotMatchConfigurationKey_ShouldThrowBinderException()
{
// Arrange
var binder = new EnvBinder();

void action() => binder.Bind<SettingsExample1>();

var ex = Assert.ThrowsException<BinderException>(action);
StringAssert.Contains(ex.Message, string.Format(
var expectedMessage = string.Format(
PropertyDoesNotMatchConfigKeyMessage,
nameof(SettingsExample1),
nameof(SettingsExample1.SecretKey)
));
);

// Act
Action act = () => binder.Bind<SettingsExample1>();

// Assert
act.Should()
.Throw<BinderException>()
.WithMessage(expectedMessage);
}

[TestMethod]
public void Bind_WhenKeyAssignedToThePropertyIsNotSet_ShouldThrowBinderException()
{
// Arrange
var binder = new EnvBinder();
var expectedMessage = string.Format(
KeyAssignedToPropertyIsNotSetMessage,
nameof(SettingsExample2),
nameof(SettingsExample2.SecretKey),
"SECRET_KEY"
);

void action() => binder.Bind<SettingsExample2>();
// Act
Action act = () => binder.Bind<SettingsExample2>();

var ex = Assert.ThrowsException<BinderException>(action);
StringAssert.Contains(ex.Message, string.Format(
KeyAssignedToPropertyIsNotSetMessage,
nameof(SettingsExample2),
nameof(SettingsExample2.SecretKey),
"SECRET_KEY"
));
// Assert
act.Should()
.Throw<BinderException>()
.WithMessage(expectedMessage);
}

[TestMethod]
public void Bind_WhenConfigurationValueCannotBeConvertedToAnotherDataType_ShouldThrowBinderException()
{
// Arrange
var binder = new EnvBinder();
SetEnvironmentVariable("BIND_WEATHER_ID", "This is not an int");
SetEnvironmentVariable("COLOR_NAME", "Red");
var expectedMessage = string.Format(
FailedConvertConfigurationValueMessage,
"BIND_WEATHER_ID",
nameof(Int32),
"This is not an int",
nameof(Int32)
);

void action() => binder.Bind<SettingsExample3>();
// Act
Action act = () => binder.Bind<SettingsExample3>();

var ex = Assert.ThrowsException<BinderException>(action);
StringAssert.Contains(ex.Message, string.Format(
FailedConvertConfigurationValueMessage,
"BIND_WEATHER_ID",
nameof(Int32),
"This is not an int",
nameof(Int32)
));
// Assert
act.Should()
.Throw<BinderException>()
.WithMessage(expectedMessage);
}

[TestMethod]
public void Bind_WhenKeyCannotBeConvertedToEnum_ShouldThrowBinderException()
{
// Arrange
var binder = new EnvBinder();
SetEnvironmentVariable("BIND_WEATHER_ID", "1");
SetEnvironmentVariable("COLOR_NAME", "Yellow");

void action() => binder.Bind<SettingsExample3>();

var ex = Assert.ThrowsException<BinderException>(action);
StringAssert.Contains(ex.Message, string.Format(
var expectedMessage = string.Format(
FailedConvertConfigurationValueMessage,
"COLOR_NAME",
nameof(Colors),
"Yellow",
nameof(Colors)
));
);

// Act
Action act = () => binder.Bind<SettingsExample3>();

// Assert
act.Should()
.Throw<BinderException>()
.WithMessage(expectedMessage);
}

[TestMethod]
public void Bind_WhenAnErrorIsFound_ShouldStoreErrorMessageInCollection()
{
string msg;
// Arrange
var customProvider = new CustomEnvironmentVariablesProvider();
var binder = new EnvBinder(customProvider).IgnoreException();
customProvider["BIND_RACE_TIME"] = "This is not an int";
customProvider["ColorName"] = "Yellow";

var expectedErrors = new List<string>
{
string.Format(KeyAssignedToPropertyIsNotSetMessage,
nameof(AppSettings), nameof(AppSettings.JwtSecret), "BIND_JWT_SECRET"),
string.Format(KeyAssignedToPropertyIsNotSetMessage,
nameof(AppSettings), nameof(AppSettings.TokenId), "BIND_TOKEN_ID"),
string.Format(FailedConvertConfigurationValueMessage,
"BIND_RACE_TIME", nameof(Int32), "This is not an int", nameof(Int32)),
string.Format(FailedConvertConfigurationValueMessage,
"ColorName", nameof(Colors), "Yellow", nameof(Colors)),
string.Format(PropertyDoesNotMatchConfigKeyMessage,
nameof(AppSettings), nameof(AppSettings.BindSecretKey)),
string.Format(PropertyDoesNotMatchConfigKeyMessage,
nameof(AppSettings), nameof(AppSettings.BindJwtSecret))
};

// Act
binder.Bind<AppSettings>(out var result);
var errors = result.ToList();

Assert.AreEqual(expected: true, actual: result.HasError());
Assert.AreEqual(expected: 6, actual: result.Count);

msg = result.ErrorMessages;
StringAssert.Contains(msg, string.Format(
KeyAssignedToPropertyIsNotSetMessage,
nameof(AppSettings),
nameof(AppSettings.JwtSecret),
"BIND_JWT_SECRET"
));
StringAssert.Contains(msg, string.Format(
KeyAssignedToPropertyIsNotSetMessage,
nameof(AppSettings),
nameof(AppSettings.TokenId),
"BIND_TOKEN_ID"
));
StringAssert.Contains(msg, string.Format(
FailedConvertConfigurationValueMessage,
"BIND_RACE_TIME",
nameof(Int32),
"This is not an int",
nameof(Int32)
));
StringAssert.Contains(msg, string.Format(
FailedConvertConfigurationValueMessage,
"ColorName",
nameof(Colors),
"Yellow",
nameof(Colors)
));
StringAssert.Contains(msg, string.Format(
PropertyDoesNotMatchConfigKeyMessage,
nameof(AppSettings) ,
nameof(AppSettings.BindSecretKey)
));
StringAssert.Contains(msg, string.Format(
PropertyDoesNotMatchConfigKeyMessage,
nameof(AppSettings),
nameof(AppSettings.BindJwtSecret)
));
// Asserts
result.HasError().Should().BeTrue();
errors.Should().BeEquivalentTo(expectedErrors);
}

[TestMethod]
public void Bind_WhenPropertyIsReadOnly_ShouldIgnoreTheReadOnlyProperty()
{
// Arrange
var customProvider = new CustomEnvironmentVariablesProvider();
var binder = new EnvBinder(customProvider);
customProvider["SECRET_KEY"] = "12345ex";
customProvider["ApiKey"] = "example12345";

// Act
var settings = binder.Bind<ReadOnlyProperties>();

Assert.AreNotEqual(notExpected: "12345ex", actual: settings.SecretKey);
Assert.AreNotEqual(notExpected: "example12345", actual: settings.ApiKey);
// Asserts
settings.SecretKey.Should().NotBe("12345ex");
settings.ApiKey.Should().NotBe("example12345");
}

[TestMethod]
public void Bind_WhenPropertyIsWriteOnly_ShouldIgnoreTheWriteOnlyProperty()
{
// Arrange
var customProvider = new CustomEnvironmentVariablesProvider();
var binder = new EnvBinder(customProvider);
customProvider["WEATHER_ID"] = "10";
customProvider["ApiKey"] = "123456";

// Act
var settings = binder.Bind<WriteOnlyProperties>();

Assert.AreNotEqual(notExpected: 10, actual: settings.weatherId);
Assert.AreNotEqual(notExpected: "123456", actual: settings.apiKey);
// Asserts
settings.weatherId.Should().NotBe(10);
settings.apiKey.Should().NotBe("123456");
}

[TestMethod]
public void Bind_WhenAllowedBindNonPublicProperties_ShouldSetNonPublicProperties()
{
// Arrange
var customProvider = new CustomEnvironmentVariablesProvider();
var binder = new EnvBinder(customProvider).AllowBindNonPublicProperties();
customProvider["TokenId"] = "e45d";
Expand All @@ -216,13 +235,15 @@ public void Bind_WhenAllowedBindNonPublicProperties_ShouldSetNonPublicProperties
customProvider["TimeId"] = "34";
customProvider["Url"] = "example.com";

// Act
var settings = binder.Bind<NonPublicProperties>();

Assert.AreEqual(expected: "e45d", actual: settings.TokenId);
Assert.AreEqual(expected: "example123", actual: settings.apiKey);
Assert.AreEqual(expected: 3, actual: settings.weatherId);
Assert.AreEqual(expected: "23example", actual: settings.SecretKey);
Assert.AreEqual(expected: 34, actual: settings.TimeId);
Assert.AreEqual(expected: "example.com", actual: settings.url);
// Asserts
settings.TokenId.Should().Be("e45d");
settings.apiKey.Should().Be("example123");
settings.weatherId.Should().Be(3);
settings.SecretKey.Should().Be("23example");
settings.TimeId.Should().Be(34);
settings.url.Should().Be("example.com");
}
}
1 change: 1 addition & 0 deletions tests/DotEnv.Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="6.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
Expand Down
1 change: 1 addition & 0 deletions tests/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
global using System.Text;
global using System.Collections;
global using Microsoft.VisualStudio.TestTools.UnitTesting;
global using FluentAssertions;
global using static System.Environment;
global using static DotEnv.Core.ExceptionMessages;
global using static DotEnv.Core.FormattingMessage;
Loading

0 comments on commit cdf58b9

Please sign in to comment.