This commit is contained in:
Janus C. H. Knudsen 2026-01-10 20:39:17 +01:00
parent 54b057886c
commit 7fc1ae0650
204 changed files with 4345 additions and 134 deletions

View file

@ -0,0 +1,143 @@
using Newtonsoft.Json.Linq;
using PlanTempus.Core.Configurations;
using PlanTempus.Core.Configurations.JsonConfigProvider;
using PlanTempus.Core.Configurations.SmartConfigProvider;
using Shouldly;
namespace PlanTempus.X.TDD.ConfigurationTests;
[TestClass]
public class JsonConfigurationProviderTests : TestFixture
{
private const string _testFolder = "ConfigurationTests/";
public JsonConfigurationProviderTests() : base(_testFolder)
{
}
[TestMethod]
public void GetSection_ShouldReturnCorrectFeatureSection()
{
// Arrange
var expectedJObject = JObject.Parse(@"{
'Enabled': true,
'RolloutPercentage': 25,
'AllowedUserGroups': ['beta']
}") as JToken;
var builder = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.Build();
// Act
var section = builder.GetSection("Feature");
// Assert
section.ShouldNotBeNull();
section.Value.ShouldBeEquivalentTo(expectedJObject);
}
[TestMethod]
public void Get_ShouldReturnCorrectFeatureObject()
{
// Arrange
var expectedFeature = new Feature
{
Enabled = true,
RolloutPercentage = 25,
AllowedUserGroups = new List<string> { "beta" }
};
var builder = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.Build();
// Act
var actualFeature = builder.GetSection("Feature").ToObject<Feature>();
#pragma warning disable CS0618 // Type or member is obsolete
var actualFeatureObsoleted = builder.GetSection("Feature").Get<Feature>();
#pragma warning restore CS0618 // Type or member is obsolete
// Assert
actualFeature.ShouldBeEquivalentTo(expectedFeature);
actualFeatureObsoleted.ShouldBeEquivalentTo(expectedFeature);
}
[TestMethod]
public void Get_ShouldReturnCorrectValueAsString()
{
// Arrange
var expectedFeature = "123";
var builder = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.Build();
// Act
var actualFeature = builder.GetSection("AnotherSetting").Get<string>("Thresholds:High");
// Assert
actualFeature.ShouldBeEquivalentTo(expectedFeature);
}
/// <summary>
/// Testing a stupid indexer for compability with Microsoft ConfigurationBuilder
/// </summary>
[TestMethod]
public void Indexer_ShouldReturnValueAsString()
{
// Arrange
var expected = "SHA256";
var builder = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.Build();
// Act
var actual = builder["Authentication"];
// Assert
actual.ShouldBeEquivalentTo(expected);
}
[TestMethod]
public void Get_ShouldReturnCorrectValueAsInt()
{
// Arrange
var expectedFeature = 22;
var builder = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.Build();
// Act
var actualFeature = builder.GetSection("AnotherSetting:Temperature").Get<int>("Indoor:Max:Limit");
// Assert
actualFeature.ShouldBe(expectedFeature);
}
[TestMethod]
public void Get_ShouldReturnCorrectValueAsNullBool()
{
// Arrange
bool? expectedFeature = null;
var configRoot = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.Build();
// Act
var actualFeature = configRoot.Get<bool?>("MissingKey:WhatThen");
// Assert
actualFeature.ShouldBe(expectedFeature);
}
}
internal class Feature
{
public bool Enabled { get; set; }
public int RolloutPercentage { get; set; }
public List<string> AllowedUserGroups { get; set; }
}

View file

