using Bit.Api.Dirt.Controllers; using Bit.Api.Dirt.Models.Response; using Bit.Core.Context; using Bit.Core.Dirt.Entities; using Bit.Core.Dirt.Models.Data; using Bit.Core.Dirt.Reports.ReportFeatures.Interfaces; using Bit.Core.Dirt.Reports.ReportFeatures.Requests; using Bit.Core.Exceptions; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Mvc; using NSubstitute; using Xunit; namespace Bit.Api.Test.Dirt; [ControllerCustomize(typeof(OrganizationReportsController))] [SutProviderCustomize] public class OrganizationReportControllerTests { #region Whole OrganizationReport Endpoints [Theory, BitAutoData] public async Task GetLatestOrganizationReportAsync_WithValidOrgId_ReturnsOkResult( SutProvider sutProvider, Guid orgId, OrganizationReport expectedReport) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetLatestOrganizationReportAsync(orgId) .Returns(expectedReport); // Act var result = await sutProvider.Sut.GetLatestOrganizationReportAsync(orgId); // Assert var okResult = Assert.IsType(result); var expectedResponse = new OrganizationReportResponseModel(expectedReport); Assert.Equivalent(expectedResponse, okResult.Value); } [Theory, BitAutoData] public async Task GetLatestOrganizationReportAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(Task.FromResult(false)); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.GetLatestOrganizationReportAsync(orgId)); // Verify that the query was not called await sutProvider.GetDependency() .DidNotReceive() .GetLatestOrganizationReportAsync(Arg.Any()); } [Theory, BitAutoData] public async Task GetLatestOrganizationReportAsync_WhenNoReportFound_ReturnsOkWithNull( SutProvider sutProvider, Guid orgId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetLatestOrganizationReportAsync(orgId) .Returns((OrganizationReport)null); // Act var result = await sutProvider.Sut.GetLatestOrganizationReportAsync(orgId); // Assert var okResult = Assert.IsType(result); Assert.Null(okResult.Value); } [Theory, BitAutoData] public async Task GetLatestOrganizationReportAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, OrganizationReport expectedReport) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetLatestOrganizationReportAsync(orgId) .Returns(expectedReport); // Act await sutProvider.Sut.GetLatestOrganizationReportAsync(orgId); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .GetLatestOrganizationReportAsync(orgId); } [Theory, BitAutoData] public async Task GetOrganizationReportAsync_WithValidIds_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReport expectedReport) { // Arrange expectedReport.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportAsync(reportId) .Returns(expectedReport); // Act var result = await sutProvider.Sut.GetOrganizationReportAsync(orgId, reportId); // Assert var okResult = Assert.IsType(result); Assert.Equal(expectedReport, okResult.Value); } [Theory, BitAutoData] public async Task GetOrganizationReportAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(Task.FromResult(false)); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportAsync(orgId, reportId)); // Verify that the query was not called await sutProvider.GetDependency() .DidNotReceive() .GetOrganizationReportAsync(Arg.Any()); } [Theory, BitAutoData] public async Task GetOrganizationReportAsync_WhenReportNotFound_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportAsync(reportId) .Returns((OrganizationReport)null); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportAsync(orgId, reportId)); Assert.Equal("Report not found for the specified organization.", exception.Message); } [Theory, BitAutoData] public async Task GetOrganizationReportAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReport expectedReport) { // Arrange expectedReport.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportAsync(reportId) .Returns(expectedReport); // Act await sutProvider.Sut.GetOrganizationReportAsync(orgId, reportId); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .GetOrganizationReportAsync(reportId); } [Theory, BitAutoData] public async Task GetOrganizationReportAsync_WithValidAccess_UsesCorrectReportId( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReport expectedReport) { // Arrange expectedReport.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportAsync(reportId) .Returns(expectedReport); // Act await sutProvider.Sut.GetOrganizationReportAsync(orgId, reportId); // Assert await sutProvider.GetDependency() .Received(1) .GetOrganizationReportAsync(reportId); } [Theory, BitAutoData] public async Task CreateOrganizationReportAsync_WithValidRequest_ReturnsOkResult( SutProvider sutProvider, Guid orgId, AddOrganizationReportRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .AddOrganizationReportAsync(request) .Returns(expectedReport); // Act var result = await sutProvider.Sut.CreateOrganizationReportAsync(orgId, request); // Assert var okResult = Assert.IsType(result); var expectedResponse = new OrganizationReportResponseModel(expectedReport); Assert.Equivalent(expectedResponse, okResult.Value); } [Theory, BitAutoData] public async Task CreateOrganizationReportAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, AddOrganizationReportRequest request) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.CreateOrganizationReportAsync(orgId, request)); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .AddOrganizationReportAsync(Arg.Any()); } [Theory, BitAutoData] public async Task CreateOrganizationReportAsync_WithMismatchedOrgId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, AddOrganizationReportRequest request) { // Arrange request.OrganizationId = Guid.NewGuid(); // Different from orgId sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.CreateOrganizationReportAsync(orgId, request)); Assert.Equal("Organization ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .AddOrganizationReportAsync(Arg.Any()); } [Theory, BitAutoData] public async Task CreateOrganizationReportAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, AddOrganizationReportRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .AddOrganizationReportAsync(request) .Returns(expectedReport); // Act await sutProvider.Sut.CreateOrganizationReportAsync(orgId, request); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .AddOrganizationReportAsync(request); } [Theory, BitAutoData] public async Task UpdateOrganizationReportAsync_WithValidRequest_ReturnsOkResult( SutProvider sutProvider, Guid orgId, UpdateOrganizationReportRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportAsync(request) .Returns(expectedReport); // Act var result = await sutProvider.Sut.UpdateOrganizationReportAsync(orgId, request); // Assert var okResult = Assert.IsType(result); var expectedResponse = new OrganizationReportResponseModel(expectedReport); Assert.Equivalent(expectedResponse, okResult.Value); } [Theory, BitAutoData] public async Task UpdateOrganizationReportAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, UpdateOrganizationReportRequest request) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportAsync(orgId, request)); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportAsync_WithMismatchedOrgId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, UpdateOrganizationReportRequest request) { // Arrange request.OrganizationId = Guid.NewGuid(); // Different from orgId sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportAsync(orgId, request)); Assert.Equal("Organization ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, UpdateOrganizationReportRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportAsync(request) .Returns(expectedReport); // Act await sutProvider.Sut.UpdateOrganizationReportAsync(orgId, request); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .UpdateOrganizationReportAsync(request); } #endregion #region SummaryData Field Endpoints [Theory, BitAutoData] public async Task GetOrganizationReportSummaryDataByDateRangeAsync_WithValidParameters_ReturnsOkResult( SutProvider sutProvider, Guid orgId, DateTime startDate, DateTime endDate, List expectedSummaryData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportSummaryDataByDateRangeAsync(orgId, startDate, endDate) .Returns(expectedSummaryData); // Act var result = await sutProvider.Sut.GetOrganizationReportSummaryDataByDateRangeAsync(orgId, startDate, endDate); // Assert var okResult = Assert.IsType(result); Assert.Equal(expectedSummaryData, okResult.Value); } [Theory, BitAutoData] public async Task GetOrganizationReportSummaryDataByDateRangeAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, DateTime startDate, DateTime endDate) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportSummaryDataByDateRangeAsync(orgId, startDate, endDate)); // Verify that the query was not called await sutProvider.GetDependency() .DidNotReceive() .GetOrganizationReportSummaryDataByDateRangeAsync(Arg.Any(), Arg.Any(), Arg.Any()); } [Theory, BitAutoData] public async Task GetOrganizationReportSummaryDataByDateRangeAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, DateTime startDate, DateTime endDate, List expectedSummaryData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportSummaryDataByDateRangeAsync(orgId, startDate, endDate) .Returns(expectedSummaryData); // Act await sutProvider.Sut.GetOrganizationReportSummaryDataByDateRangeAsync(orgId, startDate, endDate); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .GetOrganizationReportSummaryDataByDateRangeAsync(orgId, startDate, endDate); } [Theory, BitAutoData] public async Task GetOrganizationReportSummaryAsync_WithValidIds_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReportSummaryDataResponse expectedSummaryData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportSummaryDataAsync(orgId, reportId) .Returns(expectedSummaryData); // Act var result = await sutProvider.Sut.GetOrganizationReportSummaryAsync(orgId, reportId); // Assert var okResult = Assert.IsType(result); Assert.Equal(expectedSummaryData, okResult.Value); } [Theory, BitAutoData] public async Task GetOrganizationReportSummaryAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportSummaryAsync(orgId, reportId)); // Verify that the query was not called await sutProvider.GetDependency() .DidNotReceive() .GetOrganizationReportSummaryDataAsync(Arg.Any(), Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportSummaryAsync_WithValidRequest_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportSummaryRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; request.ReportId = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportSummaryAsync(request) .Returns(expectedReport); // Act var result = await sutProvider.Sut.UpdateOrganizationReportSummaryAsync(orgId, reportId, request); // Assert var okResult = Assert.IsType(result); var expectedResponse = new OrganizationReportResponseModel(expectedReport); Assert.Equivalent(expectedResponse, okResult.Value); } [Theory, BitAutoData] public async Task UpdateOrganizationReportSummaryAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportSummaryRequest request) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportSummaryAsync(orgId, reportId, request)); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportSummaryAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportSummaryAsync_WithMismatchedOrgId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportSummaryRequest request) { // Arrange request.OrganizationId = Guid.NewGuid(); // Different from orgId request.ReportId = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportSummaryAsync(orgId, reportId, request)); Assert.Equal("Organization ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportSummaryAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportSummaryAsync_WithMismatchedReportId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportSummaryRequest request) { // Arrange request.OrganizationId = orgId; request.ReportId = Guid.NewGuid(); // Different from reportId sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportSummaryAsync(orgId, reportId, request)); Assert.Equal("Report ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportSummaryAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportSummaryAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportSummaryRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; request.ReportId = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportSummaryAsync(request) .Returns(expectedReport); // Act await sutProvider.Sut.UpdateOrganizationReportSummaryAsync(orgId, reportId, request); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .UpdateOrganizationReportSummaryAsync(request); } #endregion #region ReportData Field Endpoints [Theory, BitAutoData] public async Task GetOrganizationReportDataAsync_WithValidIds_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReportDataResponse expectedReportData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportDataAsync(orgId, reportId) .Returns(expectedReportData); // Act var result = await sutProvider.Sut.GetOrganizationReportDataAsync(orgId, reportId); // Assert var okResult = Assert.IsType(result); Assert.Equal(expectedReportData, okResult.Value); } [Theory, BitAutoData] public async Task GetOrganizationReportDataAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportDataAsync(orgId, reportId)); // Verify that the query was not called await sutProvider.GetDependency() .DidNotReceive() .GetOrganizationReportDataAsync(Arg.Any(), Arg.Any()); } [Theory, BitAutoData] public async Task GetOrganizationReportDataAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReportDataResponse expectedReportData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportDataAsync(orgId, reportId) .Returns(expectedReportData); // Act await sutProvider.Sut.GetOrganizationReportDataAsync(orgId, reportId); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .GetOrganizationReportDataAsync(orgId, reportId); } [Theory, BitAutoData] public async Task UpdateOrganizationReportDataAsync_WithValidRequest_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportDataRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; request.ReportId = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportDataAsync(request) .Returns(expectedReport); // Act var result = await sutProvider.Sut.UpdateOrganizationReportDataAsync(orgId, reportId, request); // Assert var okResult = Assert.IsType(result); var expectedResponse = new OrganizationReportResponseModel(expectedReport); Assert.Equivalent(expectedResponse, okResult.Value); } [Theory, BitAutoData] public async Task UpdateOrganizationReportDataAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportDataRequest request) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportDataAsync(orgId, reportId, request)); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportDataAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportDataAsync_WithMismatchedOrgId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportDataRequest request) { // Arrange request.OrganizationId = Guid.NewGuid(); // Different from orgId request.ReportId = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportDataAsync(orgId, reportId, request)); Assert.Equal("Organization ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportDataAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportDataAsync_WithMismatchedReportId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportDataRequest request) { // Arrange request.OrganizationId = orgId; request.ReportId = Guid.NewGuid(); // Different from reportId sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportDataAsync(orgId, reportId, request)); Assert.Equal("Report ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportDataAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportDataAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportDataRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; request.ReportId = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportDataAsync(request) .Returns(expectedReport); // Act await sutProvider.Sut.UpdateOrganizationReportDataAsync(orgId, reportId, request); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .UpdateOrganizationReportDataAsync(request); } #endregion #region ApplicationData Field Endpoints [Theory, BitAutoData] public async Task GetOrganizationReportApplicationDataAsync_WithValidIds_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReportApplicationDataResponse expectedApplicationData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportApplicationDataAsync(orgId, reportId) .Returns(expectedApplicationData); // Act var result = await sutProvider.Sut.GetOrganizationReportApplicationDataAsync(orgId, reportId); // Assert var okResult = Assert.IsType(result); Assert.Equal(expectedApplicationData, okResult.Value); } [Theory, BitAutoData] public async Task GetOrganizationReportApplicationDataAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportApplicationDataAsync(orgId, reportId)); // Verify that the query was not called await sutProvider.GetDependency() .DidNotReceive() .GetOrganizationReportApplicationDataAsync(Arg.Any(), Arg.Any()); } [Theory, BitAutoData] public async Task GetOrganizationReportApplicationDataAsync_WhenApplicationDataNotFound_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportApplicationDataAsync(orgId, reportId) .Returns((OrganizationReportApplicationDataResponse)null); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.GetOrganizationReportApplicationDataAsync(orgId, reportId)); Assert.Equal("Organization report application data not found.", exception.Message); } [Theory, BitAutoData] public async Task GetOrganizationReportApplicationDataAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, Guid reportId, OrganizationReportApplicationDataResponse expectedApplicationData) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .GetOrganizationReportApplicationDataAsync(orgId, reportId) .Returns(expectedApplicationData); // Act await sutProvider.Sut.GetOrganizationReportApplicationDataAsync(orgId, reportId); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .GetOrganizationReportApplicationDataAsync(orgId, reportId); } [Theory, BitAutoData] public async Task UpdateOrganizationReportApplicationDataAsync_WithValidRequest_ReturnsOkResult( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportApplicationDataRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; request.Id = reportId; expectedReport.Id = request.Id; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportApplicationDataAsync(request) .Returns(expectedReport); // Act var result = await sutProvider.Sut.UpdateOrganizationReportApplicationDataAsync(orgId, reportId, request); // Assert var okResult = Assert.IsType(result); var expectedResponse = new OrganizationReportResponseModel(expectedReport); Assert.Equivalent(expectedResponse, okResult.Value); } [Theory, BitAutoData] public async Task UpdateOrganizationReportApplicationDataAsync_WithoutAccess_ThrowsNotFoundException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportApplicationDataRequest request) { // Arrange sutProvider.GetDependency() .AccessReports(orgId) .Returns(false); // Act & Assert await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportApplicationDataAsync(orgId, reportId, request)); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportApplicationDataAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportApplicationDataAsync_WithMismatchedOrgId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportApplicationDataRequest request) { // Arrange request.OrganizationId = Guid.NewGuid(); // Different from orgId sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportApplicationDataAsync(orgId, reportId, request)); Assert.Equal("Organization ID in the request body must match the route parameter", exception.Message); // Verify that the command was not called await sutProvider.GetDependency() .DidNotReceive() .UpdateOrganizationReportApplicationDataAsync(Arg.Any()); } [Theory, BitAutoData] public async Task UpdateOrganizationReportApplicationDataAsync_WithMismatchedReportId_ThrowsBadRequestException( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportApplicationDataRequest request, OrganizationReport updatedReport) { // Arrange request.OrganizationId = orgId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportApplicationDataAsync(request) .Returns(updatedReport); // Act & Assert var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateOrganizationReportApplicationDataAsync(orgId, reportId, request)); Assert.Equal("Report ID in the request body must match the route parameter", exception.Message); } [Theory, BitAutoData] public async Task UpdateOrganizationReportApplicationDataAsync_CallsCorrectMethods( SutProvider sutProvider, Guid orgId, Guid reportId, UpdateOrganizationReportApplicationDataRequest request, OrganizationReport expectedReport) { // Arrange request.OrganizationId = orgId; request.Id = reportId; expectedReport.Id = reportId; sutProvider.GetDependency() .AccessReports(orgId) .Returns(true); sutProvider.GetDependency() .UpdateOrganizationReportApplicationDataAsync(request) .Returns(expectedReport); // Act await sutProvider.Sut.UpdateOrganizationReportApplicationDataAsync(orgId, reportId, request); // Assert await sutProvider.GetDependency() .Received(1) .AccessReports(orgId); await sutProvider.GetDependency() .Received(1) .UpdateOrganizationReportApplicationDataAsync(request); } #endregion }