diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index bb067b12b..15f86ae2c 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -3,7 +3,7 @@ * Make only high confidence suggestions when reviewing code changes. * Never change NuGet.config files unless explicitly asked to. -## Formatting +## Formatting and Style * Apply code-formatting style defined in `.editorconfig`. * Prefer file-scoped namespace declarations and single-line using directives. @@ -11,6 +11,7 @@ * Ensure that the final return statement of a method is on its own line. * Use pattern matching and switch expressions wherever possible. * Use `nameof` instead of string literals when referring to member names. +* Delete unused `using` directives ### Nullable Reference Types @@ -27,4 +28,5 @@ ## Running tests +* Copilot should build and run unit tests after making changes * To build and run tests in the repo, use the command `./build.ps1 UnitTest` diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/AddOdsInstanceContextTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/AddOdsInstanceContextTests.cs new file mode 100644 index 000000000..834a74b7e --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/AddOdsInstanceContextTests.cs @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using AutoMapper; +using EdFi.Admin.DataAccess.Models; +using EdFi.Ods.AdminApi.Common.Infrastructure; +using EdFi.Ods.AdminApi.Common.Infrastructure.ErrorHandling; +using EdFi.Ods.AdminApi.Features.OdsInstanceContext; +using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; +using EdFi.Ods.AdminApi.Infrastructure.Database.Queries; +using FakeItEasy; +using FluentValidation; +using Microsoft.AspNetCore.Http; +using NUnit.Framework; +using Shouldly; +using OdsInstanceContextEntity = EdFi.Admin.DataAccess.Models.OdsInstanceContext; + +namespace EdFi.Ods.AdminApi.UnitTests.Features.OdsInstanceContext; + +[TestFixture] +public class AddOdsInstanceContextTests +{ + private AddOdsInstanceContext.Validator _validator; + private IGetOdsInstanceQuery _getOdsInstanceQuery; + private IGetOdsInstanceContextsQuery _getOdsInstanceContextsQuery; + + [SetUp] + public void SetUp() + { + _getOdsInstanceQuery = A.Fake(); + _getOdsInstanceContextsQuery = A.Fake(); + _validator = new AddOdsInstanceContext.Validator(_getOdsInstanceQuery, _getOdsInstanceContextsQuery); + } + + [Test] + public async Task Handle_ExecutesCommandAndReturnsCreated() + { + // Arrange + + var command = A.Fake(); + var mapper = A.Fake(); + var request = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + OdsInstanceId = 1, + ContextKey = "TestKey", + ContextValue = "TestValue" + }; + var addedContext = new OdsInstanceContextEntity { OdsInstanceContextId = 123 }; + + A.CallTo(() => command.Execute(request)).Returns(addedContext); + + // Act + var result = await AddOdsInstanceContext.Handle(_validator, command, mapper, request); + + // Assert + A.CallTo(() => command.Execute(request)).MustHaveHappenedOnceExactly(); + result.ShouldNotBeNull(); + result.ShouldBeOfType(); + } + + [Test] + public void Handle_WhenValidationFails_ThrowsValidationException() + { + // Arrange + + var command = A.Fake(); + var mapper = A.Fake(); + var request = new AddOdsInstanceContext.AddOdsInstanceContextRequest(); + + // Act & Assert + Should.Throw( + async () => await AddOdsInstanceContext.Handle(_validator, command, mapper, request) + ); + } + + [Test] + public void Handle_WhenCommandThrows_ExceptionIsPropagated() + { + // Arrange + + var command = A.Fake(); + var mapper = A.Fake(); + var request = new AddOdsInstanceContext.AddOdsInstanceContextRequest(); + + A.CallTo(() => command.Execute(request)).Throws(new System.Exception("Command failed")); + + // Act & Assert + Should.Throw( + async () => await AddOdsInstanceContext.Handle(_validator, command, mapper, request) + ); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextKey_Is_Empty() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextKey)); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextKey_Is_Null() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = null, + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextKey)); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextValue_Is_Empty() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "TestKey", + ContextValue = "", + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextValue)); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextValue_Is_Null() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "TestKey", + ContextValue = null, + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextValue)); + } + + [Test] + public void Validator_Should_Have_Error_When_OdsInstanceId_Is_Zero() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "TestKey", + ContextValue = "TestValue", + OdsInstanceId = 0 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.OdsInstanceId)); + } + + [Test] + public void Validator_Should_Have_Error_When_OdsInstance_Does_Not_Exist() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "TestKey", + ContextValue = "TestValue", + OdsInstanceId = 999 + }; + + A.CallTo(() => _getOdsInstanceQuery.Execute(999)) + .Throws(new NotFoundException("odsInstance", 999)); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.OdsInstanceId)); + } + + [Test] + public void Validator_Should_Have_Error_When_Combined_Key_Is_Not_Unique() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "ExistingKey", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + ContextKey = "ExistingKey", + OdsInstance = new OdsInstance { OdsInstanceId = 1 } + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == ""); + } + + [Test] + public void Validator_Should_Pass_When_Combined_Key_Is_Unique() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "UniqueKey", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + ContextKey = "DifferentKey", + OdsInstance = new OdsInstance { OdsInstanceId = 1 } + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } + + [Test] + public void Validator_Should_Pass_With_Valid_Model() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "ValidKey", + ContextValue = "ValidValue", + OdsInstanceId = 1 + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(new List()); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } + + [Test] + public void BeAnExistingOdsInstance_Should_Return_True_When_OdsInstance_Exists() + { + // Arrange + var odsInstanceId = 1; + A.CallTo(() => _getOdsInstanceQuery.Execute(odsInstanceId)).Returns(new OdsInstance()); + + // Act + var result = _validator.Validate( + new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "TestKey", + ContextValue = "TestValue", + OdsInstanceId = odsInstanceId + } + ); + + // Assert - The validation should pass (assuming other fields are valid) + A.CallTo(() => _getOdsInstanceQuery.Execute(odsInstanceId)).MustHaveHappenedOnceExactly(); + } + + [Test] + public void BeUniqueCombinedKey_Should_Return_True_When_Key_Is_Case_Insensitive_Unique() + { + // Arrange + var model = new AddOdsInstanceContext.AddOdsInstanceContextRequest + { + ContextKey = "TESTKEY", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + ContextKey = "testkey", // different case + OdsInstance = new OdsInstance { OdsInstanceId = 2 } // different instance + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } +} diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/DeleteOdsInstanceContextTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/DeleteOdsInstanceContextTests.cs new file mode 100644 index 000000000..0c7324a2c --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/DeleteOdsInstanceContextTests.cs @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using System.Threading.Tasks; +using EdFi.Ods.AdminApi.Features.OdsInstanceContext; +using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; +using FakeItEasy; +using Microsoft.AspNetCore.Http; +using NUnit.Framework; +using Shouldly; + +namespace EdFi.Ods.AdminApi.UnitTests.Features.OdsInstanceContext; + +[TestFixture] +public class DeleteOdsInstanceContextTests +{ + [Test] + public async Task Handle_ExecutesDeleteCommandAndReturnsOk() + { + // Arrange + var fakeCommand = A.Fake(); + int testId = 123; + + // Act + var result = await DeleteOdsInstanceContext.Handle(fakeCommand, testId); + + // Assert + A.CallTo(() => fakeCommand.Execute(testId)).MustHaveHappenedOnceExactly(); + result.ShouldNotBeNull(); + result.ShouldBeOfType(); + } + + [Test] + public void Handle_WhenCommandThrows_ExceptionIsPropagated() + { + // Arrange + var fakeCommand = A.Fake(); + int testId = 999; + A.CallTo(() => fakeCommand.Execute(testId)).Throws(new System.Exception("Delete failed")); + + // Act & Assert + Should.Throw(async () => await DeleteOdsInstanceContext.Handle(fakeCommand, testId)); + } + + [Test] + public async Task Handle_WithZeroId_ExecutesCommand() + { + // Arrange + var fakeCommand = A.Fake(); + int testId = 0; + + // Act + var result = await DeleteOdsInstanceContext.Handle(fakeCommand, testId); + + // Assert + A.CallTo(() => fakeCommand.Execute(testId)).MustHaveHappenedOnceExactly(); + result.ShouldNotBeNull(); + result.ShouldBeOfType(); + } + + [Test] + public async Task Handle_WithNegativeId_ExecutesCommand() + { + // Arrange + var fakeCommand = A.Fake(); + int testId = -1; + + // Act + var result = await DeleteOdsInstanceContext.Handle(fakeCommand, testId); + + // Assert + A.CallTo(() => fakeCommand.Execute(testId)).MustHaveHappenedOnceExactly(); + result.ShouldNotBeNull(); + result.ShouldBeOfType(); + } +} \ No newline at end of file diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/EditOdsInstanceContextTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/EditOdsInstanceContextTests.cs new file mode 100644 index 000000000..59ff99a08 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/EditOdsInstanceContextTests.cs @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AutoMapper; +using EdFi.Admin.DataAccess.Contexts; +using EdFi.Admin.DataAccess.Models; +using EdFi.Ods.AdminApi.Common.Infrastructure; +using EdFi.Ods.AdminApi.Features.OdsInstanceContext; +using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; +using EdFi.Ods.AdminApi.Infrastructure.Database.Queries; +using FakeItEasy; +using FluentValidation; +using Microsoft.AspNetCore.Http; +using NUnit.Framework; +using Shouldly; +using OdsInstanceContextEntity = EdFi.Admin.DataAccess.Models.OdsInstanceContext; + +namespace EdFi.Ods.AdminApi.UnitTests.Features.OdsInstanceContext; + +[TestFixture] +public class EditOdsInstanceContextTests +{ + private EditOdsInstanceContext.Validator _validator; + private IGetOdsInstanceQuery _getOdsInstanceQuery; + private IGetOdsInstanceContextsQuery _getOdsInstanceContextsQuery; + + [SetUp] + public void SetUp() + { + _getOdsInstanceQuery = A.Fake(); + _getOdsInstanceContextsQuery = A.Fake(); + _validator = new EditOdsInstanceContext.Validator(_getOdsInstanceQuery, _getOdsInstanceContextsQuery); + } + + [Test] + public async Task Handle_ExecutesCommandAndReturnsOk() + { + // Arrange + var command = A.Fake(); + var mapper = A.Fake(); + var db = A.Fake(); + var request = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + OdsInstanceId = 1, + ContextKey = "TestKey", + ContextValue = "TestValue" + }; + int id = 123; + var editedContext = new OdsInstanceContextEntity { OdsInstanceContextId = id }; + + A.CallTo(() => command.Execute(request)).Returns(editedContext); + A.CallTo(() => _getOdsInstanceQuery.Execute(request.OdsInstanceId)) + .Returns(new OdsInstance { OdsInstanceId = request.OdsInstanceId }); + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns([]); + + // Act + try + { + var result = await EditOdsInstanceContext.Handle(_validator, command, mapper, db, request, id); + + // Assert + request.Id.ShouldBe(id); + A.CallTo(() => command.Execute(request)).MustHaveHappenedOnceExactly(); + result.ShouldNotBeNull(); + result.ShouldBeOfType(); + } + catch (ValidationException vex) + { + Assert.Fail(string.Join(";", vex.Errors.Select(e => e.ErrorMessage))); + } + } + + [Test] + public void Handle_WhenValidationFails_ThrowsValidationException() + { + // Arrange + var command = A.Fake(); + var mapper = A.Fake(); + var db = A.Fake(); + var request = new EditOdsInstanceContext.EditOdsInstanceContextRequest(); + int id = 123; + + A.CallTo(() => _getOdsInstanceQuery.Execute(request.OdsInstanceId)).Returns(new OdsInstance()); + + // Act & Assert + Should.Throw( + async () => await EditOdsInstanceContext.Handle(_validator, command, mapper, db, request, id) + ); + } + + [Test] + public void Handle_WhenCommandThrows_ExceptionIsPropagated() + { + // Arrange + var command = A.Fake(); + var mapper = A.Fake(); + var db = A.Fake(); + var request = new EditOdsInstanceContext.EditOdsInstanceContextRequest(); + int id = 123; + + A.CallTo(() => command.Execute(request)).Throws(new System.Exception("Command failed")); + + // Act & Assert + Should.Throw( + async () => await EditOdsInstanceContext.Handle(_validator, command, mapper, db, request, id) + ); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextKey_Is_Empty() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextKey)); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextKey_Is_Null() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = null, + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextKey)); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextValue_Is_Empty() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "TestKey", + ContextValue = "", + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextValue)); + } + + [Test] + public void Validator_Should_Have_Error_When_ContextValue_Is_Null() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "TestKey", + ContextValue = null, + OdsInstanceId = 1 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.ContextValue)); + } + + [Test] + public void Validator_Should_Have_Error_When_OdsInstanceId_Is_Zero() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "TestKey", + ContextValue = "TestValue", + OdsInstanceId = 0 + }; + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == nameof(model.OdsInstanceId)); + } + + [Test] + public void Validator_Should_Have_Error_When_Combined_Key_Is_Not_Unique() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "ExistingKey", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + OdsInstanceContextId = 2, // Different ID + ContextKey = "ExistingKey", + OdsInstance = new OdsInstance { OdsInstanceId = 1 } + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeFalse(); + result.Errors.ShouldContain(x => x.PropertyName == ""); + } + + [Test] + public void Validator_Should_Pass_When_Combined_Key_Is_Same_For_Same_Record() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "ExistingKey", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + OdsInstanceContextId = 1, // Same ID + ContextKey = "ExistingKey", + OdsInstance = new OdsInstance { OdsInstanceId = 1 } + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } + + [Test] + public void Validator_Should_Pass_When_Combined_Key_Is_Unique() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "UniqueKey", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + OdsInstanceContextId = 2, + ContextKey = "DifferentKey", + OdsInstance = new OdsInstance { OdsInstanceId = 1 } + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } + + [Test] + public void Validator_Should_Pass_With_Valid_Model() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "ValidKey", + ContextValue = "ValidValue", + OdsInstanceId = 1 + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(new List()); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } + + [Test] + public void BeAnExistingOdsInstance_Should_Return_True_When_OdsInstance_Exists() + { + // Arrange + var odsInstanceId = 1; + A.CallTo(() => _getOdsInstanceQuery.Execute(odsInstanceId)).Returns(new OdsInstance()); + + // Act + var result = _validator.Validate( + new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "TestKey", + ContextValue = "TestValue", + OdsInstanceId = odsInstanceId + } + ); + + // Assert - The validation should pass (assuming other fields are valid) + A.CallTo(() => _getOdsInstanceQuery.Execute(odsInstanceId)).MustHaveHappenedOnceExactly(); + } + + [Test] + public void BeUniqueCombinedKey_Should_Return_True_When_Key_Is_Case_Insensitive_Unique() + { + // Arrange + var model = new EditOdsInstanceContext.EditOdsInstanceContextRequest + { + Id = 1, + ContextKey = "TESTKEY", + ContextValue = "TestValue", + OdsInstanceId = 1 + }; + + var existingContexts = new List + { + new OdsInstanceContextEntity + { + OdsInstanceContextId = 2, + ContextKey = "testkey", // different case + OdsInstance = new OdsInstance { OdsInstanceId = 2 } // different instance + } + }; + + A.CallTo(() => _getOdsInstanceContextsQuery.Execute()).Returns(existingContexts); + + // Act + var result = _validator.Validate(model); + + // Assert + result.IsValid.ShouldBeTrue(); + } +} diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/ReadOdsInstanceContextTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/ReadOdsInstanceContextTests.cs new file mode 100644 index 000000000..6ea228be5 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Features/OdsInstanceContext/ReadOdsInstanceContextTests.cs @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using EdFi.Ods.AdminApi.Features.OdsInstanceContext; +using NUnit.Framework; +using Shouldly; +using System; + +namespace EdFi.Ods.AdminApi.UnitTests.Features.OdsInstanceContext; + +[TestFixture] +public class ReadOdsInstanceContextTests +{ + [Test] + public void ReadOdsInstanceContext_ImplementsIFeature() + { + // Arrange & Act + var readOdsInstanceContext = new ReadOdsInstanceContext(); + + // Assert + readOdsInstanceContext.ShouldBeAssignableTo(); + } + + [Test] + public void MapEndpoints_DoesNotExceptNull() + { + // Arrange + var readOdsInstanceContext = new ReadOdsInstanceContext(); + + // Act & Assert + Should.Throw(() => readOdsInstanceContext.MapEndpoints(null!)); + } +} diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/AddOdsInstanceContextCommandTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/AddOdsInstanceContextCommandTests.cs new file mode 100644 index 000000000..a6a434a7b --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/AddOdsInstanceContextCommandTests.cs @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using EdFi.Admin.DataAccess.Contexts; +using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; +using FakeItEasy; +using NUnit.Framework; +using Shouldly; + +namespace EdFi.Ods.AdminApi.UnitTests.Infrastructure.Database.Commands; + +[TestFixture] +public class AddOdsInstanceContextCommandTests +{ + [Test] + public void Constructor_WithValidContext_InitializesSuccessfully() + { + // Arrange & Act + var context = A.Fake(); + var command = new AddOdsInstanceContextCommand(context); + + // Assert + command.ShouldNotBeNull(); + } + + [Test] + public void Constructor_WithNullContext_ShouldThrowArgumentNullException() + { + // Act & Assert + Should.Throw(() => new AddOdsInstanceContextCommand(null)); + } +} diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommandTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommandTests.cs new file mode 100644 index 000000000..5ef92c323 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommandTests.cs @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using EdFi.Admin.DataAccess.Contexts; +using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; +using FakeItEasy; +using NUnit.Framework; +using Shouldly; + +namespace EdFi.Ods.AdminApi.UnitTests.Infrastructure.Database.Commands; + +[TestFixture] +public class DeleteOdsInstanceContextCommandTests +{ + [Test] + public void Constructor_WithValidContext_InitializesSuccessfully() + { + // Arrange & Act + var context = A.Fake(); + var command = new DeleteOdsInstanceContextCommand(context); + + // Assert + command.ShouldNotBeNull(); + } + + [Test] + public void Constructor_WithNullContext_ShouldThrowArgumentNullException() + { + // Act & Assert + Should.Throw(() => new DeleteOdsInstanceContextCommand(null)); + } +} diff --git a/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/EditOdsInstanceContextCommandTests.cs b/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/EditOdsInstanceContextCommandTests.cs new file mode 100644 index 000000000..3ec09df76 --- /dev/null +++ b/Application/EdFi.Ods.AdminApi.UnitTests/Infrastructure/Database/Commands/EditOdsInstanceContextCommandTests.cs @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using EdFi.Admin.DataAccess.Contexts; +using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; +using FakeItEasy; +using NUnit.Framework; +using Shouldly; + +namespace EdFi.Ods.AdminApi.UnitTests.Infrastructure.Database.Commands; + +[TestFixture] +public class EditOdsInstanceContextCommandTests +{ + [Test] + public void Constructor_WithValidContext_InitializesSuccessfully() + { + // Arrange & Act + var context = A.Fake(); + var command = new EditOdsInstanceContextCommand(context); + + // Assert + command.ShouldNotBeNull(); + } + + [Test] + public void Constructor_WithNullContext_ShouldThrowArgumentNullException() + { + // Act & Assert + Should.Throw(() => new EditOdsInstanceContextCommand(null)); + } +} diff --git a/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/AddOdsInstanceContext.cs b/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/AddOdsInstanceContext.cs index dab366bfd..35bd862c4 100644 --- a/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/AddOdsInstanceContext.cs +++ b/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/AddOdsInstanceContext.cs @@ -4,13 +4,15 @@ // See the LICENSE and NOTICES files in the project root for more information. using AutoMapper; -using FluentValidation; -using Swashbuckle.AspNetCore.Annotations; +using EdFi.Ods.AdminApi.Common.Features; +using EdFi.Ods.AdminApi.Common.Infrastructure; +using EdFi.Ods.AdminApi.Common.Infrastructure.ErrorHandling; using EdFi.Ods.AdminApi.Infrastructure; using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; using EdFi.Ods.AdminApi.Infrastructure.Database.Queries; -using EdFi.Ods.AdminApi.Common.Features; -using EdFi.Ods.AdminApi.Common.Infrastructure; +using FluentValidation; +using Swashbuckle.AspNetCore.Annotations; + namespace EdFi.Ods.AdminApi.Features.OdsInstanceContext; public class AddOdsInstanceContext : IFeature @@ -18,28 +20,43 @@ public class AddOdsInstanceContext : IFeature public void MapEndpoints(IEndpointRouteBuilder endpoints) { AdminApiEndpointBuilder - .MapPost(endpoints, "/odsInstanceContexts", Handle) - .WithDefaultSummaryAndDescription() - .WithRouteOptions(b => b.WithResponseCode(201)) - .BuildForVersions(AdminApiVersions.V2); + .MapPost(endpoints, "/odsInstanceContexts", Handle) + .WithDefaultSummaryAndDescription() + .WithRouteOptions(b => b.WithResponseCode(201)) + .BuildForVersions(AdminApiVersions.V2); } - public static async Task Handle(Validator validator, IAddOdsInstanceContextCommand addOdsInstanceContextCommand, IMapper mapper, AddOdsInstanceContextRequest request) + public static async Task Handle( + Validator validator, + IAddOdsInstanceContextCommand addOdsInstanceContextCommand, + IMapper mapper, + AddOdsInstanceContextRequest request + ) { await validator.GuardAsync(request); var addedOdsInstanceContext = addOdsInstanceContextCommand.Execute(request); return Results.Created($"/odsInstanceContexts/{addedOdsInstanceContext.OdsInstanceContextId}", null); } - [SwaggerSchema(Title = "AddOdsInstanceContextRequest")] public class AddOdsInstanceContextRequest : IAddOdsInstanceContextModel { - [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextOdsInstanceIdDescription, Nullable = false)] + [SwaggerSchema( + Description = FeatureConstants.OdsInstanceContextOdsInstanceIdDescription, + Nullable = false + )] public int OdsInstanceId { get; set; } - [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextContextKeyDescription, Nullable = false)] + + [SwaggerSchema( + Description = FeatureConstants.OdsInstanceContextContextKeyDescription, + Nullable = false + )] public string? ContextKey { get; set; } - [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextContextValueDescription, Nullable = false)] + + [SwaggerSchema( + Description = FeatureConstants.OdsInstanceContextContextValueDescription, + Nullable = false + )] public string? ContextValue { get; set; } } @@ -48,7 +65,10 @@ public class Validator : AbstractValidator private readonly IGetOdsInstanceQuery _getOdsInstanceQuery; private readonly IGetOdsInstanceContextsQuery _getOdsInstanceContextsQuery; - public Validator(IGetOdsInstanceQuery getOdsInstanceQuery, IGetOdsInstanceContextsQuery getOdsInstanceContextsQuery) + public Validator( + IGetOdsInstanceQuery getOdsInstanceQuery, + IGetOdsInstanceContextsQuery getOdsInstanceContextsQuery + ) { _getOdsInstanceQuery = getOdsInstanceQuery; _getOdsInstanceContextsQuery = getOdsInstanceContextsQuery; @@ -60,27 +80,39 @@ public Validator(IGetOdsInstanceQuery getOdsInstanceQuery, IGetOdsInstanceContex .NotEqual(0) .WithMessage(FeatureConstants.OdsInstanceIdValidationMessage); - RuleFor(m => m.OdsInstanceId) - .Must(BeAnExistingOdsInstance) - .When(m => !m.OdsInstanceId.Equals(0)); + RuleFor(m => m.OdsInstanceId).Must(BeAnExistingOdsInstance).When(m => !m.OdsInstanceId.Equals(0)); RuleFor(odsContext => odsContext) - .Must(BeUniqueCombinedKey) - .WithMessage(FeatureConstants.OdsInstanceContextCombinedKeyMustBeUnique); - + .Must(BeUniqueCombinedKey) + .WithMessage(FeatureConstants.OdsInstanceContextCombinedKeyMustBeUnique); } private bool BeAnExistingOdsInstance(int id) { - _getOdsInstanceQuery.Execute(id); - return true; + try + { + _getOdsInstanceQuery.Execute(id); + return true; + } + catch (NotFoundException) + { + return false; + } + catch (Exception ex) + { + System.Console.WriteLine(ex); + return false; + } } private bool BeUniqueCombinedKey(AddOdsInstanceContextRequest request) { - return !_getOdsInstanceContextsQuery.Execute().Exists - (x => x.OdsInstance?.OdsInstanceId == request.OdsInstanceId && - x.ContextKey.Equals(request.ContextKey, StringComparison.OrdinalIgnoreCase)); + return !_getOdsInstanceContextsQuery + .Execute() + .Exists(x => + x.OdsInstance?.OdsInstanceId == request.OdsInstanceId + && x.ContextKey.Equals(request.ContextKey, StringComparison.OrdinalIgnoreCase) + ); } } } diff --git a/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/EditOdsInstanceContext.cs b/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/EditOdsInstanceContext.cs index 34a7d63cd..0d7f63350 100644 --- a/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/EditOdsInstanceContext.cs +++ b/Application/EdFi.Ods.AdminApi/Features/OdsInstanceContext/EditOdsInstanceContext.cs @@ -7,7 +7,7 @@ using EdFi.Admin.DataAccess.Contexts; using EdFi.Ods.AdminApi.Common.Features; using EdFi.Ods.AdminApi.Common.Infrastructure; -using EdFi.Ods.AdminApi.Infrastructure; +using EdFi.Ods.AdminApi.Common.Infrastructure.ErrorHandling; using EdFi.Ods.AdminApi.Infrastructure.Database.Commands; using EdFi.Ods.AdminApi.Infrastructure.Database.Queries; using EdFi.Ods.AdminApi.Infrastructure.Documentation; @@ -27,7 +27,14 @@ public void MapEndpoints(IEndpointRouteBuilder endpoints) .BuildForVersions(AdminApiVersions.V2); } - public static async Task Handle(Validator validator, IEditOdsInstanceContextCommand editOdsInstanceContextCommand, IMapper mapper, IUsersContext db, EditOdsInstanceContextRequest request, int id) + public static async Task Handle( + Validator validator, + IEditOdsInstanceContextCommand editOdsInstanceContextCommand, + IMapper mapper, + IUsersContext db, + EditOdsInstanceContextRequest request, + int id + ) { request.Id = id; await validator.GuardAsync(request); @@ -35,18 +42,29 @@ public static async Task Handle(Validator validator, IEditOdsInstanceCo return Results.Ok(); } - [SwaggerSchema(Title = "EditOdsInstanceContextRequest")] public class EditOdsInstanceContextRequest : IEditOdsInstanceContextModel { [SwaggerExclude] [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextIdDescription, Nullable = false)] public int Id { get; set; } - [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextOdsInstanceIdDescription, Nullable = false)] + + [SwaggerSchema( + Description = FeatureConstants.OdsInstanceContextOdsInstanceIdDescription, + Nullable = false + )] public int OdsInstanceId { get; set; } - [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextContextKeyDescription, Nullable = false)] + + [SwaggerSchema( + Description = FeatureConstants.OdsInstanceContextContextKeyDescription, + Nullable = false + )] public string? ContextKey { get; set; } - [SwaggerSchema(Description = FeatureConstants.OdsInstanceContextContextValueDescription, Nullable = false)] + + [SwaggerSchema( + Description = FeatureConstants.OdsInstanceContextContextValueDescription, + Nullable = false + )] public string? ContextValue { get; set; } } @@ -55,7 +73,10 @@ public class Validator : AbstractValidator private readonly IGetOdsInstanceQuery _getOdsInstanceQuery; private readonly IGetOdsInstanceContextsQuery _getOdsInstanceContextsQuery; - public Validator(IGetOdsInstanceQuery getOdsInstanceQuery, IGetOdsInstanceContextsQuery getOdsInstanceContextsQuery) + public Validator( + IGetOdsInstanceQuery getOdsInstanceQuery, + IGetOdsInstanceContextsQuery getOdsInstanceContextsQuery + ) { _getOdsInstanceQuery = getOdsInstanceQuery; _getOdsInstanceContextsQuery = getOdsInstanceContextsQuery; @@ -67,9 +88,7 @@ public Validator(IGetOdsInstanceQuery getOdsInstanceQuery, IGetOdsInstanceContex .NotEqual(0) .WithMessage(FeatureConstants.OdsInstanceIdValidationMessage); - RuleFor(m => m.OdsInstanceId) - .Must(BeAnExistingOdsInstance) - .When(m => !m.OdsInstanceId.Equals(0)); + RuleFor(m => m.OdsInstanceId).Must(BeAnExistingOdsInstance).When(m => !m.OdsInstanceId.Equals(0)); RuleFor(odsContext => odsContext) .Must(BeUniqueCombinedKey) @@ -78,16 +97,26 @@ public Validator(IGetOdsInstanceQuery getOdsInstanceQuery, IGetOdsInstanceContex private bool BeAnExistingOdsInstance(int id) { - _getOdsInstanceQuery.Execute(id); - return true; + try + { + _getOdsInstanceQuery.Execute(id); + return true; + } + catch (NotFoundException) + { + return false; + } } private bool BeUniqueCombinedKey(EditOdsInstanceContextRequest request) { - return !_getOdsInstanceContextsQuery.Execute().Exists - (x => x.OdsInstance?.OdsInstanceId == request.OdsInstanceId && - x.ContextKey.Equals(request.ContextKey, StringComparison.OrdinalIgnoreCase) && - x.OdsInstanceContextId != request.Id); + return !_getOdsInstanceContextsQuery + .Execute() + .Exists(x => + x.OdsInstance?.OdsInstanceId == request.OdsInstanceId + && x.ContextKey.Equals(request.ContextKey, StringComparison.OrdinalIgnoreCase) + && x.OdsInstanceContextId != request.Id + ); } } } diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/AddOdsInstanceContextCommand.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/AddOdsInstanceContextCommand.cs index 7af2cebe4..b09048b2a 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/AddOdsInstanceContextCommand.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/AddOdsInstanceContextCommand.cs @@ -1,48 +1,49 @@ -// SPDX-License-Identifier: Apache-2.0 -// Licensed to the Ed-Fi Alliance under one or more agreements. -// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. -// See the LICENSE and NOTICES files in the project root for more information. - -using EdFi.Admin.DataAccess.Contexts; -using EdFi.Admin.DataAccess.Models; -using EdFi.Ods.AdminApi.Common.Infrastructure.ErrorHandling; - -namespace EdFi.Ods.AdminApi.Infrastructure.Database.Commands; - -public interface IAddOdsInstanceContextCommand -{ - OdsInstanceContext Execute(IAddOdsInstanceContextModel newOdsInstanceContext); -} - -public class AddOdsInstanceContextCommand : IAddOdsInstanceContextCommand -{ - private readonly IUsersContext _context; - - public AddOdsInstanceContextCommand(IUsersContext context) - { - _context = context; - } - - public OdsInstanceContext Execute(IAddOdsInstanceContextModel newOdsInstanceContext) +// SPDX-License-Identifier: Apache-2.0 +// Licensed to the Ed-Fi Alliance under one or more agreements. +// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0. +// See the LICENSE and NOTICES files in the project root for more information. + +using EdFi.Admin.DataAccess.Contexts; +using EdFi.Admin.DataAccess.Models; +using EdFi.Ods.AdminApi.Common.Infrastructure.ErrorHandling; + +namespace EdFi.Ods.AdminApi.Infrastructure.Database.Commands; + +public interface IAddOdsInstanceContextCommand +{ + OdsInstanceContext Execute(IAddOdsInstanceContextModel newOdsInstanceContext); +} + +public class AddOdsInstanceContextCommand : IAddOdsInstanceContextCommand +{ + private readonly IUsersContext _context; + + public AddOdsInstanceContextCommand(IUsersContext context) { - var odsInstance = _context.OdsInstances.SingleOrDefault(v => v.OdsInstanceId == newOdsInstanceContext.OdsInstanceId) ?? - throw new NotFoundException("odsInstance", newOdsInstanceContext.OdsInstanceId); - - var odsInstanceContext = new OdsInstanceContext - { - ContextKey = newOdsInstanceContext.ContextKey, - ContextValue = newOdsInstanceContext.ContextValue, - OdsInstance = odsInstance - }; - _context.OdsInstanceContexts.Add(odsInstanceContext); - _context.SaveChanges(); - return odsInstanceContext; - } -} - -public interface IAddOdsInstanceContextModel -{ - public int OdsInstanceId { get; set; } - public string? ContextKey { get; set; } - public string? ContextValue { get; set; } -} + _context = context ?? throw new ArgumentNullException(nameof(context)); + } + + public OdsInstanceContext Execute(IAddOdsInstanceContextModel newOdsInstanceContext) + { + var odsInstance = + _context.OdsInstances.SingleOrDefault(v => v.OdsInstanceId == newOdsInstanceContext.OdsInstanceId) + ?? throw new NotFoundException("odsInstance", newOdsInstanceContext.OdsInstanceId); + + var odsInstanceContext = new OdsInstanceContext + { + ContextKey = newOdsInstanceContext.ContextKey, + ContextValue = newOdsInstanceContext.ContextValue, + OdsInstance = odsInstance + }; + _context.OdsInstanceContexts.Add(odsInstanceContext); + _context.SaveChanges(); + return odsInstanceContext; + } +} + +public interface IAddOdsInstanceContextModel +{ + int OdsInstanceId { get; set; } + string? ContextKey { get; set; } + string? ContextValue { get; set; } +} diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommand.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommand.cs index d37d7d2cd..8832d774c 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommand.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/DeleteOdsInstanceContextCommand.cs @@ -19,12 +19,14 @@ public class DeleteOdsInstanceContextCommand : IDeleteOdsInstanceContextCommand public DeleteOdsInstanceContextCommand(IUsersContext context) { - _context = context; + _context = context ?? throw new ArgumentNullException(nameof(context)); } public void Execute(int id) { - var odsInstanceContext = _context.OdsInstanceContexts.SingleOrDefault(v => v.OdsInstanceContextId == id) ?? throw new NotFoundException("odsInstanceContext", id); + var odsInstanceContext = + _context.OdsInstanceContexts.SingleOrDefault(v => v.OdsInstanceContextId == id) + ?? throw new NotFoundException("odsInstanceContext", id); _context.OdsInstanceContexts.Remove(odsInstanceContext); _context.SaveChanges(); } diff --git a/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/EditOdsInstanceContextCommand.cs b/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/EditOdsInstanceContextCommand.cs index 2fa77e3b5..a54be3aa2 100644 --- a/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/EditOdsInstanceContextCommand.cs +++ b/Application/EdFi.Ods.AdminApi/Infrastructure/Database/Commands/EditOdsInstanceContextCommand.cs @@ -6,8 +6,8 @@ using EdFi.Admin.DataAccess.Contexts; using EdFi.Admin.DataAccess.Models; using EdFi.Ods.AdminApi.Common.Infrastructure.ErrorHandling; -using Microsoft.EntityFrameworkCore; - +using Microsoft.EntityFrameworkCore; + namespace EdFi.Ods.AdminApi.Infrastructure.Database.Commands; public interface IEditOdsInstanceContextCommand @@ -21,17 +21,20 @@ public class EditOdsInstanceContextCommand : IEditOdsInstanceContextCommand public EditOdsInstanceContextCommand(IUsersContext context) { - _context = context; + _context = context ?? throw new ArgumentNullException(nameof(context)); } public OdsInstanceContext Execute(IEditOdsInstanceContextModel changedOdsInstanceContextData) { - var odsInstanceContext = _context.OdsInstanceContexts - .Include(oid => oid.OdsInstance) - .SingleOrDefault(v => v.OdsInstanceContextId == changedOdsInstanceContextData.Id) ?? - throw new NotFoundException("odsInstanceContext", changedOdsInstanceContextData.Id); - var odsInstance = _context.OdsInstances.SingleOrDefault(v => v.OdsInstanceId == changedOdsInstanceContextData.OdsInstanceId) ?? - throw new NotFoundException("odsInstance", changedOdsInstanceContextData.OdsInstanceId); + var odsInstanceContext = + _context + .OdsInstanceContexts.Include(oid => oid.OdsInstance) + .SingleOrDefault(v => v.OdsInstanceContextId == changedOdsInstanceContextData.Id) + ?? throw new NotFoundException("odsInstanceContext", changedOdsInstanceContextData.Id); + var odsInstance = + _context.OdsInstances.SingleOrDefault(v => + v.OdsInstanceId == changedOdsInstanceContextData.OdsInstanceId + ) ?? throw new NotFoundException("odsInstance", changedOdsInstanceContextData.OdsInstanceId); odsInstanceContext.ContextKey = changedOdsInstanceContextData.ContextKey; odsInstanceContext.OdsInstance = odsInstance; @@ -44,8 +47,8 @@ public OdsInstanceContext Execute(IEditOdsInstanceContextModel changedOdsInstanc public interface IEditOdsInstanceContextModel { - public int Id { get; set; } - public int OdsInstanceId { get; set; } - public string? ContextKey { get; set; } - public string? ContextValue { get; set; } + int Id { get; set; } + int OdsInstanceId { get; set; } + string? ContextKey { get; set; } + string? ContextValue { get; set; } }