diff --git a/CDP4Common.NetCore.Tests/Comparers/BooleanValueSetComparerAdditionalTestFixture.cs b/CDP4Common.NetCore.Tests/Comparers/BooleanValueSetComparerAdditionalTestFixture.cs new file mode 100644 index 000000000..92fe31514 --- /dev/null +++ b/CDP4Common.NetCore.Tests/Comparers/BooleanValueSetComparerAdditionalTestFixture.cs @@ -0,0 +1,64 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Common.NetCore.Tests.Comparers +{ + using CDP4Common.Comparers; + using CDP4Common.Types; + using NUnit.Framework; + + /// + /// Additional coverage tests for . + /// + [TestFixture] + public class BooleanValueSetComparerAdditionalTestFixture + { + [Test] + public void VerifyThatStringComparisonIsUsedWhenConversionFails() + { + var left = new ValueArray(new[] { "maybe" }); + var right = new ValueArray(new[] { "certain" }); + var comparer = new BooleanValueSetComparer(); + + var result = comparer.Compare(left, right); + + var expected = string.CompareOrdinal(left.ToString().ToLower(), right.ToString().ToLower()); + Assert.That(result, Is.EqualTo(expected)); + } + + [Test] + public void VerifyThatFailedConversionResetsBooleanList() + { + var comparer = new BooleanValueSetComparer(); + var valueArray = new ValueArray(new[] { "true", "value", "false" }); + + var success = comparer.TryConvertStringValueArrayToBooleanList(valueArray, out var booleanList); + + Assert.Multiple(() => + { + Assert.That(success, Is.False); + Assert.That(booleanList, Is.Empty); + }); + } + } +} diff --git a/CDP4Common.NetCore.Tests/Extensions/GuidExtensionsTestFixture.cs b/CDP4Common.NetCore.Tests/Extensions/GuidExtensionsTestFixture.cs new file mode 100644 index 000000000..a27fd1147 --- /dev/null +++ b/CDP4Common.NetCore.Tests/Extensions/GuidExtensionsTestFixture.cs @@ -0,0 +1,70 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Common.NetCore.Tests.Extensions +{ + using System; + using System.Collections.Generic; + using System.Linq; + using CDP4Common.Extensions; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class GuidExtensionsTestFixture + { + [Test] + public void VerifyShortGuidRoundTrip() + { + var guid = Guid.NewGuid(); + + var shortGuid = guid.ToShortGuid(); + var roundTrip = shortGuid.FromShortGuid(); + + Assert.Multiple(() => + { + Assert.That(shortGuid, Has.Length.EqualTo(22)); + Assert.That(shortGuid, Does.Not.Contain("/").And.Not.Contain("+")); + Assert.That(roundTrip, Is.EqualTo(guid)); + }); + } + + [Test] + public void VerifyShortGuidArrayRoundTrip() + { + var guids = new List { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() }; + + var shortGuidArray = guids.ToShortGuidArray(); + var roundTrip = shortGuidArray.FromShortGuidArray().ToList(); + + Assert.Multiple(() => + { + Assert.That(shortGuidArray.StartsWith("[") && shortGuidArray.EndsWith("]"), Is.True); + Assert.That(roundTrip, Is.EqualTo(guids)); + }); + } + + } +} diff --git a/CDP4Common.NetCore.Tests/Helpers/ParameterValueValidatorTestFixture.cs b/CDP4Common.NetCore.Tests/Helpers/ParameterValueValidatorTestFixture.cs new file mode 100644 index 000000000..dae328db8 --- /dev/null +++ b/CDP4Common.NetCore.Tests/Helpers/ParameterValueValidatorTestFixture.cs @@ -0,0 +1,64 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Common.NetCore.Tests.Helpers +{ + using CDP4Common.Helpers; + using CDP4Common.SiteDirectoryData; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class ParameterValueValidatorTestFixture + { + [Test] + public void VerifyThatNullParameterTypeReturnsError() + { + var error = ParameterValueValidator.Validate("value", null); + + Assert.That(error, Is.EqualTo("Error: The parameter type is null.")); + } + + [Test] + public void VerifyThatValidBooleanValueReturnsNull() + { + var parameterType = new BooleanParameterType(); + + var error = ParameterValueValidator.Validate(true, parameterType); + + Assert.That(error, Is.Null); + } + + [Test] + public void VerifyThatInvalidBooleanValueReturnsValidationMessage() + { + var parameterType = new BooleanParameterType(); + + var error = ParameterValueValidator.Validate("not-a-boolean", parameterType); + + Assert.That(error, Does.Contain("not-a-boolean")); + } + } +} diff --git a/CDP4Dal.NetCore.Tests/DAL/AuthenticationInformationTestFixture.cs b/CDP4Dal.NetCore.Tests/DAL/AuthenticationInformationTestFixture.cs new file mode 100644 index 000000000..401e26967 --- /dev/null +++ b/CDP4Dal.NetCore.Tests/DAL/AuthenticationInformationTestFixture.cs @@ -0,0 +1,67 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Dal.NetCore.Tests.DAL +{ + using CDP4Dal.DAL; + using CDP4DalCommon.Authentication; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class AuthenticationInformationTestFixture + { + [Test] + public void VerifyConstructorWithUserNameAndPassword() + { + const string expectedUserName = "user"; + const string expectedPassword = "pass"; + + var information = new AuthenticationInformation(expectedUserName, expectedPassword); + + Assert.Multiple(() => + { + Assert.That(information.UserName, Is.EqualTo(expectedUserName)); + Assert.That(information.Password, Is.EqualTo(expectedPassword)); + Assert.That(information.Token, Is.Null); + }); + } + + [Test] + public void VerifyConstructorWithAuthenticationToken() + { + var expectedToken = new AuthenticationToken("access", "refresh"); + + var information = new AuthenticationInformation(expectedToken); + + Assert.Multiple(() => + { + Assert.That(information.Token, Is.SameAs(expectedToken)); + Assert.That(information.UserName, Is.Null); + Assert.That(information.Password, Is.Null); + }); + } + } +} diff --git a/CDP4Dal.NetCore.Tests/DAL/AvailableDalsTestFixture.cs b/CDP4Dal.NetCore.Tests/DAL/AvailableDalsTestFixture.cs new file mode 100644 index 000000000..a9b6931e2 --- /dev/null +++ b/CDP4Dal.NetCore.Tests/DAL/AvailableDalsTestFixture.cs @@ -0,0 +1,76 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Dal.NetCore.Tests.DAL +{ + using System; + using System.Collections.Generic; + using CDP4Dal; + using CDP4Dal.Composition; + using CDP4Dal.DAL; + using Moq; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class AvailableDalsTestFixture + { + [Test] + public void VerifyThatConstructorCopiesProvidedDalKinds() + { + var firstDal = new Lazy(() => Mock.Of(), new TestDalMetaData("first")); + var secondDal = new Lazy(() => Mock.Of(), new TestDalMetaData("second")); + var provided = new List> { firstDal, secondDal }; + + var availableDals = new AvailableDals(provided); + + Assert.Multiple(() => + { + Assert.That(availableDals.DataAccessLayerKinds, Is.Not.SameAs(provided)); + Assert.That(availableDals.DataAccessLayerKinds, Is.EquivalentTo(provided)); + }); + + provided.Add(new Lazy(() => Mock.Of(), new TestDalMetaData("third"))); + + Assert.That(availableDals.DataAccessLayerKinds, Has.Count.EqualTo(2)); + } + + private sealed class TestDalMetaData : IDalMetaData + { + public TestDalMetaData(string name) + { + this.Name = name; + } + + public DalType DalType => DalType.Web; + + public string CDPVersion => "1"; + + public string Name { get; } + + public string Description => this.Name; + } + } +} diff --git a/CDP4Reporting.Tests/DynamicTableCellTestFixture.cs b/CDP4Reporting.Tests/DynamicTableCellTestFixture.cs new file mode 100644 index 000000000..14111c6c6 --- /dev/null +++ b/CDP4Reporting.Tests/DynamicTableCellTestFixture.cs @@ -0,0 +1,64 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Reporting.Tests +{ + using CDP4Reporting.DynamicTableChecker; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class DynamicTableCellTestFixture + { + [Test] + public void VerifyConstructorInitializesExpression() + { + var cell = new DynamicTableCell("=Fields.Name"); + + Assert.Multiple(() => + { + Assert.That(cell.Expression, Is.EqualTo("=Fields.Name")); + Assert.That(cell.ForeColorExpression, Is.Null); + Assert.That(cell.BackColorExpression, Is.Null); + }); + } + + [Test] + public void VerifyExpressionsAreMutable() + { + var cell = new DynamicTableCell("=Fields.Value") + { + ForeColorExpression = "=Iif(Value > 0, 'Green', 'Red')", + BackColorExpression = "=Parameters.Background" + }; + + Assert.Multiple(() => + { + Assert.That(cell.ForeColorExpression, Is.EqualTo("=Iif(Value > 0, 'Green', 'Red')")); + Assert.That(cell.BackColorExpression, Is.EqualTo("=Parameters.Background")); + }); + } + } +} diff --git a/CDP4Reporting.Tests/ReportingParameterTestFixture.cs b/CDP4Reporting.Tests/ReportingParameterTestFixture.cs new file mode 100644 index 000000000..fe14d68c4 --- /dev/null +++ b/CDP4Reporting.Tests/ReportingParameterTestFixture.cs @@ -0,0 +1,68 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Reporting.Tests +{ + using System; + using CDP4Reporting.Parameters; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class ReportingParameterTestFixture + { + [Test] + public void VerifyParameterNameAndForceDefaultValue() + { + var parameter = new ReportingParameter("Total Mass", typeof(int), 5, "[Mass] > 0"); + + Assert.Multiple(() => + { + Assert.That(parameter.Name, Is.EqualTo("Total Mass")); + Assert.That(parameter.ParameterName, Is.EqualTo("dyn_Total_Mass")); + Assert.That(parameter.Type, Is.EqualTo(typeof(int))); + Assert.That(parameter.DefaultValue, Is.EqualTo(5)); + Assert.That(parameter.FilterExpression, Is.EqualTo("[Mass] > 0")); + Assert.That(parameter.ForceDefaultValue, Is.True); + }); + } + + [Test] + public void VerifyLookupValuesCanBeAddedFluently() + { + var parameter = new ReportingParameter("Status", typeof(string), "Open"); + + var returned = parameter.AddLookupValue(1, "Open").AddLookupValue(2, "Closed"); + + Assert.Multiple(() => + { + Assert.That(returned, Is.SameAs(parameter)); + Assert.That(parameter.LookUpValues, Has.Count.EqualTo(2)); + Assert.That(parameter.LookUpValues[1], Is.EqualTo("Open")); + Assert.That(parameter.LookUpValues[2], Is.EqualTo("Closed")); + }); + } + } +} diff --git a/CDP4Reporting.Tests/ReportingParametersTestFixture.cs b/CDP4Reporting.Tests/ReportingParametersTestFixture.cs new file mode 100644 index 000000000..82c32cb74 --- /dev/null +++ b/CDP4Reporting.Tests/ReportingParametersTestFixture.cs @@ -0,0 +1,76 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Reporting.Tests +{ + using System; + using System.Collections.Generic; + using CDP4Reporting.DataCollection; + using CDP4Reporting.Parameters; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class ReportingParametersTestFixture + { + [Test] + public void VerifyFilterStringConcatenation() + { + var reportingParameters = new TestReportingParameters(); + var parameters = new List + { + new ReportingParameter("First", typeof(string), null, "[Field1] = 1"), + new ReportingParameter("Second", typeof(string), null, "[Field2] = 2"), + new ReportingParameter("Third", typeof(string), null, " ") + }; + + var filter = reportingParameters.CreateFilterString(parameters); + + Assert.That(filter, Is.EqualTo("([Field1] = 1) Or ([Field2] = 2)")); + } + + [Test] + public void VerifyFilterStringIsEmptyWhenNoFiltersSpecified() + { + var reportingParameters = new TestReportingParameters(); + var parameters = new List + { + new ReportingParameter("First", typeof(string), null) + }; + + var filter = reportingParameters.CreateFilterString(parameters); + + Assert.That(filter, Is.Empty); + } + + private sealed class TestReportingParameters : ReportingParameters + { + public override IEnumerable CreateParameters(object dataSource, IDataCollector dataCollector) + { + throw new NotSupportedException(); + } + } + } +} diff --git a/CDP4Reporting.Tests/ReportingUtilitiesTestFixture.cs b/CDP4Reporting.Tests/ReportingUtilitiesTestFixture.cs new file mode 100644 index 000000000..86125a397 --- /dev/null +++ b/CDP4Reporting.Tests/ReportingUtilitiesTestFixture.cs @@ -0,0 +1,88 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Reporting.Tests +{ + using System.Collections.Generic; + using System.Data; + + using CDP4Common.EngineeringModelData; + + using CDP4Reporting.Utilities; + + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class ReportingUtilitiesTestFixture + { + [Test] + public void VerifyPrimitiveSequenceIsConvertedToDataTable() + { + var table = new DataTable(); + var result = new[] { 1, 2, 3 }.ToDataTable(table, LoadOption.Upsert); + + Assert.Multiple(() => + { + Assert.That(result.Columns.Contains("Value"), Is.True); + Assert.That(result.Rows.Count, Is.EqualTo(3)); + Assert.That(result.Rows[0]["Value"], Is.EqualTo(1)); + }); + } + + [Test] + public void VerifyComplexSequenceIsConvertedToDataTable() + { + var items = new List + { + new BaseItem { Name = "Base", Count = 1 }, + new DerivedItem { Name = "Derived", Count = 2, Extra = "extra" } + }; + + var table = items.ToDataTable(); + + Assert.Multiple(() => + { + Assert.That(table.Columns.Contains(nameof(BaseItem.Name)), Is.True); + Assert.That(table.Columns.Contains(nameof(BaseItem.Count)), Is.True); + Assert.That(table.Columns.Contains(nameof(DerivedItem.Extra)), Is.True); + Assert.That(table.Rows.Count, Is.EqualTo(2)); + Assert.That(table.Rows[1][nameof(DerivedItem.Extra)], Is.EqualTo("extra")); + }); + } + + private class BaseItem + { + public string Name { get; set; } + + public int Count; + } + + private sealed class DerivedItem : BaseItem + { + public string Extra { get; set; } + } + } +} diff --git a/CDP4ServicesDal.NetCore.Tests/ExternalAuthenticationProviderService/OpenIdConnectServiceTestFixture.cs b/CDP4ServicesDal.NetCore.Tests/ExternalAuthenticationProviderService/OpenIdConnectServiceTestFixture.cs new file mode 100644 index 000000000..a34d132fc --- /dev/null +++ b/CDP4ServicesDal.NetCore.Tests/ExternalAuthenticationProviderService/OpenIdConnectServiceTestFixture.cs @@ -0,0 +1,176 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4ServicesDal.NetCore.Tests.ExternalAuthenticationProviderService +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Net.Sockets; + using System.Text; + using System.Text.Json; + using System.Threading.Tasks; + using CDP4DalCommon.Authentication; + using CDP4ServicesDal.ExternalAuthenticationProviderService; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class OpenIdConnectServiceTestFixture + { + private readonly JsonSerializerOptions serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; + + [Test] + public async Task VerifyThatRefreshTokenFlowIsUsedWhenNoRedirectUriIsProvided() + { + using var listener = this.CreateListener(out var authority); + var schemeResponse = this.CreateSchemeResponse(authority); + var expectedToken = new AuthenticationToken("access", "refresh"); + var bodyTask = this.HandleRequestAsync(listener, 200, JsonSerializer.Serialize(expectedToken, this.serializerOptions)); + + var service = new OpenIdConnectService(); + var token = await service.RequestAuthenticationToken("refresh-token", schemeResponse, clientSecret: "secret"); + var body = await bodyTask; + var formValues = this.ParseFormUrlEncoded(body); + + Assert.Multiple(() => + { + Assert.That(token.AccessToken, Is.EqualTo(expectedToken.AccessToken)); + Assert.That(token.RefreshToken, Is.EqualTo(expectedToken.RefreshToken)); + Assert.That(formValues["grant_type"], Is.EqualTo("refresh_token")); + Assert.That(formValues["refresh_token"], Is.EqualTo("refresh-token")); + Assert.That(formValues["client_id"], Is.EqualTo(schemeResponse.ClientId)); + Assert.That(formValues["client_secret"], Is.EqualTo("secret")); + }); + } + + [Test] + public async Task VerifyThatAuthorizationCodeFlowIsUsedWhenRedirectUriIsProvided() + { + using var listener = this.CreateListener(out var authority); + var schemeResponse = this.CreateSchemeResponse(authority); + var expectedToken = new AuthenticationToken("access", "refresh"); + var bodyTask = this.HandleRequestAsync(listener, 200, JsonSerializer.Serialize(expectedToken, this.serializerOptions)); + + var service = new OpenIdConnectService(); + var token = await service.RequestAuthenticationToken("code-value", schemeResponse, "http://localhost/callback"); + var body = await bodyTask; + var formValues = this.ParseFormUrlEncoded(body); + + Assert.Multiple(() => + { + Assert.That(token.AccessToken, Is.EqualTo(expectedToken.AccessToken)); + Assert.That(formValues["grant_type"], Is.EqualTo("authorization_code")); + Assert.That(formValues["code"], Is.EqualTo("code-value")); + Assert.That(formValues["redirect_uri"], Is.EqualTo("http://localhost/callback")); + }); + } + + [Test] + public void VerifyThatUnsupportedSchemesThrow() + { + var schemeResponse = new AuthenticationSchemeResponse + { + Authority = "http://localhost", + ClientId = "client", + Schemes = new List { AuthenticationSchemeKind.Basic } + }; + + var service = new OpenIdConnectService(); + + Assert.That(() => service.RequestAuthenticationToken("code", schemeResponse), Throws.InvalidOperationException); + } + + [Test] + public async Task VerifyThatHttpErrorsAreSurfaced() + { + using var listener = this.CreateListener(out var authority); + var schemeResponse = this.CreateSchemeResponse(authority); + var bodyTask = this.HandleRequestAsync(listener, 500, string.Empty); + + var service = new OpenIdConnectService(); + + var exception = Assert.ThrowsAsync(() => service.RequestAuthenticationToken("code", schemeResponse)); + await bodyTask; + Assert.That(exception!.Message, Does.Contain("Status Code: 500")); + } + + private AuthenticationSchemeResponse CreateSchemeResponse(string authority) + { + return new AuthenticationSchemeResponse + { + Authority = authority, + ClientId = "client-id", + Schemes = new List { AuthenticationSchemeKind.ExternalJwtBearer } + }; + } + + private HttpListener CreateListener(out string authority) + { + var port = GetFreeTcpPort(); + authority = $"http://localhost:{port}"; + var listener = new HttpListener(); + listener.Prefixes.Add($"{authority}/"); + listener.Start(); + return listener; + } + + private async Task HandleRequestAsync(HttpListener listener, int statusCode, string responseContent) + { + var context = await listener.GetContextAsync(); + using var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding); + var body = await reader.ReadToEndAsync(); + + context.Response.StatusCode = statusCode; + if (!string.IsNullOrEmpty(responseContent)) + { + var buffer = Encoding.UTF8.GetBytes(responseContent); + await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length); + } + + context.Response.Close(); + return body; + } + + private Dictionary ParseFormUrlEncoded(string body) + { + return body.Split('&', StringSplitOptions.RemoveEmptyEntries) + .Select(part => part.Split('=', 2)) + .ToDictionary(kvp => Uri.UnescapeDataString(kvp[0]), kvp => Uri.UnescapeDataString(kvp[1])); + } + + private static int GetFreeTcpPort() + { + var listener = new TcpListener(IPAddress.Loopback, 0); + listener.Start(); + var port = ((IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; + } + } +} diff --git a/CDP4ServicesDal.NetCore.Tests/Helper/HttpClientExtensionsTestFixture.cs b/CDP4ServicesDal.NetCore.Tests/Helper/HttpClientExtensionsTestFixture.cs new file mode 100644 index 000000000..cdfe81751 --- /dev/null +++ b/CDP4ServicesDal.NetCore.Tests/Helper/HttpClientExtensionsTestFixture.cs @@ -0,0 +1,73 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2015-2025 Starion Group S.A. +// +// Author: Sam Gerené, Alex Vorobiev, Alexander van Delft, Nathanael Smiechowski, Antoine Théate +// +// This file is part of COMET-SDK Community Edition +// +// The COMET-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The COMET-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4ServicesDal.NetCore.Tests.Helper +{ + using System; + using System.Net.Http; + using System.Text; + using CDP4Dal.DAL; + using CDP4DalCommon.Authentication; + using CDP4ServicesDal.Extensions; + using NUnit.Framework; + + /// + /// Tests for . + /// + [TestFixture] + public class HttpClientExtensionsTestFixture + { + [Test] + public void VerifyThatBasicCredentialsProduceExpectedAuthorizationHeader() + { + var credentials = new Credentials("user", "password", new Uri("http://example.com")); + + using var client = new HttpClient(); + client.SetAuthorizationHeader(credentials); + + var expectedParameter = Convert.ToBase64String(Encoding.UTF8.GetBytes("user:password")); + + Assert.Multiple(() => + { + Assert.That(client.DefaultRequestHeaders.Authorization!.Scheme, Is.EqualTo(AuthenticationSchemeKind.Basic.ToString())); + Assert.That(client.DefaultRequestHeaders.Authorization.Parameter, Is.EqualTo(expectedParameter)); + }); + } + + [Test] + public void VerifyThatBearerTokenCredentialsProduceExpectedAuthorizationHeader() + { + var credentials = new Credentials(new Uri("http://example.com")); + credentials.ProvideUserToken(new AuthenticationToken("access-token", "refresh-token"), AuthenticationSchemeKind.ExternalJwtBearer); + + using var client = new HttpClient(); + client.SetAuthorizationHeader(credentials); + + Assert.Multiple(() => + { + Assert.That(client.DefaultRequestHeaders.Authorization!.Scheme, Is.EqualTo(AuthenticationSchemeKind.ExternalJwtBearer.ToString())); + Assert.That(client.DefaultRequestHeaders.Authorization.Parameter, Is.EqualTo("access-token")); + }); + } + } +}