public async Task FindVenue_RefProvidedAndMatches_ReturnsVenueId() { // Arrange var blobServiceClient = new Mock <BlobServiceClient>(); blobServiceClient.Setup(mock => mock.GetBlobContainerClient(It.IsAny <string>())).Returns(Mock.Of <BlobContainerClient>()); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, blobServiceClient.Object, Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var venue = await TestData.CreateVenue(providerId : provider.ProviderId, createdBy : user, venueName : "My Venue", providerVenueRef : "VENUE1"); var row = new CsvCourseRow() { DeliveryMode = "classroom based", ProviderVenueRef = "venue1" }; var rowInfo = new CourseDataUploadRowInfo(row, rowNumber: 2, courseId: Guid.NewGuid()); // Act var result = fileUploadProcessor.FindVenue(rowInfo, new[] { venue }); // Assert Assert.Equal(venue.VenueId, result?.VenueId); }
[InlineData(1)] // Less than valid row //[InlineData(99] // More than valid row - we don't have a way of checking this currently public async Task FileMatchesSchema_RowHasIncorrectColumnCount_ReturnsInvalidRows(int columnCount) { // Arrange var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var stream = DataManagementFileHelper.CreateVenueUploadCsvStream(csvWriter => { for (int i = 0; i < columnCount; i++) { csvWriter.WriteField("value"); } csvWriter.NextRecord(); }); // Act var(result, missingHeaders) = await fileUploadProcessor.FileMatchesSchema <CsvVenueRow>(stream); // Assert result.Should().Be(FileMatchesSchemaResult.InvalidRows); }
public async Task FileMatchesSchema_HeaderHasMissingColumn_ReturnsInvalidHeaderResult() { // Arrange var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var stream = DataManagementFileHelper.CreateCsvStream(csvWriter => { // Miss out VENUE_NAME, POSTCODE csvWriter.WriteField("YOUR_VENUE_REFERENCE"); csvWriter.WriteField("ADDRESS_LINE_1"); csvWriter.WriteField("ADDRESS_LINE_2"); csvWriter.WriteField("TOWN_OR_CITY"); csvWriter.WriteField("COUNTY"); csvWriter.WriteField("EMAIL"); csvWriter.WriteField("PHONE"); csvWriter.WriteField("WEBSITE"); csvWriter.NextRecord(); }); // Act var(result, missingHeaders) = await fileUploadProcessor.FileMatchesSchema <CsvVenueRow>(stream); // Assert result.Should().Be(FileMatchesSchemaResult.InvalidHeader); missingHeaders.Should().BeEquivalentTo(new[] { "VENUE_NAME", "POSTCODE" }); }
public async Task PublishCourseUpload_StatusIsProcessedWithErrors_ReturnsUploadHasErrors() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); await TestData.CreateCourseUpload( provider.ProviderId, createdBy : user, UploadStatus.ProcessedWithErrors); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); // Act var result = await fileUploadProcessor.PublishCourseUploadForProvider(provider.ProviderId, user); // Assert result.Status.Should().Be(PublishResultStatus.UploadHasErrors); }
public async Task PublishVenueUpload_RevalidationAddsSupplementaryRows_PublishesSuccessfully() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, venueUploadRows) = await TestData.CreateVenueUpload( provider.ProviderId, createdBy : user, UploadStatus.ProcessedSuccessfully, rowBuilder => { rowBuilder.AddRow(record => { record.VenueName = "Venue1"; record.ProviderVenueRef = "VENUE1"; }); }); // Ensure we have a record in the Postcodes table for extracting lat/lng var postcodePosition = (Latitude : 1d, Longitude : 2d); foreach (var postcode in venueUploadRows.Select(r => r.Postcode).Distinct()) { await TestData.CreatePostcodeInfo(postcode, postcodePosition.Latitude, postcodePosition.Longitude); } // Add a new venue for the provider and link a T-Level to it (so the venue cannot be removed by the publish). // Revalidation should kick in and add a supplementary row (without any validation errors). Clock.UtcNow += TimeSpan.FromDays(1); var oldVenue2 = await TestData.CreateVenue(provider.ProviderId, createdBy : user, venueName : "Venue2", providerVenueRef : "VENUE2"); var tLevelDefinitions = await TestData.CreateInitialTLevelDefinitions(); await TestData.CreateTLevel( provider.ProviderId, tLevelDefinitions.First().TLevelDefinitionId, new[] { oldVenue2.VenueId }, createdBy : user); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); // Act var result = await fileUploadProcessor.PublishVenueUploadForProvider(provider.ProviderId, user); // Assert result.Status.Should().Be(PublishResultStatus.Success); result.PublishedCount.Should().Be(2); }
public async Task PublishCourseUpload_StatusIsProcessedWithErrorsAfterRevalidation_ReturnsUploadHasErrors() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var venue = await TestData.CreateVenue(provider.ProviderId, createdBy : user, venueName : "My Venue", providerVenueRef : "VENUE1"); var learnAimRef = (await TestData.CreateLearningDelivery()).LearnAimRef; var(courseUpload, _) = await TestData.CreateCourseUpload( provider.ProviderId, createdBy : user, UploadStatus.ProcessedSuccessfully, rowBuilder => { rowBuilder.AddRow(learnAimRef, record => { record.DeliveryMode = "classroom based"; record.ResolvedDeliveryMode = CourseDeliveryMode.ClassroomBased; record.ProviderVenueRef = venue.ProviderVenueRef; record.VenueId = venue.VenueId; }); }); // Delete the venue linked to the row in the upload, triggering revalidation // (which should fail since the venue has gone away) Clock.UtcNow += TimeSpan.FromDays(1); await WithSqlQueryDispatcher(dispatcher => dispatcher.ExecuteQuery(new DeleteVenue() { VenueId = venue.VenueId, DeletedBy = user, DeletedOn = Clock.UtcNow })); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); // Act var result = await fileUploadProcessor.PublishCourseUploadForProvider(provider.ProviderId, user); // Assert result.Status.Should().Be(PublishResultStatus.UploadHasErrors); }
public async Task GetCourseUploadRowsRequiringRevalidation_MatchedVenueUpdatedSinceRowLastValidated_ReturnsRow() { // Arrange var blobServiceClient = new Mock <BlobServiceClient>(); blobServiceClient.Setup(mock => mock.GetBlobContainerClient(It.IsAny <string>())).Returns(Mock.Of <BlobContainerClient>()); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, blobServiceClient.Object, Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var learnAimRef = (await TestData.CreateLearningDelivery()).LearnAimRef; var venue = await TestData.CreateVenue(provider.ProviderId, createdBy : user, venueName : "My Venue", providerVenueRef : "REF"); var(courseUpload, rows) = await TestData.CreateCourseUpload( provider.ProviderId, user, UploadStatus.ProcessedWithErrors, configureRows : rowBuilder => { rowBuilder.AddRow(learnAimRef, record => { record.DeliveryMode = "classroom based"; record.ResolvedDeliveryMode = CourseDeliveryMode.ClassroomBased; record.ProviderVenueRef = venue.ProviderVenueRef; record.VenueId = venue.VenueId; }); }); Clock.UtcNow += TimeSpan.FromHours(1); await TestData.UpdateVenue(venue.VenueId, updatedBy : user); // Act var result = await WithSqlQueryDispatcher( dispatcher => fileUploadProcessor.GetCourseUploadRowsRequiringRevalidation(dispatcher, courseUpload)); // Assert Assert.Collection( result, row => Assert.Equal(rows[0].CourseRunId, row.CourseRunId)); }
public async Task ProcessCourseFile_RowHasErrors_SetStatusToProcessedWithErrors() { // Arrange var blobServiceClient = new Mock <BlobServiceClient>(); blobServiceClient.Setup(mock => mock.GetBlobContainerClient(It.IsAny <string>())).Returns(Mock.Of <BlobContainerClient>()); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, blobServiceClient.Object, Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var learnAimRef = (await TestData.CreateLearningDelivery()).LearnAimRef; var(courseUpload, _) = await TestData.CreateCourseUpload(provider.ProviderId, user, UploadStatus.Created); var stream = DataManagementFileHelper.CreateCourseUploadCsvStream( // Empty record will always yield errors (but we will always have a valid LARS code at this point) new CsvCourseRow() { LearnAimRef = learnAimRef }); // Act await fileUploadProcessor.ProcessCourseFile(courseUpload.CourseUploadId, stream); // Assert courseUpload = await WithSqlQueryDispatcher( dispatcher => dispatcher.ExecuteQuery(new GetCourseUpload() { CourseUploadId = courseUpload.CourseUploadId })); using (new AssertionScope()) { courseUpload.UploadStatus.Should().Be(UploadStatus.ProcessedWithErrors); courseUpload.ProcessingCompletedOn.Should().Be(Clock.UtcNow); courseUpload.ProcessingStartedOn.Should().NotBeNull(); } }
public async Task ProcessVenueFile_AllRecordsValid_SetStatusToProcessedSuccessfully() { // Arrange var blobServiceClient = new Mock <BlobServiceClient>(); blobServiceClient.Setup(mock => mock.GetBlobContainerClient(It.IsAny <string>())).Returns(Mock.Of <BlobContainerClient>()); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, blobServiceClient.Object, Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, user, UploadStatus.Created); var uploadRows = DataManagementFileHelper.CreateVenueUploadRows(rowCount: 3).ToArray(); await WithSqlQueryDispatcher(dispatcher => AddPostcodeInfoForRows(dispatcher, uploadRows.ToDataUploadRowCollection())); var stream = DataManagementFileHelper.CreateVenueUploadCsvStream(uploadRows); // Act await fileUploadProcessor.ProcessVenueFile(venueUpload.VenueUploadId, stream); // Assert venueUpload = await WithSqlQueryDispatcher( dispatcher => dispatcher.ExecuteQuery(new GetVenueUpload() { VenueUploadId = venueUpload.VenueUploadId })); using (new AssertionScope()) { venueUpload.UploadStatus.Should().Be(UploadStatus.ProcessedSuccessfully); venueUpload.LastValidated.Should().Be(Clock.UtcNow); venueUpload.ProcessingCompletedOn.Should().Be(Clock.UtcNow); venueUpload.ProcessingStartedOn.Should().NotBeNull(); } }
public async Task ValidateVenueUploadFile_RowsHasErrors_InsertsExpectedErrorCodesIntoDb( CsvVenueRow row, IEnumerable <string> expectedErrorCodes, IEnumerable <CsvVenueRow> additionalRows) { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, createdBy : user, UploadStatus.Processing); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var uploadRows = new[] { row }.Concat(additionalRows ?? Enumerable.Empty <CsvVenueRow>()).ToDataUploadRowCollection(); await WithSqlQueryDispatcher(async dispatcher => { // Add a row into Postcodes table to ensure we don't have errors due to it missing // (ValidateVenueUploadFile_PostcodeIsNotInDb_InsertsExpectedErrorCodesIntoDb tests that scenario) await AddPostcodeInfoForRows(dispatcher, uploadRows); // Act await fileUploadProcessor.ValidateVenueUploadFile( dispatcher, venueUpload.VenueUploadId, venueUpload.ProviderId, uploadRows); var(rows, _) = await dispatcher.ExecuteQuery(new GetVenueUploadRows() { VenueUploadId = venueUpload.VenueUploadId }); rows.First().IsValid.Should().BeFalse(); rows.First().Errors.Should().BeEquivalentTo(expectedErrorCodes); }); }
public async Task ProcessVenueFile_RowHasErrors_SetStatusToProcessedWithErrors() { // Arrange var blobServiceClient = new Mock <BlobServiceClient>(); blobServiceClient.Setup(mock => mock.GetBlobContainerClient(It.IsAny <string>())).Returns(Mock.Of <BlobContainerClient>()); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, blobServiceClient.Object, Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, user, UploadStatus.Created); var stream = DataManagementFileHelper.CreateVenueUploadCsvStream( // Empty record will always yield errors new CsvVenueRow()); // Act await fileUploadProcessor.ProcessVenueFile(venueUpload.VenueUploadId, stream); // Assert venueUpload = await WithSqlQueryDispatcher( dispatcher => dispatcher.ExecuteQuery(new GetVenueUpload() { VenueUploadId = venueUpload.VenueUploadId })); using (new AssertionScope()) { venueUpload.UploadStatus.Should().Be(UploadStatus.ProcessedWithErrors); venueUpload.LastValidated.Should().Be(Clock.UtcNow); venueUpload.ProcessingCompletedOn.Should().Be(Clock.UtcNow); venueUpload.ProcessingStartedOn.Should().NotBeNull(); } }
public async Task LooksLikeCsv_ReturnsExpectedResult(byte[] content, bool expectedResult) { // Arrange var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var stream = new MemoryStream(content); stream.Seek(0L, SeekOrigin.Begin); // Act var result = await fileUploadProcessor.LooksLikeCsv(stream); // Assert result.Should().Be(expectedResult); }
public async Task ValidateVenueUploadFile_DoesNotNormalizeInvalidPostcode() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, createdBy : user, UploadStatus.Processing); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var row = new CsvVenueRow() { Postcode = "xxxx", }; var uploadRows = new[] { row }.ToDataUploadRowCollection(); await WithSqlQueryDispatcher(async dispatcher => { // Act await fileUploadProcessor.ValidateVenueUploadFile( dispatcher, venueUpload.VenueUploadId, venueUpload.ProviderId, uploadRows); var(rows, _) = await dispatcher.ExecuteQuery(new GetVenueUploadRows() { VenueUploadId = venueUpload.VenueUploadId }); rows.Count.Should().Be(1); rows.Last().Postcode.Should().Be(row.Postcode); }); }
public async Task ProcessCourseFile_LearnAimRefWithMissingLeadingZero_HasLeadingZeroAdded() { // Arrange var blobServiceClient = new Mock <BlobServiceClient>(); blobServiceClient.Setup(mock => mock.GetBlobContainerClient(It.IsAny <string>())).Returns(Mock.Of <BlobContainerClient>()); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, blobServiceClient.Object, Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(courseUpload, _) = await TestData.CreateCourseUpload(provider.ProviderId, user, UploadStatus.Created); var learningDelivery = await TestData.CreateLearningDelivery(learnAimRef : "01234567"); var uploadRows = DataManagementFileHelper.CreateCourseUploadRows(learningDelivery.LearnAimRef.TrimStart('0'), rowCount: 1).ToArray(); uploadRows[0].CourseName = string.Empty; var stream = DataManagementFileHelper.CreateCourseUploadCsvStream(uploadRows); // Act await fileUploadProcessor.ProcessCourseFile(courseUpload.CourseUploadId, stream); // Assert var rows = await WithSqlQueryDispatcher(async dispatcher => (await dispatcher.ExecuteQuery(new GetCourseUploadRows() { CourseUploadId = courseUpload.CourseUploadId, WithErrorsOnly = false })).Rows); rows.Single().LearnAimRef.Should().Be(learningDelivery.LearnAimRef); }
public async Task ValidateLearnAimRefs_ReturnsExpectedResult() { // Arrange var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); // Add missing lars var learnAimRef = (await TestData.CreateLearningDelivery()).LearnAimRef; List <CsvCourseRow> courseUploadRows = DataManagementFileHelper.CreateCourseUploadRows(learnAimRef, 1).ToList(); courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows("", 1).ToList()); courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows(learnAimRef, 1).ToList()); courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows(" ", 1).ToList()); // Add invalid and expired lars var expiredLearnAimRef = (await TestData.CreateLearningDelivery(effectiveTo: DateTime.Now.AddDays(-1))).LearnAimRef; var expiredOperationalEndDate = (await TestData.CreateLearningDelivery(operationalEndDate: DateTime.Now.AddDays(-1))).LearnAimRef; courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows("ABCDEFGH", 1).ToList()); courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows(expiredLearnAimRef, 1).ToList()); courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows("GHFEDCBA", 1).ToList()); courseUploadRows.AddRange(DataManagementFileHelper.CreateCourseUploadRows(expiredOperationalEndDate, 1).ToList()); var stream = DataManagementFileHelper.CreateCourseUploadCsvStream(courseUploadRows.ToArray()); // Act var(missing, invalid, expired) = await fileUploadProcessor.ValidateLearnAimRefs(stream); // Assert missing.Should().BeEquivalentTo(new[] { 3, 5 }); invalid.Should().BeEquivalentTo(new[]
public async Task ValidateCourseUploadRows_RowsHaveNoLarsCode_AreNotGrouped() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(courseUpload, _) = await TestData.CreateCourseUpload(provider.ProviderId, createdBy : user, null); var learnAimRef = (await TestData.CreateLearningDelivery()).LearnAimRef; var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var rows = DataManagementFileHelper.CreateCourseUploadRows(learnAimRef, rowCount: 2).ToArray(); rows[0].LearnAimRef = string.Empty; rows[1].LearnAimRef = string.Empty; var uploadRows = rows.ToDataUploadRowCollection(); await WithSqlQueryDispatcher(async dispatcher => { // Act var(_, rows) = await fileUploadProcessor.ValidateCourseUploadRows( dispatcher, courseUpload.CourseUploadId, provider.ProviderId, uploadRows); // Assert rows.First().CourseId.Should().NotBe(rows.Last().CourseId); }); }
public async Task ValidateVenueUploadFile_PostcodeIsNotInEngland_InsertsExpectedOutsideOfEnglandValueIntoDb() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, createdBy : user, UploadStatus.Processing); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var uploadRows = DataManagementFileHelper.CreateVenueUploadRows(rowCount: 1).ToDataUploadRowCollection(); await WithSqlQueryDispatcher(async dispatcher => { await AddPostcodeInfoForRows(dispatcher, uploadRows, inEngland: false); // Act await fileUploadProcessor.ValidateVenueUploadFile( dispatcher, venueUpload.VenueUploadId, venueUpload.ProviderId, uploadRows); var(rows, _) = await dispatcher.ExecuteQuery(new GetVenueUploadRows() { VenueUploadId = venueUpload.VenueUploadId }); rows.First().IsValid.Should().BeTrue(); rows.First().OutsideOfEngland.Should().BeTrue(); }); }
public async Task PublishVenueUpload_CanBePublished_UpsertsRowsArchivesUnmatchedVenuesAndSetsStatusToPublished() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var oldVenue1 = await TestData.CreateVenue(provider.ProviderId, createdBy : user, venueName : "Venue 1", providerVenueRef : "VENUE1"); var oldVenue2 = await TestData.CreateVenue(provider.ProviderId, createdBy : user, venueName : "Venue 2"); var(venueUpload, venueUploadRows) = await TestData.CreateVenueUpload( provider.ProviderId, createdBy : user, UploadStatus.ProcessedSuccessfully, rowBuilder => { // Add two rows; one matching `oldVenue` and one that doesn't match an existing venue rowBuilder.AddRow(record => { record.VenueName = "Venue 1"; record.ProviderVenueRef = "VENUE1"; record.VenueId = oldVenue1.VenueId; }); rowBuilder.AddRow(record => record.VenueName = "New venue 1"); }); // Ensure we have a record in the Postcodes table for extracting lat/lng var postcodePosition = (Latitude : 1d, Longitude : 2d); foreach (var postcode in venueUploadRows.Select(r => r.Postcode).Distinct()) { await TestData.CreatePostcodeInfo(postcode, postcodePosition.Latitude, postcodePosition.Longitude); } var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); // Act var result = await fileUploadProcessor.PublishVenueUploadForProvider(provider.ProviderId, user); // Assert result.Status.Should().Be(PublishResultStatus.Success); result.PublishedCount.Should().Be(2); await WithSqlQueryDispatcher(async dispatcher => { venueUpload = await dispatcher.ExecuteQuery(new GetVenueUpload() { VenueUploadId = venueUpload.VenueUploadId }); venueUpload.UploadStatus.Should().Be(UploadStatus.Published); venueUpload.PublishedOn.Should().Be(Clock.UtcNow); var providerVenues = await dispatcher.ExecuteQuery(new GetVenuesByProvider() { ProviderId = provider.ProviderId }); providerVenues.Should().BeEquivalentTo(new[] { new Venue() { VenueId = oldVenue1.VenueId, VenueName = venueUploadRows[0].VenueName, ProviderId = provider.ProviderId, ProviderUkprn = provider.Ukprn, ProviderVenueRef = venueUploadRows[0].ProviderVenueRef, AddressLine1 = venueUploadRows[0].AddressLine1, AddressLine2 = venueUploadRows[0].AddressLine2, Town = venueUploadRows[0].Town, County = venueUploadRows[0].County, Postcode = venueUploadRows[0].Postcode, Latitude = postcodePosition.Latitude, Longitude = postcodePosition.Longitude, Email = venueUploadRows[0].Email, Telephone = venueUploadRows[0].Telephone, Website = venueUploadRows[0].Website }, new Venue() { VenueId = venueUploadRows[1].VenueId, VenueName = venueUploadRows[1].VenueName, ProviderId = provider.ProviderId, ProviderUkprn = provider.Ukprn, ProviderVenueRef = venueUploadRows[1].ProviderVenueRef, AddressLine1 = venueUploadRows[1].AddressLine1, AddressLine2 = venueUploadRows[1].AddressLine2, Town = venueUploadRows[1].Town, County = venueUploadRows[1].County, Postcode = venueUploadRows[1].Postcode, Latitude = postcodePosition.Latitude, Longitude = postcodePosition.Longitude, Email = venueUploadRows[1].Email, Telephone = venueUploadRows[1].Telephone, Website = venueUploadRows[1].Website }, }); }); }
public async Task ValidateVenueUploadFile_InsertsRowsIntoDb() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, createdBy : user, UploadStatus.Processing); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var row = new CsvVenueRow() { ProviderVenueRef = "REF", VenueName = "Place", AddressLine1 = "Line 1", AddressLine2 = "Line 2", Town = "Town", County = "County", Postcode = "AB1 2DE", Email = "*****@*****.**", Telephone = "01234 567890", Website = "provider.com/place" }; var uploadRows = new[] { row }.ToDataUploadRowCollection(); await WithSqlQueryDispatcher(async dispatcher => { // Act await fileUploadProcessor.ValidateVenueUploadFile( dispatcher, venueUpload.VenueUploadId, venueUpload.ProviderId, uploadRows); var(rows, _) = await dispatcher.ExecuteQuery(new GetVenueUploadRows() { VenueUploadId = venueUpload.VenueUploadId }); rows.Count.Should().Be(1); rows.Last().Should().BeEquivalentTo(new VenueUploadRow() { RowNumber = 2, LastUpdated = Clock.UtcNow, LastValidated = Clock.UtcNow, IsSupplementary = false, IsDeletable = true, AddressLine1 = row.AddressLine1, AddressLine2 = row.AddressLine2, County = row.County, Email = row.Email, Postcode = row.Postcode, ProviderVenueRef = row.ProviderVenueRef, Telephone = row.Telephone, Town = row.Town, VenueName = row.VenueName, Website = row.Website }, config => config.Excluding(r => r.IsValid).Excluding(r => r.Errors).Excluding(r => r.VenueId)); }); }
public async Task ValidateVenueUploadFile_FileIsMissingVenuesWithLiveOfferings_AddsSupplementaryRowsToFile() { // Arrange var provider = await TestData.CreateProvider(); var user = await TestData.CreateUser(providerId : provider.ProviderId); var(venueUpload, _) = await TestData.CreateVenueUpload(provider.ProviderId, createdBy : user, UploadStatus.Processing); var venue = await TestData.CreateVenue(provider.ProviderId, createdBy : user, venueName : "Venue 1"); var tLevelDefinitions = await TestData.CreateInitialTLevelDefinitions(); await TestData.CreateTLevel( provider.ProviderId, tLevelDefinitions.First().TLevelDefinitionId, locationVenueIds : new[] { venue.VenueId }, createdBy : user); var fileUploadProcessor = new FileUploadProcessor( SqlQueryDispatcherFactory, Mock.Of <BlobServiceClient>(), Clock, new RegionCache(SqlQueryDispatcherFactory), new ExecuteImmediatelyBackgroundWorkScheduler(Fixture.ServiceScopeFactory)); var uploadRows = new[] { new CsvVenueRow() { VenueName = "Upload venue 1" } }.ToDataUploadRowCollection(); await WithSqlQueryDispatcher(async dispatcher => { // Act await fileUploadProcessor.ValidateVenueUploadFile( dispatcher, venueUpload.VenueUploadId, venueUpload.ProviderId, uploadRows); var(rows, _) = await dispatcher.ExecuteQuery(new GetVenueUploadRows() { VenueUploadId = venueUpload.VenueUploadId }); rows.Count.Should().Be(2); // One from upload, one retained rows.Last().Should().BeEquivalentTo(new VenueUploadRow() { RowNumber = 3, LastUpdated = Clock.UtcNow, LastValidated = Clock.UtcNow, IsSupplementary = true, VenueId = venue.VenueId, IsDeletable = false, AddressLine1 = venue.AddressLine1, AddressLine2 = venue.AddressLine2, County = venue.County, Email = venue.Email, Postcode = venue.Postcode, ProviderVenueRef = venue.ProviderVenueRef, Telephone = venue.Telephone, Town = venue.Town, VenueName = venue.VenueName, Website = venue.Website }, config => config.Excluding(r => r.IsValid).Excluding(r => r.Errors)); }); }