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 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 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 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));
            });
        }
        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));
            });
        }