@ -0,0 +1,75 @@
using Newtonsoft.Json.Linq;
using PlanTempus.Core.Configurations.Common;
namespace PlanTempus.X.TDD.ConfigurationTests;
[TestClass]
public class ConfigurationTests : TestFixture
{
[TestInitialize]
public void Init()
{
}
[TestMethod]
public void ConfigurationSettingsTest()
{
var pairs = new List<KeyValuePair<string, JToken>>
{
new("Debug", true),
// Database konfiguration
new("Database:ConnectionString", "Server=db.example.com;Port=5432"),
new("Database:Timeout", 30),
new("Database:UseSSL", true),
// Logging konfiguration med JObject
new("Logging:FileOptions", JObject.Parse(@"{
'Path': '/var/logs/app.log',
'MaxSizeMB': 100,
'RetentionDays': 7
}")),
// Feature flags med kompleks konfiguration
new("Features:Experimental", JObject.Parse(@"{
'Enabled': true,
'RolloutPercentage': 25,
'AllowedUserGroups': ['beta']
}")),
// API endpoints med array
new("API:Endpoints", "/api/users"),
new("API:Endpoints", "/api/products")
};
var result = KeyValueToJson.Convert(pairs);
var expected = JObject.Parse(@"{
'Debug' : true,
'Database': {
'ConnectionString': 'Server=db.example.com;Port=5432',
'Timeout': 30,
'UseSSL': true
},
'Logging': {
'FileOptions': {
'Path': '/var/logs/app.log',
'MaxSizeMB': 100,
'RetentionDays': 7
}
},
'Features': {
'Experimental': {
'Enabled': true,
'RolloutPercentage': 25,
'AllowedUserGroups': ['beta']
}
},
'API': {
'Endpoints': ['/api/users', '/api/products']
}
}");
Assert.IsTrue(JToken.DeepEquals(expected, result));
}
}

View file

@ -0,0 +1,82 @@
using Autofac;
using Insight.Database;
using PlanTempus.Core.Configurations;
using PlanTempus.Core.Configurations.JsonConfigProvider;
using PlanTempus.Core.Configurations.SmartConfigProvider;
using PlanTempus.Core.Database.ConnectionFactory;
using Shouldly;
namespace PlanTempus.X.TDD.ConfigurationTests;
[TestClass]
public class SmartConfigProviderTests : TestFixture
{
private const string _testFolder = "ConfigurationTests/";
[TestMethod]
public void TrySmartConfigWithOptionsForPostgres()
{
var config = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.AddSmartConfig(options => options.UsePostgres("DefaultConnection"))
.Build();
var actualFeature = config.Get<bool>("Database:UseSSL");
}
[TestMethod]
public void Get_ShouldReturnCorrectValueAsBool()
{
// Arrange
var expectedFeature = true;
var config = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.AddSmartConfig(options => options.UsePostgres("DefaultConnection"))
.Build();
// Act
var actualFeature = config.Get<bool>("Database:UseSSL");
// Assert
actualFeature.ShouldBe(expectedFeature);
}
[TestMethod]
public void Get_ShouldReturnCorrectValueWhenSelectingIntoValueRowInConfigTable()
{
// Arrange
var expectedFeature = 100;
var builder = new ConfigurationBuilder()
.AddJsonFile($"{_testFolder}appconfiguration.dev.json")
.AddSmartConfig(options => options.UsePostgres("DefaultConnection"))
.Build();
// Act
var actualFeature = builder.GetSection("Logging:FileOptions").Get<int>("MaxSizeMB");
var withoutSectionThisAlsoWorks = builder.Get<int>("Logging:FileOptions:MaxSizeMB");
// Assert
actualFeature.ShouldBe(expectedFeature);
actualFeature.ShouldBe(withoutSectionThisAlsoWorks);
}
[TestMethod]
public void TryGetActiveConfigurations()
{
var connFactory = Container.Resolve<IDbConnectionFactory>();
const string sql = @"
SELECT id, ""key"", value, label, content_type,
valid_from, expires_at, created_at, modified_at, etag
FROM app_configuration
WHERE CURRENT_TIMESTAMP BETWEEN valid_from AND expires_at
OR (valid_from IS NULL AND expires_at IS NULL)";
using (var conn = connFactory.Create())
{
var result = conn.QuerySql(sql);
}
}
}

View file

@ -0,0 +1,74 @@
{
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Host=192.168.1.63;Port=5432;Database=sandbox;User Id=sathumper;Password=3911;"
},
"ApplicationInsights": {
"ConnectionString": "InstrumentationKey=07d2a2b9-5e8e-4924-836e-264f8438f6c5;IngestionEndpoint=https://northeurope-2.in.applicationinsights.azure.com/;LiveEndpoint=https://northeurope.livediagnostics.monitor.azure.com/;ApplicationId=56748c39-2fa3-4880-a1e2-24068e791548",
"UseSeqLoggingTelemetryChannel": true
},
"SeqConfiguration": {
"IngestionEndpoint": "http://localhost:5341",
"ApiKey": null,
"Environment": "MSTEST"
},
"Authentication": "SHA256",
"Feature": {
"Enabled": true,
"RolloutPercentage": 25,
"AllowedUserGroups": [
"beta"
]
},
"AnotherSetting": {
"Thresholds": {
"High": "123",
"Low": "-1"
},
"Temperature": {
"Indoor": {
"Max": {
"Limit": 22
},
"Min": {
"Limit": 18
}
},
"Outdoor": {
"Max": {
"Limit": 12
},
"Min": {
"Limit": 9
}
}
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341",
"apiKey": ""
}
}
],
"Enrich": [
"WithMachineName",
"WithThreadId",
"WithProcessId",
"WithEnvironmentName"
],
"Properties": {
"Application": "PlanTempus"
}
}
}