Exemple #1
0
        public AzureStorageBackedTests(ITestOutputHelper output)
        {
            _mockIALogger    = new Mock <ILogger <IInstalledAppManager> >();
            _mockStateLogger = new Mock <ILogger <IStateManager <string> > >();
            _mockIALogger.Setup(log => log.Log(It.IsAny <Microsoft.Extensions.Logging.LogLevel>(),
                                               It.IsAny <EventId>(),
                                               It.IsAny <object>(),
                                               null,
                                               It.IsAny <Func <object, Exception, string> >()))
            .Callback <Microsoft.Extensions.Logging.LogLevel,
                       EventId,
                       object,
                       Exception,
                       Func <object, Exception, string> >((logLevel, e, state, ex, f) =>
            {
                output.WriteLine($"{logLevel} logged: \"{state}\"");
            });
            _mockStateLogger.Setup(log => log.Log(It.IsAny <Microsoft.Extensions.Logging.LogLevel>(),
                                                  It.IsAny <EventId>(),
                                                  It.IsAny <object>(),
                                                  null,
                                                  It.IsAny <Func <object, Exception, string> >()))
            .Callback <Microsoft.Extensions.Logging.LogLevel,
                       EventId,
                       object,
                       Exception,
                       Func <object, Exception, string> >((logLevel, e, state, ex, f) =>
            {
                output.WriteLine($"{logLevel} logged: \"{state}\"");
            });

            _mockSmartThingsAPIHelper = new Mock <ISmartThingsAPIHelper>();
            _mockSmartThingsAPIHelper.Setup(api => api.RefreshTokensAsync(It.IsAny <InstalledAppInstance>()))
            .Returns(() =>
            {
                return(Task.FromResult <InstalledAppInstance>(CommonUtils.GetValidInstalledAppInstance()));
            });

            var iaBlobStream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(CommonUtils.GetIACache())));

            iaBlobStream.Seek(0, SeekOrigin.Begin);

            var iaBlobStreamInfo = BlobsModelFactory.BlobDownloadInfo(DateTimeOffset.Now,
                                                                      0,
                                                                      BlobType.Block,
                                                                      null,
                                                                      null,
                                                                      null,
                                                                      null,
                                                                      null,
                                                                      null,
                                                                      CopyStatus.Success,
                                                                      null,
                                                                      LeaseDurationType.Infinite,
                                                                      null,
                                                                      LeaseState.Available,
                                                                      null,
                                                                      LeaseStatus.Unlocked,
                                                                      null,
                                                                      null,
        private static AutoSubstituteBuilder ConfigureServiceClient(string plateFile, int level, int x, int y, string expectedContainerName = null, string blobFormat = null)
        {
            // For all the non dss plate files
            var blobName      = $"{plateFile.Replace(".plate", string.Empty)}/L{level}X{x}Y{y}.png";
            var containerName = AzurePlateTilePyramidOptions.DefaultContainer;

            if (plateFile == "dssterrapixel.plate")
            {
                blobName      = $"DSSTerraPixelL{level}X{x}Y{y}.png";
                containerName = "dss";
            }

            return(AutoSubstitute.Configure()
                   .InjectProperties()
                   .MakeUnregisteredTypesPerLifetime()
                   .SubstituteFor <Response <BlobDownloadInfo> >()
                   .SubstituteFor <DownloadResult>()
                   .Provide(ctx => BlobsModelFactory.BlobDownloadInfo(content: ctx.Resolve <DownloadResult>()))
                   .SubstituteFor <BlobClient>()
                   .ResolveReturnValue(c => c.Download())
                   .SubstituteFor <BlobContainerClient>()
                   .ResolveReturnValue(t => t.GetBlobClient(blobName))
                   .ConfigureSubstitute(c =>
            {
                c.Configure()
                .CreateIfNotExists().Returns(Substitute.For <Response <BlobContainerInfo> >());
            })
                   .SubstituteFor <BlobServiceClient>()
                   .ResolveReturnValue(service => service.GetBlobContainerClient(containerName)));
        }
        private static AutoSubstituteBuilder ConfigureServiceClient(string plateFile, int level, int x, int y, string expectedContainerName = null, string blobFormat = null)
        {
            blobFormat ??= "L{0}X{1}Y{2}.png";
            var blobName      = string.Format(blobFormat, level, x, y);
            var containerName = expectedContainerName ?? plateFile.Replace(".plate", string.Empty);

            return(AutoSubstitute.Configure()
                   .SubstituteFor2 <DownloadResult>().Provide(out var result).Configured()
                   .SubstituteFor2 <BlobClient>().Provide(out var blob).Configure(b =>
            {
                var response = Substitute.ForPartsOf <Response <BlobDownloadInfo> >();
                response.Value.Returns(BlobsModelFactory.BlobDownloadInfo(content: result.Value));

                b.Configure()
                .Download().Returns(response);

                b.WhenForAnyArgs(b => b.Upload(Arg.Any <Stream>(), Arg.Any <bool>(), Arg.Any <CancellationToken>()))
                .DoNotCallBase();
            })
                   .SubstituteFor2 <BlobContainerClient>().Provide(out var container).Configure(c =>
            {
                c.Configure()
                .GetBlobClient(blobName).Returns(blob.Value);

                c.Configure()
                .CreateIfNotExists().Returns(Substitute.For <Response <BlobContainerInfo> >());
            })
                   .SubstituteFor2 <BlobServiceClient>().Provide(out var service).Configure(service =>
            {
                service.Configure()
                .GetBlobContainerClient(containerName).Returns(container.Value);
            }));
        }
        private static Func <Response <BlobDownloadInfo> > ReturnBlob(string blobContent) => () =>
        {
            var response = new Mock <Response <BlobDownloadInfo> >();

            response.SetupGet(s => s.Value)
            .Returns(BlobsModelFactory.BlobDownloadInfo(content: new MemoryStream(Encoding.UTF8.GetBytes(blobContent))));

            return(response.Object);
        };
Exemple #5
0
        private BlobDownloadInfo GetMockBlob()
        {
            byte[]       firstString = Encoding.UTF8.GetBytes("doc");
            MemoryStream str         = new MemoryStream(firstString);

            BlobDownloadInfo blob = BlobsModelFactory.BlobDownloadInfo(
                DateTime.UtcNow, 0, BlobType.Block, null, null, null, null, null, null,
                CopyStatus.Pending, null, LeaseDurationType.Infinite, null, LeaseState.Available,
                null, LeaseStatus.Locked, null, null, default, 0, null, false, null, null,
Exemple #6
0
        public void BlobDownloadInfo_Dispose()
        {
            MockStream       stream           = new MockStream();
            BlobDownloadInfo blobDownloadInfo = BlobsModelFactory.BlobDownloadInfo(content: stream);

            Assert.IsFalse(stream.IsDisposed);
            blobDownloadInfo.Dispose();
            Assert.IsTrue(stream.IsDisposed);
        }
Exemple #7
0
        public static void ContentType_ReturnsExpectedValue()
        {
            const string contentType = "test/content";

            var downloadInfo = BlobsModelFactory.BlobDownloadInfo(contentType: contentType);

            var document = new AzureBlobDocument(downloadInfo);

            document.ContentType.Should().Be(downloadInfo.ContentType);
        }
Exemple #8
0
        public static void ContentInfo_ReturnsExpectedValue()
        {
            using var stream = new MemoryStream();

            var downloadInfo = BlobsModelFactory.BlobDownloadInfo(content: stream);

            var document = new AzureBlobDocument(downloadInfo);

            document.Content.Should().BeSameAs(downloadInfo.Content);
        }
                internal MockSdk Returns(Stream content, string contentType)
                {
                    var downloadInfo = BlobsModelFactory.BlobDownloadInfo(
                        content: content,
                        contentType: contentType);

                    var mockResponse = new Mock <Response <BlobDownloadInfo> >();

                    mockResponse.Setup(r => r.Value).Returns(downloadInfo);

                    mockSdk.mockBlobClient.Setup(c => c.DownloadAsync())
                    .ReturnsAsync(mockResponse.Object);

                    return(mockSdk);
                }
Exemple #10
0
        public async Task Run_ReturnsExpectedResult()
        {
            var now = DateTimeOffset.Now;

            _nowUtc.Setup(s => s.Invoke())
            .Returns(now);

            _referenceDataResponse.Setup(s => s.Invoke(It.IsAny <HttpRequestMessage>(), It.IsAny <CancellationToken>()))
            .Returns <HttpRequestMessage, CancellationToken>(async(r, ct) => new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(await File.ReadAllTextAsync("Integration/fechoices.json"))
            });

            _providerService.Setup(s => s.GetActiveProvidersAsync())
            .Returns(async() => JsonConvert.DeserializeObject <IEnumerable <Provider> >(await File.ReadAllTextAsync("Integration/providers.json")));

            _cosmosDbHelper.Setup(s => s.GetLiveApprenticeships(It.IsAny <DocumentClient>(), It.IsAny <string>()))
            .Returns(() => JsonConvert.DeserializeObject <List <Apprenticeship> >(File.ReadAllText("Integration/apprenticeships.json")));

            var blobClient      = new Mock <BlobClient>();
            var blobLeaseClient = new Mock <BlobLeaseClient>();
            var blobBytes       = default(byte[]);

            blobClient.Setup(s => s.ExistsAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(() => new MockResponse <bool>(true));

            blobLeaseClient.Setup(s => s.AcquireAsync(It.IsAny <TimeSpan>(), It.IsAny <RequestConditions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(() => new MockResponse <BlobLease>(BlobsModelFactory.BlobLease(new ETag(Guid.NewGuid().ToString()), DateTimeOffset.UtcNow, Guid.NewGuid().ToString())));

            _blobStorageClient.Setup(s => s.GetBlobClient(It.Is <string>(blobName => blobName == new ExportKey(now))))
            .Returns(blobClient.Object);

            _blobStorageClient.Setup(s => s.GetBlobLeaseClient(blobClient.Object, It.IsAny <string>()))
            .Returns(blobLeaseClient.Object);

            blobClient.Setup(s => s.UploadAsync(It.IsAny <Stream>(), It.IsAny <BlobHttpHeaders>(), It.IsAny <IDictionary <string, string> >(), It.IsAny <BlobRequestConditions>(), It.IsAny <IProgress <long> >(), It.IsAny <AccessTier?>(), It.IsAny <StorageTransferOptions>(), It.IsAny <CancellationToken>()))
            .Callback <Stream, BlobHttpHeaders, IDictionary <string, string>, BlobRequestConditions, IProgress <long>, AccessTier?, StorageTransferOptions, CancellationToken>((s, h, m, c, p, a, t, ct) =>
            {
                using (var ms = new MemoryStream())
                {
                    s.CopyTo(ms);
                    blobBytes = ms.ToArray();
                }
            });

            blobClient.Setup(s => s.DownloadAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(() => new MockResponse <BlobDownloadInfo>(BlobsModelFactory.BlobDownloadInfo(content: new MemoryStream(blobBytes))));

            await _generateProviderExportFunction.Run(new TimerInfo(new ScheduleStub(), new ScheduleStatus()), NullLogger.Instance, CancellationToken.None);

            var result = await _getApprenticeshipAsProviderFunction.Run(new Mock <HttpRequest>().Object, NullLogger.Instance, CancellationToken.None);

            var contentResult = result.Should().BeOfType <FileStreamResult>().Subject;

            contentResult.Should().NotBeNull();
            contentResult.ContentType.Should().Be("application/json");

            using var sr = new StreamReader(contentResult.FileStream);
            var resultJToken         = JToken.Parse(await sr.ReadToEndAsync());
            var expectedResultJToken = JToken.Parse(await File.ReadAllTextAsync("Integration/expectedresults.json"));

            var resultIsExpected = JToken.DeepEquals(resultJToken, expectedResultJToken);

            if (!resultIsExpected)
            {
                // Output the results so we can investigate further
                await File.WriteAllTextAsync("Integration/results.json", JsonConvert.SerializeObject(resultJToken, Formatting.Indented));
            }

            resultIsExpected.Should().BeTrue();
        }
        private string CreateBlobAndUploadToContainer(Mock <BlobContainerClient> containerMock, List <BlobItem> blobItems, string blobContent = "test", DateTimeOffset lastModified = default)
        {
            string blobName            = Path.GetRandomFileName().Replace(".", "");
            Mock <BlobBaseClient> item = new Mock <BlobBaseClient>();

            if (lastModified == default)
            {
                lastModified = DateTimeOffset.UtcNow;
            }
            var blobProperties = BlobsModelFactory.BlobProperties(lastModified: lastModified);

            item.Setup(x => x.GetPropertiesAsync(null, It.IsAny <CancellationToken>())).ReturnsAsync(Response.FromValue(blobProperties, null));
            item.Setup(x => x.Name).Returns(blobName);

            BlobItemProperties blobItemProperties = BlobsModelFactory.BlobItemProperties(true, lastModified: lastModified);
            BlobItem           blobItem           = BlobsModelFactory.BlobItem(
                name: blobName,
                properties: blobItemProperties
                );

            blobItems.Add(blobItem);

            Mock <BlobClient> blobClientMock = new Mock <BlobClient>();

            blobClientMock.Setup(x => x.Name).Returns(blobName);
            blobClientMock.Setup(x => x.Download(It.IsAny <CancellationToken>())).Returns(() =>
                                                                                          Response.FromValue(BlobsModelFactory.BlobDownloadInfo(content: new MemoryStream(Encoding.UTF8.GetBytes(blobContent))), null));
            blobClientMock.Setup(x => x.GetProperties(It.IsAny <BlobRequestConditions>(), It.IsAny <CancellationToken>()))
            .Returns(Response.FromValue(blobProperties, null));
            containerMock.Setup(x => x.GetBlobClient(blobName)).Returns(blobClientMock.Object);

            return(blobName);
        }
        public async Task GetCursor()
        {
            // Arrange
            string manifestPath = "idx/segments/2020/03/25/0200/meta.json";

            Mock <BlobContainerClient> containerClient = new Mock <BlobContainerClient>(MockBehavior.Strict);
            Mock <BlobClient>          blobClient      = new Mock <BlobClient>(MockBehavior.Strict);
            Mock <ShardFactory>        shardFactory    = new Mock <ShardFactory>(MockBehavior.Strict);

            List <Mock <Shard> > shards = new List <Mock <Shard> >();
            int shardCount = 3;

            for (int i = 0; i < shardCount; i++)
            {
                shards.Add(new Mock <Shard>(MockBehavior.Strict));
            }

            List <ShardCursor> shardCursors = new List <ShardCursor>
            {
                new ShardCursor(1, 2, 3),
                new ShardCursor(4, 5, 6),
                new ShardCursor(7, 8, 9)
            };

            DateTimeOffset dateTime   = new DateTimeOffset(2020, 3, 25, 2, 0, 0, TimeSpan.Zero);
            int            shardIndex = 1;

            SegmentCursor expectedCursor = new SegmentCursor(
                dateTime,
                shardCursors,
                shardIndex);

            containerClient.Setup(r => r.GetBlobClient(It.IsAny <string>())).Returns(blobClient.Object);

            using FileStream stream = File.OpenRead(
                      $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}{Path.DirectorySeparatorChar}Resources{Path.DirectorySeparatorChar}{"SegmentManifest.json"}");
            BlobDownloadInfo            blobDownloadInfo = BlobsModelFactory.BlobDownloadInfo(content: stream);
            Response <BlobDownloadInfo> downloadResponse = Response.FromValue(blobDownloadInfo, new MockResponse(200));

            if (IsAsync)
            {
                blobClient.Setup(r => r.DownloadAsync()).ReturnsAsync(downloadResponse);
            }
            else
            {
                blobClient.Setup(r => r.Download()).Returns(downloadResponse);
            }

            shardFactory.SetupSequence(r => r.BuildShard(
                                           It.IsAny <bool>(),
                                           It.IsAny <string>(),
                                           It.IsAny <ShardCursor>()))
            .ReturnsAsync(shards[0].Object)
            .ReturnsAsync(shards[1].Object)
            .ReturnsAsync(shards[2].Object);

            for (int i = 0; i < shardCount; i++)
            {
                shards[i].Setup(r => r.GetCursor()).Returns(shardCursors[i]);
            }

            SegmentFactory segmentFactory = new SegmentFactory(
                containerClient.Object,
                shardFactory.Object);
            Segment segment = await segmentFactory.BuildSegment(
                IsAsync,
                manifestPath,
                expectedCursor);

            // Act
            SegmentCursor cursor = segment.GetCursor();

            // Assert
            Assert.AreEqual(expectedCursor.SegmentTime, cursor.SegmentTime);
            Assert.AreEqual(expectedCursor.ShardCursors.Count, cursor.ShardCursors.Count);
            for (int i = 0; i < shardCount; i++)
            {
                Assert.AreEqual(expectedCursor.ShardCursors[i].BlockOffset, cursor.ShardCursors[i].BlockOffset);
                Assert.AreEqual(expectedCursor.ShardCursors[i].ChunkIndex, cursor.ShardCursors[i].ChunkIndex);
                Assert.AreEqual(expectedCursor.ShardCursors[i].EventIndex, cursor.ShardCursors[i].EventIndex);
            }
            Assert.AreEqual(shardIndex, cursor.ShardIndex);

            containerClient.Verify(r => r.GetBlobClient(manifestPath));

            if (IsAsync)
            {
                blobClient.Verify(r => r.DownloadAsync());
            }
            else
            {
                blobClient.Verify(r => r.Download());
            }

            for (int i = 0; i < shards.Count; i++)
            {
                shardFactory.Verify(r => r.BuildShard(
                                        IsAsync,
                                        $"log/0{i}/2020/03/25/0200/",
                                        shardCursors[i]));
            }
        }
        public async Task GetPage()
        {
            // Arrange
            string manifestPath = "idx/segments/2020/03/25/0200/meta.json";
            int    shardCount   = 3;
            int    eventCount   = 5;

            Mock <BlobContainerClient> containerClient = new Mock <BlobContainerClient>(MockBehavior.Strict);
            Mock <BlobClient>          blobClient      = new Mock <BlobClient>(MockBehavior.Strict);
            Mock <ShardFactory>        shardFactory    = new Mock <ShardFactory>(MockBehavior.Strict);

            List <Mock <Shard> > shards = new List <Mock <Shard> >();

            for (int i = 0; i < shardCount; i++)
            {
                shards.Add(new Mock <Shard>(MockBehavior.Strict));
            }

            List <Guid> eventIds = new List <Guid>();

            for (int i = 0; i < eventCount; i++)
            {
                eventIds.Add(Guid.NewGuid());
            }

            containerClient.Setup(r => r.GetBlobClient(It.IsAny <string>())).Returns(blobClient.Object);

            using FileStream stream = File.OpenRead(
                      $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}{Path.DirectorySeparatorChar}Resources{Path.DirectorySeparatorChar}{"SegmentManifest.json"}");
            BlobDownloadInfo            blobDownloadInfo = BlobsModelFactory.BlobDownloadInfo(content: stream);
            Response <BlobDownloadInfo> downloadResponse = Response.FromValue(blobDownloadInfo, new MockResponse(200));

            if (IsAsync)
            {
                blobClient.Setup(r => r.DownloadAsync()).ReturnsAsync(downloadResponse);
            }
            else
            {
                blobClient.Setup(r => r.Download()).Returns(downloadResponse);
            }

            shardFactory.SetupSequence(r => r.BuildShard(
                                           It.IsAny <bool>(),
                                           It.IsAny <string>(),
                                           It.IsAny <ShardCursor>()))
            .ReturnsAsync(shards[0].Object)
            .ReturnsAsync(shards[1].Object)
            .ReturnsAsync(shards[2].Object);

            // Set up Shards
            shards[0].SetupSequence(r => r.Next(It.IsAny <bool>(), default))
            .Returns(Task.FromResult(new BlobChangeFeedEvent
            {
                Id = eventIds[0]
            }))
            .Returns(Task.FromResult(new BlobChangeFeedEvent
            {
                Id = eventIds[3]
            }));

            shards[0].SetupSequence(r => r.HasNext())
            .Returns(true)
            .Returns(false);

            shards[1].SetupSequence(r => r.Next(It.IsAny <bool>(), default))
            .Returns(Task.FromResult(new BlobChangeFeedEvent
            {
                Id = eventIds[1]
            }))
            .Returns(Task.FromResult(new BlobChangeFeedEvent
            {
                Id = eventIds[4]
            }));

            shards[1].SetupSequence(r => r.HasNext())
            .Returns(true)
            .Returns(false);

            shards[2].Setup(r => r.Next(It.IsAny <bool>(), default))
            .Returns(Task.FromResult(new BlobChangeFeedEvent
            {
                Id = eventIds[2]
            }));

            shards[2].Setup(r => r.HasNext())
            .Returns(false);

            SegmentFactory segmentFactory = new SegmentFactory(
                containerClient.Object,
                shardFactory.Object);
            Segment segment = await segmentFactory.BuildSegment(
                IsAsync,
                manifestPath);

            // Act
            List <BlobChangeFeedEvent> events = await segment.GetPage(IsAsync, 25);

            // Assert
            Assert.AreEqual(eventCount, events.Count);
            for (int i = 0; i < eventCount; i++)
            {
                Assert.AreEqual(eventIds[i], events[i].Id);
            }

            containerClient.Verify(r => r.GetBlobClient(manifestPath));
            if (IsAsync)
            {
                blobClient.Verify(r => r.DownloadAsync());
            }
            else
            {
                blobClient.Verify(r => r.Download());
            }

            for (int i = 0; i < shards.Count; i++)
            {
                shardFactory.Verify(r => r.BuildShard(
                                        IsAsync,
                                        $"log/0{i}/2020/03/25/0200/",
                                        default));
            }

            shards[0].Verify(r => r.Next(IsAsync, default));
            shards[0].Verify(r => r.HasNext());
            shards[1].Verify(r => r.Next(IsAsync, default));
            shards[1].Verify(r => r.HasNext());
            shards[2].Verify(r => r.Next(IsAsync, default));
            shards[2].Verify(r => r.HasNext());
            shards[0].Verify(r => r.Next(IsAsync, default));
            shards[0].Verify(r => r.HasNext());
            shards[1].Verify(r => r.Next(IsAsync, default));
            shards[1].Verify(r => r.HasNext());
        }
        public Task ImportData_ReadsCsvAndUpsertsToSql() => WithSqlQueryDispatcher(async sqlDispatcher =>
        {
            // Arrange

            // Create a CSV with 4 records;
            // 2 valid inside England, 1 valid outside of England and one with invalid lat/lng
            var csv = $@"pcds,lat,long,ctry
AB1 2CD,1,-1,{OnspdDataImporter.EnglandCountryId}
BC2 3DE,-2,2,{OnspdDataImporter.EnglandCountryId}
CD3 4EF,3,3,notenglandcountry
DE4 5FG,-99,1,{OnspdDataImporter.EnglandCountryId}";

            var csvStream = new MemoryStream(Encoding.UTF8.GetBytes(csv));
            csvStream.Seek(0L, SeekOrigin.Begin);

            var downloadResponse = new Mock <Response <BlobDownloadInfo> >();

            var blobDownloadInfo = BlobsModelFactory.BlobDownloadInfo(content: csvStream);

            downloadResponse.SetupGet(mock => mock.Value).Returns(blobDownloadInfo);

            var blobClient = new Mock <BlobClient>();

            blobClient
            .Setup(mock => mock.DownloadAsync())
            .ReturnsAsync(downloadResponse.Object);

            var blobContainerClient = new Mock <BlobContainerClient>();

            blobContainerClient
            .Setup(mock => mock.GetBlobClient(OnspdDataImporter.FileName))
            .Returns(blobClient.Object);

            var blobServiceClient = new Mock <BlobServiceClient>();

            blobServiceClient
            .Setup(mock => mock.GetBlobContainerClient(OnspdDataImporter.ContainerName))
            .Returns(blobContainerClient.Object);

            var importer = new OnspdDataImporter(
                blobServiceClient.Object,
                sqlDispatcher,
                new NullLogger <OnspdDataImporter>());

            // Act
            await importer.ImportData();

            // Assert
            var imported = (await sqlDispatcher.Transaction.Connection.QueryAsync <PostcodeInfo>(
                                "select Postcode, Position.Lat Latitude, Position.Long Longitude, InEngland from Pttcd.Postcodes",
                                transaction: sqlDispatcher.Transaction)).AsList();

            imported.Should().BeEquivalentTo(new[]
            {
                new PostcodeInfo()
                {
                    Postcode = "AB1 2CD", Latitude = 1, Longitude = -1, InEngland = true
                },
                new PostcodeInfo()
                {
                    Postcode = "BC2 3DE", Latitude = -2, Longitude = 2, InEngland = true
                },
                new PostcodeInfo()
                {
                    Postcode = "CD3 4EF", Latitude = 3, Longitude = 3, InEngland = false
                }
            });
        });
        public async Task GetPersonnelNumbersTest()
        {
            var storageAccountSecret  = new StorageAccountSecret("myconnectionstring");
            var loggerMock            = new Mock <ILoggingRepository>();
            var blobClientFactoryMock = new Mock <IBlobClientFactory>();
            var blobClientMock        = new Mock <BlobClient>();

            var personnelNumber = "1223344";
            var sw = new StreamWriter(new MemoryStream());

            sw.WriteLine("PersonnelNumbers");
            sw.WriteLine(personnelNumber);
            sw.Flush();
            sw.BaseStream.Position = 0;

            var bdi = BlobsModelFactory.BlobDownloadInfo(
                DateTimeOffset.Now,
                1,
                BlobType.Block,
                null, null,
                null,
                null,
                null,
                new Uri("http://file.url"),
                CopyStatus.Success,
                null,
                LeaseDurationType.Fixed,
                null,
                LeaseState.Available,
                null,
                LeaseStatus.Unlocked,
                new byte[0],
                null,
                ETag.All,
                0,
                null,
                false,
                null,
                null,
                1000,
                new byte[0],
                null,
                sw.BaseStream,
                DateTimeOffset.Now);

            var response = new Mock <Response>();

            response.SetupGet(x => x.Status).Returns((int)HttpStatusCode.OK);

            var bdiresponse = Response.FromValue <BlobDownloadInfo>(bdi, null);

            var downloadResponse = new Mock <Response <BlobDownloadInfo> >();

            downloadResponse.SetupGet(x => x.Value).Returns(bdiresponse);
            downloadResponse.Setup(x => x.GetRawResponse()).Returns(response.Object);

            blobClientMock.Setup(x => x.Exists(It.IsAny <CancellationToken>())).Returns(Response.FromValue <bool>(true, new Mock <Response>().Object));
            blobClientMock.Setup(x => x.DownloadAsync()).ReturnsAsync(downloadResponse.Object);

            blobClientFactoryMock.Setup(x => x.GetBlobClient(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())).Returns(blobClientMock.Object);

            var service          = new AzureUserReaderService(storageAccountSecret, loggerMock.Object, blobClientFactoryMock.Object);
            var personnelNumbers = await service.GetPersonnelNumbersAsync("validcontainer", "valid/blob/path/file.csv");

            Assert.AreEqual(1, personnelNumbers.Count);
            Assert.AreEqual(personnelNumbers[0], personnelNumber);
        }
        public async Task UploadUsersMemberIdTest()
        {
            var storageAccountSecret  = new StorageAccountSecret("myconnectionstring");
            var loggerMock            = new Mock <ILoggingRepository>();
            var blobClientFactoryMock = new Mock <IBlobClientFactory>();
            var blobClientMock        = new Mock <BlobClient>();

            var personnelNumbers = new[] { "111111", "222222", "333333", "444444" };
            var sw = new StreamWriter(new MemoryStream());

            sw.WriteLine("PersonnelNumber,AzureObjectId,UserPrincipalName");
            sw.WriteLine($"{personnelNumbers[0]},{Guid.NewGuid()},[email protected]");
            sw.WriteLine($"{personnelNumbers[1]},{Guid.NewGuid()},[email protected]");
            sw.Flush();
            sw.BaseStream.Position = 0;

            var bdi = BlobsModelFactory.BlobDownloadInfo(
                DateTimeOffset.Now,
                1,
                BlobType.Block,
                null, null,
                null,
                null,
                null,
                new Uri("http://file.url"),
                CopyStatus.Success,
                null,
                LeaseDurationType.Fixed,
                null,
                LeaseState.Available,
                null,
                LeaseStatus.Unlocked,
                new byte[0],
                null,
                ETag.All,
                0,
                null,
                false,
                null,
                null,
                1000,
                new byte[0],
                null,
                sw.BaseStream,
                DateTimeOffset.Now);

            var response         = new Mock <Response>();
            var bdiresponse      = Response.FromValue <BlobDownloadInfo>(bdi, null);
            var downloadResponse = new Mock <Response <BlobDownloadInfo> >();
            var usersToUpload    = new List <GraphProfileInformation>();

            response.SetupGet(x => x.Status).Returns((int)HttpStatusCode.OK);
            downloadResponse.SetupGet(x => x.Value).Returns(bdiresponse);
            blobClientMock.Setup(x => x.Exists(It.IsAny <CancellationToken>())).Returns(Response.FromValue <bool>(true, new Mock <Response>().Object));
            blobClientMock.Setup(x => x.DownloadAsync()).ReturnsAsync(downloadResponse.Object);
            blobClientMock.Setup(x => x.UploadAsync(It.IsAny <Stream>(), It.IsAny <bool>(), It.IsAny <CancellationToken>()))
            .Callback((Stream stream, bool overwrite, CancellationToken token) =>
            {
                var sr = new StreamReader(stream);

                using (var reader = new StreamReader(stream))
                {
                    reader.ReadLine();                 // skip header

                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        var data = line.Split(",", StringSplitOptions.RemoveEmptyEntries);
                        if (data.Length >= 2)
                        {
                            usersToUpload.Add(new GraphProfileInformation {
                                PersonnelNumber = data[0], Id = data[1]
                            });
                        }
                    }
                }
            });
            blobClientFactoryMock.Setup(x => x.GetBlobClient(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())).Returns(blobClientMock.Object);

            var users = new List <GraphProfileInformation>
            {
                new GraphProfileInformation {
                    PersonnelNumber = personnelNumbers[2], Id = Guid.NewGuid().ToString()
                },
                new GraphProfileInformation {
                    PersonnelNumber = personnelNumbers[3], Id = Guid.NewGuid().ToString()
                }
            };

            var service = new AzureUserReaderService(storageAccountSecret, loggerMock.Object, blobClientFactoryMock.Object);
            await service.UploadUsersMemberIdAsync(new Entities.UploadRequest {
                ContainerName = "mycontainer", BlobTargetDirectory = "/target/folder", Users = users
            });

            Assert.AreEqual(4, usersToUpload.Count);
            foreach (var personnelNumber in personnelNumbers)
            {
                Assert.IsTrue(usersToUpload.Any(x => x.PersonnelNumber == personnelNumber));
            }
        }