wip
This commit is contained in:
parent
0010a32248
commit
ddb6abc14e
14 changed files with 754 additions and 718 deletions
|
|
@ -1,21 +1,23 @@
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
|
|
||||||
class TestPostgresLISTENNOTIFY
|
namespace PlanTempus.X.TDD.CodeSnippets;
|
||||||
|
|
||||||
|
internal class TestPostgresLISTENNOTIFY
|
||||||
{
|
{
|
||||||
static async Task Main(string[] args)
|
private static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
var connectionString = "Host=192.168.1.57;Database=ptdb01;Username=postgres;Password=3911";
|
var connectionString = "Host=192.168.1.57;Database=ptdb01;Username=postgres;Password=3911";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using NpgsqlConnection conn = new NpgsqlConnection(connectionString);
|
await using var conn = new NpgsqlConnection(connectionString);
|
||||||
await conn.OpenAsync();
|
await conn.OpenAsync();
|
||||||
|
|
||||||
Console.WriteLine("Forbundet til databasen. Lytter efter notifikationer...");
|
Console.WriteLine("Forbundet til databasen. Lytter efter notifikationer...");
|
||||||
|
|
||||||
conn.Notification += (o, e) =>
|
conn.Notification += (o, e) =>
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Notifikation modtaget:");
|
Console.WriteLine("Notifikation modtaget:");
|
||||||
Console.WriteLine($" PID: {e.PID}");
|
Console.WriteLine($" PID: {e.PID}");
|
||||||
Console.WriteLine($" Kanal: {e.Channel}");
|
Console.WriteLine($" Kanal: {e.Channel}");
|
||||||
Console.WriteLine($" Payload: {e.Payload}");
|
Console.WriteLine($" Payload: {e.Payload}");
|
||||||
|
|
@ -29,10 +31,7 @@ class TestPostgresLISTENNOTIFY
|
||||||
|
|
||||||
Console.WriteLine("Tryk på en tast for at stoppe...");
|
Console.WriteLine("Tryk på en tast for at stoppe...");
|
||||||
|
|
||||||
while (!Console.KeyAvailable)
|
while (!Console.KeyAvailable) await conn.WaitAsync();
|
||||||
{
|
|
||||||
await conn.WaitAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
using PlanTempus.Database.ConfigurationManagementSystem;
|
using System.Data;
|
||||||
using Insight.Database;
|
|
||||||
using System.Data;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Shouldly;
|
using Insight.Database;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using PlanTempus.Core.Sql.ConnectionFactory;
|
using PlanTempus.Core.Sql.ConnectionFactory;
|
||||||
|
using Shouldly;
|
||||||
|
|
||||||
namespace PlanTempus.Tests.ConfigurationSystem;
|
namespace PlanTempus.X.TDD.ConfigurationSystem;
|
||||||
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class SetupConfigurationTests : TestFixture
|
public class SetupConfigurationTests : TestFixture
|
||||||
{
|
{
|
||||||
private IDbConnection _connection;
|
private IDbConnection _connection;
|
||||||
private SetupConfiguration _setupConfiguration;
|
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
|
@ -58,9 +56,9 @@ public class SetupConfigurationTests : TestFixture
|
||||||
// Assert
|
// Assert
|
||||||
var expected = JsonConvert.SerializeObject(new
|
var expected = JsonConvert.SerializeObject(new
|
||||||
{
|
{
|
||||||
key = configData.key,
|
configData.key,
|
||||||
value = configData.value,
|
configData.value,
|
||||||
label = configData.label,
|
configData.label,
|
||||||
action_type = "I"
|
action_type = "I"
|
||||||
});
|
});
|
||||||
var actual = JsonConvert.SerializeObject(history) as string;
|
var actual = JsonConvert.SerializeObject(history) as string;
|
||||||
|
|
@ -83,7 +81,7 @@ public class SetupConfigurationTests : TestFixture
|
||||||
RETURNING modified_at", configData)
|
RETURNING modified_at", configData)
|
||||||
.Single();
|
.Single();
|
||||||
|
|
||||||
System.Threading.Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var updated = _connection.QuerySql<dynamic>(@"
|
var updated = _connection.QuerySql<dynamic>(@"
|
||||||
|
|
@ -91,7 +89,7 @@ public class SetupConfigurationTests : TestFixture
|
||||||
SET value = @value
|
SET value = @value
|
||||||
WHERE key = @key
|
WHERE key = @key
|
||||||
RETURNING modified_at",
|
RETURNING modified_at",
|
||||||
new { key = configData.key, value = "updated value" })
|
new { configData.key, value = "updated value" })
|
||||||
.Single();
|
.Single();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -129,8 +127,8 @@ public class SetupConfigurationTests : TestFixture
|
||||||
|
|
||||||
var expected = JsonConvert.SerializeObject(new
|
var expected = JsonConvert.SerializeObject(new
|
||||||
{
|
{
|
||||||
key = configData.key,
|
configData.key,
|
||||||
value = configData.value,
|
configData.value,
|
||||||
action_type = "D"
|
action_type = "D"
|
||||||
});
|
});
|
||||||
var actual = JsonConvert.SerializeObject(history) as string;
|
var actual = JsonConvert.SerializeObject(history) as string;
|
||||||
|
|
@ -177,10 +175,10 @@ public class SetupConfigurationTests : TestFixture
|
||||||
// Assert
|
// Assert
|
||||||
var expected = JsonConvert.SerializeObject(new
|
var expected = JsonConvert.SerializeObject(new
|
||||||
{
|
{
|
||||||
key = configData.key,
|
configData.key,
|
||||||
value = configData.value,
|
configData.value,
|
||||||
label = configData.label,
|
configData.label,
|
||||||
content_type = configData.content_type,
|
configData.content_type,
|
||||||
valid_from = ((DateTimeOffset)configData.valid_from).ToUnixTimeSeconds(),
|
valid_from = ((DateTimeOffset)configData.valid_from).ToUnixTimeSeconds(),
|
||||||
expires_at = ((DateTimeOffset)configData.expires_at).ToUnixTimeSeconds()
|
expires_at = ((DateTimeOffset)configData.expires_at).ToUnixTimeSeconds()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Shouldly;
|
|
||||||
using PlanTempus.Tests;
|
|
||||||
using PlanTempus.Core.Configurations;
|
using PlanTempus.Core.Configurations;
|
||||||
using PlanTempus.Core.Configurations.JsonConfigProvider;
|
using PlanTempus.Core.Configurations.JsonConfigProvider;
|
||||||
using PlanTempus.Core.Configurations.SmartConfigProvider;
|
using PlanTempus.Core.Configurations.SmartConfigProvider;
|
||||||
|
using Shouldly;
|
||||||
|
|
||||||
|
namespace PlanTempus.X.TDD.ConfigurationTests;
|
||||||
|
|
||||||
namespace PlanTempus.Tests.ConfigurationTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class JsonConfigurationProviderTests : TestFixture
|
public class JsonConfigurationProviderTests : TestFixture
|
||||||
{
|
{
|
||||||
const string _testFolder = "ConfigurationTests/";
|
private const string _testFolder = "ConfigurationTests/";
|
||||||
|
|
||||||
public JsonConfigurationProviderTests() : base(_testFolder) { }
|
public JsonConfigurationProviderTests() : base(_testFolder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
@ -45,7 +46,7 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
{
|
{
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
RolloutPercentage = 25,
|
RolloutPercentage = 25,
|
||||||
AllowedUserGroups = new() { "beta" }
|
AllowedUserGroups = new List<string> { "beta" }
|
||||||
};
|
};
|
||||||
|
|
||||||
var builder = new ConfigurationBuilder()
|
var builder = new ConfigurationBuilder()
|
||||||
|
|
@ -60,8 +61,8 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
// Assert
|
// Assert
|
||||||
actualFeature.ShouldBeEquivalentTo(expectedFeature);
|
actualFeature.ShouldBeEquivalentTo(expectedFeature);
|
||||||
actualFeatureObsoleted.ShouldBeEquivalentTo(expectedFeature);
|
actualFeatureObsoleted.ShouldBeEquivalentTo(expectedFeature);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Get_ShouldReturnCorrectValueAsString()
|
public void Get_ShouldReturnCorrectValueAsString()
|
||||||
{
|
{
|
||||||
|
|
@ -78,6 +79,7 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
// Assert
|
// Assert
|
||||||
actualFeature.ShouldBeEquivalentTo(expectedFeature);
|
actualFeature.ShouldBeEquivalentTo(expectedFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Testing a stupid indexer for compability with Microsoft ConfigurationBuilder
|
/// Testing a stupid indexer for compability with Microsoft ConfigurationBuilder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -97,6 +99,7 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
// Assert
|
// Assert
|
||||||
actual.ShouldBeEquivalentTo(expected);
|
actual.ShouldBeEquivalentTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Get_ShouldReturnCorrectValueAsInt()
|
public void Get_ShouldReturnCorrectValueAsInt()
|
||||||
{
|
{
|
||||||
|
|
@ -113,6 +116,7 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
// Assert
|
// Assert
|
||||||
actualFeature.ShouldBe(expectedFeature);
|
actualFeature.ShouldBe(expectedFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Get_ShouldReturnCorrectValueAsBool()
|
public void Get_ShouldReturnCorrectValueAsBool()
|
||||||
{
|
{
|
||||||
|
|
@ -138,5 +142,3 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
public int RolloutPercentage { get; set; }
|
public int RolloutPercentage { get; set; }
|
||||||
public List<string> AllowedUserGroups { get; set; }
|
public List<string> AllowedUserGroups { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PlanTempus.Core.Configurations.Common;
|
using PlanTempus.Core.Configurations.Common;
|
||||||
using PlanTempus.Tests;
|
|
||||||
|
|
||||||
namespace PlanTempus.Tests.ConfigurationTests;
|
namespace PlanTempus.X.TDD.ConfigurationTests;
|
||||||
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class ConfigurationTests : TestFixture
|
public class ConfigurationTests : TestFixture
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Shouldly;
|
|
||||||
using System.Data;
|
|
||||||
using Insight.Database;
|
using Insight.Database;
|
||||||
using PlanTempus.Core.Configurations;
|
using PlanTempus.Core.Configurations;
|
||||||
using PlanTempus.Core.Configurations.JsonConfigProvider;
|
using PlanTempus.Core.Configurations.JsonConfigProvider;
|
||||||
using PlanTempus.Core.Configurations.SmartConfigProvider;
|
using PlanTempus.Core.Configurations.SmartConfigProvider;
|
||||||
using PlanTempus.Core.Sql.ConnectionFactory;
|
using PlanTempus.Core.Sql.ConnectionFactory;
|
||||||
|
using Shouldly;
|
||||||
|
|
||||||
|
namespace PlanTempus.X.TDD.ConfigurationTests;
|
||||||
|
|
||||||
namespace PlanTempus.Tests.ConfigurationTests
|
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class SmartConfigProviderTests : TestFixture
|
public class SmartConfigProviderTests : TestFixture
|
||||||
{
|
{
|
||||||
const string _testFolder = "ConfigurationTests/";
|
private const string _testFolder = "ConfigurationTests/";
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TrySmartConfigWithOptionsForPostgres()
|
public void TrySmartConfigWithOptionsForPostgres()
|
||||||
|
|
@ -23,7 +22,6 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var actualFeature = config.Get<bool>("Database:UseSSL");
|
var actualFeature = config.Get<bool>("Database:UseSSL");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
@ -43,6 +41,7 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
// Assert
|
// Assert
|
||||||
actualFeature.ShouldBe(expectedFeature);
|
actualFeature.ShouldBe(expectedFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Get_ShouldReturnCorrectValueWhenSelectingIntoValueRowInConfigTable()
|
public void Get_ShouldReturnCorrectValueWhenSelectingIntoValueRowInConfigTable()
|
||||||
{
|
{
|
||||||
|
|
@ -61,7 +60,6 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
// Assert
|
// Assert
|
||||||
actualFeature.ShouldBe(expectedFeature);
|
actualFeature.ShouldBe(expectedFeature);
|
||||||
actualFeature.ShouldBe(withoutSectionThisAlsoWorks);
|
actualFeature.ShouldBe(withoutSectionThisAlsoWorks);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
@ -79,8 +77,6 @@ namespace PlanTempus.Tests.ConfigurationTests
|
||||||
using (var conn = connFactory.Create())
|
using (var conn = connFactory.Create())
|
||||||
{
|
{
|
||||||
var result = conn.QuerySql(sql);
|
var result = conn.QuerySql(sql);
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,23 +16,31 @@
|
||||||
"Feature": {
|
"Feature": {
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"RolloutPercentage": 25,
|
"RolloutPercentage": 25,
|
||||||
"AllowedUserGroups": [ "beta" ]
|
"AllowedUserGroups": [
|
||||||
|
"beta"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"AnotherSetting": {
|
"AnotherSetting": {
|
||||||
|
|
||||||
"Thresholds": {
|
"Thresholds": {
|
||||||
"High": "123",
|
"High": "123",
|
||||||
"Low": "-1"
|
"Low": "-1"
|
||||||
},
|
},
|
||||||
"Temperature": {
|
"Temperature": {
|
||||||
|
|
||||||
"Indoor": {
|
"Indoor": {
|
||||||
"Max": { "Limit": 22 },
|
"Max": {
|
||||||
"Min": { "Limit": 18 }
|
"Limit": 22
|
||||||
|
},
|
||||||
|
"Min": {
|
||||||
|
"Limit": 18
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Outdoor": {
|
"Outdoor": {
|
||||||
"Max": { "Limit": 12 },
|
"Max": {
|
||||||
"Min": { "Limit": 9 }
|
"Limit": 12
|
||||||
|
},
|
||||||
|
"Min": {
|
||||||
|
"Limit": 9
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Net;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Microsoft.ApplicationInsights;
|
using Microsoft.ApplicationInsights;
|
||||||
using Microsoft.ApplicationInsights.Channel;
|
using Microsoft.ApplicationInsights.Channel;
|
||||||
|
|
@ -5,14 +6,14 @@ using Microsoft.ApplicationInsights.DataContracts;
|
||||||
using PlanTempus.Core.Logging;
|
using PlanTempus.Core.Logging;
|
||||||
using PlanTempus.Core.Telemetry;
|
using PlanTempus.Core.Telemetry;
|
||||||
|
|
||||||
namespace PlanTempus.Tests.Logging
|
namespace PlanTempus.X.TDD.Logging;
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class SeqBackgroundServiceTest : TestFixture
|
public class SeqBackgroundServiceTest : TestFixture
|
||||||
{
|
{
|
||||||
|
private CancellationTokenSource _cts;
|
||||||
private IMessageChannel<ITelemetry> _messageChannel;
|
private IMessageChannel<ITelemetry> _messageChannel;
|
||||||
private SeqBackgroundService _service;
|
private SeqBackgroundService _service;
|
||||||
private CancellationTokenSource _cts;
|
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void SetupThis()
|
public void SetupThis()
|
||||||
|
|
@ -34,7 +35,7 @@ namespace PlanTempus.Tests.Logging
|
||||||
{
|
{
|
||||||
await _service.StartAsync(_cts.Token);
|
await _service.StartAsync(_cts.Token);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (var i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
var eventTelemetry = new EventTelemetry
|
var eventTelemetry = new EventTelemetry
|
||||||
{
|
{
|
||||||
|
|
@ -54,7 +55,7 @@ namespace PlanTempus.Tests.Logging
|
||||||
await _service.StopAsync(CancellationToken.None);
|
await _service.StopAsync(CancellationToken.None);
|
||||||
|
|
||||||
|
|
||||||
bool hasMoreMessages = await _messageChannel.Reader.WaitToReadAsync();
|
var hasMoreMessages = await _messageChannel.Reader.WaitToReadAsync();
|
||||||
Assert.IsFalse(hasMoreMessages, "Queue should be empty after 5 seconds");
|
Assert.IsFalse(hasMoreMessages, "Queue should be empty after 5 seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,8 +65,7 @@ namespace PlanTempus.Tests.Logging
|
||||||
HttpRequestMessage request,
|
HttpRequestMessage request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK));
|
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,14 +3,14 @@ using Microsoft.ApplicationInsights;
|
||||||
using Microsoft.ApplicationInsights.DataContracts;
|
using Microsoft.ApplicationInsights.DataContracts;
|
||||||
using PlanTempus.Core.Logging;
|
using PlanTempus.Core.Logging;
|
||||||
|
|
||||||
namespace PlanTempus.Tests.Logging
|
namespace PlanTempus.X.TDD.Logging;
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class SeqLoggerTests : TestFixture
|
public class SeqLoggerTests : TestFixture
|
||||||
{
|
{
|
||||||
private SeqLogger<SeqLoggerTests> _logger;
|
|
||||||
private SeqHttpClient _httpClient;
|
|
||||||
private readonly string _testId;
|
private readonly string _testId;
|
||||||
|
private readonly SeqHttpClient _httpClient;
|
||||||
|
private readonly SeqLogger<SeqLoggerTests> _logger;
|
||||||
|
|
||||||
public SeqLoggerTests()
|
public SeqLoggerTests()
|
||||||
{
|
{
|
||||||
|
|
@ -34,9 +34,8 @@ namespace PlanTempus.Tests.Logging
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await _logger.LogAsync(traceTelemetry);
|
await _logger.LogAsync(traceTelemetry);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task LogTraceTelemetry_SendsCorrectDataWithWarningLevel()
|
public async Task LogTraceTelemetry_SendsCorrectDataWithWarningLevel()
|
||||||
{
|
{
|
||||||
|
|
@ -51,8 +50,8 @@ namespace PlanTempus.Tests.Logging
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await _logger.LogAsync(traceTelemetry);
|
await _logger.LogAsync(traceTelemetry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task LogEventTelemetry_SendsCorrectData()
|
public async Task LogEventTelemetry_SendsCorrectData()
|
||||||
{
|
{
|
||||||
|
|
@ -74,13 +73,11 @@ namespace PlanTempus.Tests.Logging
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int t = 0;
|
var t = 0;
|
||||||
var result = 10 / t;
|
var result = 10 / t;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
var exceptionTelemetry = new ExceptionTelemetry(e)
|
var exceptionTelemetry = new ExceptionTelemetry(e)
|
||||||
{
|
{
|
||||||
|
|
@ -121,9 +118,8 @@ namespace PlanTempus.Tests.Logging
|
||||||
{
|
{
|
||||||
var telemetryClient = Container.Resolve<TelemetryClient>();
|
var telemetryClient = Container.Resolve<TelemetryClient>();
|
||||||
|
|
||||||
using (Microsoft.ApplicationInsights.Extensibility.IOperationHolder<RequestTelemetry> parent = telemetryClient.StartOperation<RequestTelemetry>("Parent First"))
|
using (var parent = telemetryClient.StartOperation<RequestTelemetry>("Parent First"))
|
||||||
{
|
{
|
||||||
|
|
||||||
parent.Telemetry.Duration = TimeSpan.FromMilliseconds(250);
|
parent.Telemetry.Duration = TimeSpan.FromMilliseconds(250);
|
||||||
parent.Telemetry.Url = new Uri("http://parent.test.com/api/test");
|
parent.Telemetry.Url = new Uri("http://parent.test.com/api/test");
|
||||||
|
|
||||||
|
|
@ -139,10 +135,11 @@ namespace PlanTempus.Tests.Logging
|
||||||
child.Telemetry.Properties.Add("TestId", _testId);
|
child.Telemetry.Properties.Add("TestId", _testId);
|
||||||
|
|
||||||
await _logger.LogAsync(child);
|
await _logger.LogAsync(child);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
await _logger.LogAsync(parent);
|
await _logger.LogAsync(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,15 @@ using Microsoft.ApplicationInsights.DataContracts;
|
||||||
using PlanTempus.Core.Logging;
|
using PlanTempus.Core.Logging;
|
||||||
using PlanTempus.Core.Telemetry;
|
using PlanTempus.Core.Telemetry;
|
||||||
|
|
||||||
namespace PlanTempus.Tests.Logging
|
namespace PlanTempus.X.TDD.Logging;
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class SeqTelemetryChannelTest : TestFixture
|
public class SeqTelemetryChannelTest : TestFixture
|
||||||
{
|
{
|
||||||
private IMessageChannel<ITelemetry> _messageChannel;
|
|
||||||
TelemetryClient _telemetryClient;
|
|
||||||
private SeqBackgroundService _service;
|
|
||||||
private CancellationTokenSource _cts;
|
private CancellationTokenSource _cts;
|
||||||
|
private IMessageChannel<ITelemetry> _messageChannel;
|
||||||
|
private SeqBackgroundService _service;
|
||||||
|
private TelemetryClient _telemetryClient;
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void SetupThis()
|
public void SetupThis()
|
||||||
|
|
@ -34,7 +34,7 @@ namespace PlanTempus.Tests.Logging
|
||||||
{
|
{
|
||||||
await _service.StartAsync(_cts.Token);
|
await _service.StartAsync(_cts.Token);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (var i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
var eventTelemetry = new EventTelemetry
|
var eventTelemetry = new EventTelemetry
|
||||||
{
|
{
|
||||||
|
|
@ -54,8 +54,7 @@ namespace PlanTempus.Tests.Logging
|
||||||
|
|
||||||
await _service.StopAsync(CancellationToken.None);
|
await _service.StopAsync(CancellationToken.None);
|
||||||
|
|
||||||
bool hasMoreMessages = await _messageChannel.Reader.WaitToReadAsync();
|
var hasMoreMessages = await _messageChannel.Reader.WaitToReadAsync();
|
||||||
Assert.IsFalse(hasMoreMessages, "Queue should be empty after 5 seconds");
|
Assert.IsFalse(hasMoreMessages, "Queue should be empty after 5 seconds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
@ -1,42 +1,41 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Sodium;
|
using System.Text;
|
||||||
using PlanTempus.Core;
|
using PlanTempus.Core;
|
||||||
|
using Sodium;
|
||||||
|
|
||||||
|
namespace PlanTempus.X.TDD;
|
||||||
|
|
||||||
namespace PlanTempus.Tests
|
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class PasswordHasherTests : TestFixture
|
public class PasswordHasherTests : TestFixture
|
||||||
{
|
{
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MyTestMethod()
|
public void MyTestMethod()
|
||||||
{
|
{
|
||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
|
|
||||||
byte[] salt = PasswordHash.ScryptGenerateSalt();
|
var salt = PasswordHash.ScryptGenerateSalt();
|
||||||
|
|
||||||
// 2. Konverter password til byte[]
|
// 2. Konverter password til byte[]
|
||||||
byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes("password123");
|
var passwordBytes = Encoding.UTF8.GetBytes("password123");
|
||||||
|
|
||||||
// 3. Kald ScryptHashBinary korrekt
|
// 3. Kald ScryptHashBinary korrekt
|
||||||
byte[] hash = PasswordHash.ScryptHashBinary(
|
var hash = PasswordHash.ScryptHashBinary(
|
||||||
password: passwordBytes,
|
passwordBytes,
|
||||||
salt: salt, // 32-byte array
|
salt
|
||||||
limit: PasswordHash.Strength.Interactive,
|
|
||||||
outputLength: 32
|
|
||||||
);
|
);
|
||||||
|
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void HashPassword_ShouldCreateValidHashFormat()
|
public void HashPassword_ShouldCreateValidHashFormat()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
string password = "TestPassword123";
|
var password = "TestPassword123";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
string hashedPassword = new SecureTokenizer().TokenizeText(password);
|
var hashedPassword = new SecureTokenizer().TokenizeText(password);
|
||||||
string[] parts = hashedPassword.Split('.');
|
var parts = hashedPassword.Split('.');
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(3, parts.Length);
|
Assert.AreEqual(3, parts.Length);
|
||||||
|
|
@ -47,11 +46,11 @@ namespace PlanTempus.Tests
|
||||||
public void VerifyPassword_WithCorrectPassword_ShouldReturnTrue()
|
public void VerifyPassword_WithCorrectPassword_ShouldReturnTrue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
string password = "TestPassword123";
|
var password = "TestPassword123";
|
||||||
string hashedPassword = new SecureTokenizer().TokenizeText(password);
|
var hashedPassword = new SecureTokenizer().TokenizeText(password);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool result = new SecureTokenizer().VerifyToken(hashedPassword, password);
|
var result = new SecureTokenizer().VerifyToken(hashedPassword, password);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsTrue(result);
|
Assert.IsTrue(result);
|
||||||
|
|
@ -61,12 +60,12 @@ namespace PlanTempus.Tests
|
||||||
public void VerifyPassword_WithWrongPassword_ShouldReturnFalse()
|
public void VerifyPassword_WithWrongPassword_ShouldReturnFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
string correctPassword = "TestPassword123";
|
var correctPassword = "TestPassword123";
|
||||||
string wrongPassword = "WrongPassword123";
|
var wrongPassword = "WrongPassword123";
|
||||||
string hashedPassword = new SecureTokenizer().TokenizeText(correctPassword);
|
var hashedPassword = new SecureTokenizer().TokenizeText(correctPassword);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool result = new SecureTokenizer().VerifyToken(hashedPassword, wrongPassword);
|
var result = new SecureTokenizer().VerifyToken(hashedPassword, wrongPassword);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsFalse(result);
|
Assert.IsFalse(result);
|
||||||
|
|
@ -76,14 +75,13 @@ namespace PlanTempus.Tests
|
||||||
public void VerifyPassword_WithInvalidHashFormat_ShouldReturnFalse()
|
public void VerifyPassword_WithInvalidHashFormat_ShouldReturnFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
string password = "TestPassword123";
|
var password = "TestPassword123";
|
||||||
string invalidHash = "InvalidHash";
|
var invalidHash = "InvalidHash";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool result = new SecureTokenizer().VerifyToken(invalidHash, password);
|
var result = new SecureTokenizer().VerifyToken(invalidHash, password);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.IsFalse(result);
|
Assert.IsFalse(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using System.Data;
|
|
||||||
using Insight.Database;
|
using Insight.Database;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using PlanTempus.Core.Sql.ConnectionFactory;
|
|
||||||
using PlanTempus.Core.Sql;
|
using PlanTempus.Core.Sql;
|
||||||
|
using PlanTempus.Core.Sql.ConnectionFactory;
|
||||||
|
using Shouldly;
|
||||||
|
|
||||||
|
namespace PlanTempus.X.TDD;
|
||||||
|
|
||||||
namespace PlanTempus.Tests
|
|
||||||
{
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class PostgresTests : TestFixture
|
public class PostgresTests : TestFixture
|
||||||
{
|
{
|
||||||
IDbConnectionFactory _connFactory;
|
private IDbConnectionFactory _connFactory;
|
||||||
IDatabaseOperations _databaseOperations;
|
private IDatabaseOperations _databaseOperations;
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void MyTestMethod()
|
public void MyTestMethod()
|
||||||
|
|
@ -19,14 +18,16 @@ namespace PlanTempus.Tests
|
||||||
_connFactory = Container.Resolve<IDbConnectionFactory>();
|
_connFactory = Container.Resolve<IDbConnectionFactory>();
|
||||||
_databaseOperations = Container.Resolve<IDatabaseOperations>();
|
_databaseOperations = Container.Resolve<IDatabaseOperations>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestDefaultConnection()
|
public void TestDefaultConnection()
|
||||||
{
|
{
|
||||||
//https://stackoverflow.com/questions/69169247/how-to-create-idbconnection-factory-using-autofac-for-dapper
|
//https://stackoverflow.com/questions/69169247/how-to-create-idbconnection-factory-using-autofac-for-dapper
|
||||||
|
|
||||||
using (var conn = _connFactory.Create())
|
using (var conn = _connFactory.Create())
|
||||||
|
{
|
||||||
conn.ExecuteSql("SELECT 1 as p");
|
conn.ExecuteSql("SELECT 1 as p");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
@ -46,6 +47,7 @@ namespace PlanTempus.Tests
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task TestScopeConnectionWithErrorLogging()
|
public async Task TestScopeConnectionWithErrorLogging()
|
||||||
{
|
{
|
||||||
|
|
@ -53,7 +55,7 @@ namespace PlanTempus.Tests
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var user = await db.Connection.QuerySqlAsync<string>(
|
var user = await db.Connection.QuerySqlAsync<string>(
|
||||||
"SELECT tablename FROM pg_tabless limit 5");
|
"SELECT tablename FROM pg_tables limit 5");
|
||||||
|
|
||||||
db.Success();
|
db.Success();
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +64,47 @@ namespace PlanTempus.Tests
|
||||||
db.Error(ex);
|
db.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task TestForUniqueUserEmail()
|
||||||
|
{
|
||||||
|
using var db = _databaseOperations.CreateScope(nameof(TestForUniqueUserEmail));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sql = @"
|
||||||
|
INSERT INTO system.users(email, password_hash, security_stamp, email_confirmed,
|
||||||
|
access_failed_count, lockout_enabled,
|
||||||
|
is_active)
|
||||||
|
VALUES(@Email, @PasswordHash, @SecurityStamp, @EmailConfirmed,
|
||||||
|
@AccessFailedCount, @LockoutEnabled, @IsActive)
|
||||||
|
RETURNING id, created_at, email, is_active";
|
||||||
|
|
||||||
|
var parameters = new
|
||||||
|
{
|
||||||
|
Email = "elon.musk@mars.com",
|
||||||
|
PasswordHash = "MartianRover2025",
|
||||||
|
SecurityStamp = "MarsOrBust",
|
||||||
|
EmailConfirmed = true,
|
||||||
|
AccessFailedCount = 0,
|
||||||
|
LockoutEnabled = false,
|
||||||
|
IsActive = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var user = await db.Connection.QuerySqlAsync<dynamic>(sql, parameters);
|
||||||
|
|
||||||
|
user.ShouldNotBeNull();
|
||||||
|
// ((string)user.email).ShouldBe("elon.musk@mars.com");
|
||||||
|
// ((bool)user.is_active).ShouldBeTrue();
|
||||||
|
|
||||||
|
db.Success();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
db.Error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task TestSimpleDatabaseOperation()
|
public async Task TestSimpleDatabaseOperation()
|
||||||
{
|
{
|
||||||
|
|
@ -72,13 +115,13 @@ namespace PlanTempus.Tests
|
||||||
return await connection.QuerySqlAsync<string>(
|
return await connection.QuerySqlAsync<string>(
|
||||||
"SELECT tablename FROM pg_tables limit 5");
|
"SELECT tablename FROM pg_tables limit 5");
|
||||||
}, nameof(TestSimpleDatabaseOperation));
|
}, nameof(TestSimpleDatabaseOperation));
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void SetupPostgresql_LISTEN()
|
public void SetupPostgresql_LISTEN()
|
||||||
{
|
{
|
||||||
|
|
@ -92,4 +135,3 @@ namespace PlanTempus.Tests
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1 @@
|
||||||
|
namespace PlanTempus.X.TDD;
|
||||||
|
|
||||||
namespace PlanTempus.Tests
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +1,36 @@
|
||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics;
|
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Microsoft.ApplicationInsights;
|
using Microsoft.ApplicationInsights;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using PlanTempus.Core.Configurations;
|
using PlanTempus.Core.Configurations;
|
||||||
using PlanTempus.Core.Configurations.JsonConfigProvider;
|
using PlanTempus.Core.Configurations.JsonConfigProvider;
|
||||||
|
using PlanTempus.Core.Logging;
|
||||||
using PlanTempus.Core.ModuleRegistry;
|
using PlanTempus.Core.ModuleRegistry;
|
||||||
namespace PlanTempus.Tests
|
using PlanTempus.Database.ModuleRegistry;
|
||||||
{
|
|
||||||
|
namespace PlanTempus.X.TDD;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Act as base class for tests. Avoids duplication of test setup code
|
/// Act as base class for tests. Avoids duplication of test setup code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public abstract partial class TestFixture
|
public abstract class TestFixture
|
||||||
{
|
{
|
||||||
private readonly string _configurationFilePath;
|
private readonly string _configurationFilePath;
|
||||||
|
|
||||||
|
protected TestFixture() : this(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestFixture(string configurationFilePath)
|
||||||
|
{
|
||||||
|
if (configurationFilePath is not null)
|
||||||
|
_configurationFilePath = configurationFilePath?.TrimEnd('/') + "/";
|
||||||
|
|
||||||
|
CreateContainerBuilder();
|
||||||
|
Container = ContainerBuilder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
protected IContainer Container { get; private set; }
|
protected IContainer Container { get; private set; }
|
||||||
protected ContainerBuilder ContainerBuilder { get; private set; }
|
protected ContainerBuilder ContainerBuilder { get; private set; }
|
||||||
|
|
||||||
|
|
@ -28,18 +43,9 @@ namespace PlanTempus.Tests
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TestFixture() : this(null) { }
|
|
||||||
public TestFixture(string configurationFilePath)
|
|
||||||
{
|
|
||||||
if (configurationFilePath is not null)
|
|
||||||
_configurationFilePath = configurationFilePath?.TrimEnd('/') + "/";
|
|
||||||
|
|
||||||
CreateContainerBuilder();
|
|
||||||
Container = ContainerBuilder.Build();
|
|
||||||
}
|
|
||||||
protected virtual void CreateContainerBuilder()
|
protected virtual void CreateContainerBuilder()
|
||||||
{
|
{
|
||||||
IConfigurationRoot configuration = Configuration();
|
var configuration = Configuration();
|
||||||
|
|
||||||
//var logger = new LoggerConfiguration()
|
//var logger = new LoggerConfiguration()
|
||||||
// .MinimumLevel.Verbose()
|
// .MinimumLevel.Verbose()
|
||||||
|
|
@ -59,7 +65,7 @@ namespace PlanTempus.Tests
|
||||||
.SingleInstance();
|
.SingleInstance();
|
||||||
|
|
||||||
|
|
||||||
builder.RegisterModule(new Database.ModuleRegistry.DbPostgreSqlModule
|
builder.RegisterModule(new DbPostgreSqlModule
|
||||||
{
|
{
|
||||||
ConnectionString = configuration.GetConnectionString("DefaultConnection")
|
ConnectionString = configuration.GetConnectionString("DefaultConnection")
|
||||||
});
|
});
|
||||||
|
|
@ -70,8 +76,7 @@ namespace PlanTempus.Tests
|
||||||
});
|
});
|
||||||
builder.RegisterModule(new SeqLoggingModule
|
builder.RegisterModule(new SeqLoggingModule
|
||||||
{
|
{
|
||||||
SeqConfiguration = configuration.GetSection("SeqConfiguration").ToObject<Core.Logging.SeqConfiguration>()
|
SeqConfiguration = configuration.GetSection("SeqConfiguration").ToObject<SeqConfiguration>()
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -91,6 +96,4 @@ namespace PlanTempus.Tests
|
||||||
Container = null;
|
Container = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue