public void SetLatestStablePackage_Add()
        {
            // Arrange
            Uri catalog = new Uri("http://foo");
            Uri baseAddress = new Uri("http://storage");
            MemoryStorage storage = new MemoryStorage(baseAddress);
            Uri fileAddress = new Uri("http://storage/packagecatalog.json");
            storage.Content.Add(fileAddress, new StringStorageContent(inputJson));

            // Act
            PackageCatalog packageCatalog = new PackageCatalog(catalog, storage, fileAddress, null);
            packageCatalog.LoadAsync(fileAddress, storage, new CancellationToken()).Wait();
            packageCatalog.SetLatestStablePackage("My.Shiny.New.Package", "99.99.99-prerelease", new Guid(), DateTime.MinValue, new Uri("http://foo/download"), true);

            // Assert
            PackageInfo package = packageCatalog.Packages["My.Shiny.New.Package"];

            Assert.Equal(4, packageCatalog.Packages.Count);
            Assert.Equal("My.Shiny.New.Package", package.PackageId);
            Assert.Equal("99.99.99-prerelease", package.LatestStableVersion);
            Assert.Equal(true, package.HaveIdx);
            Assert.Equal(new Guid(), package.CommitId);
            Assert.Equal(DateTime.MinValue, package.CommitTimeStamp);
            Assert.Equal(new Uri("http://foo/download"), package.DownloadUrl);
        }
        public static MemoryStorage CreateTestCatalogWithThreePackagesAndDelete()
        {
            var catalogStorage = new MemoryStorage();

            catalogStorage.Content.Add(
                new Uri(catalogStorage.BaseAddress, "index.json"),
                new StringStorageContent(TestCatalogEntries.TestCatalogStorageWithThreePackagesAndDeleteIndex));

            catalogStorage.Content.Add(
                new Uri(catalogStorage.BaseAddress, "page0.json"),
                new StringStorageContent(TestCatalogEntries.TestCatalogStorageWithThreePackagesAndDeletePage));

            catalogStorage.Content.Add(
                new Uri(catalogStorage.BaseAddress, "data/2015.10.12.10.08.54/listedpackage.1.0.0.json"),
                new StringStorageContent(TestCatalogEntries.TestCatalogStorageWithThreePackagesListedPackage100));

            catalogStorage.Content.Add(
                new Uri(catalogStorage.BaseAddress, "data/2015.10.12.10.08.54/unlistedpackage.1.0.0.json"),
                new StringStorageContent(TestCatalogEntries.TestCatalogStorageWithThreePackagesUnlistedPackage100));

            catalogStorage.Content.Add(
                new Uri(catalogStorage.BaseAddress, "data/2015.10.12.10.08.55/listedpackage.1.0.1.json"),
                new StringStorageContent(TestCatalogEntries.TestCatalogStorageWithThreePackagesListedPackage101));
            catalogStorage.Content.Add(
                new Uri(catalogStorage.BaseAddress, "data/2015.10.13.06.40.07/otherpackage.1.0.0.json"),
                new StringStorageContent(TestCatalogEntries.TestCatalogStorageWithThreePackagesOtherPackage100));

            return catalogStorage;
        }
        public async Task PropagatesDeleteToAllStorage()
        {
            // Arrange
            var storage1 = new MemoryStorage(new Uri("http://tempuri.org/firstone"));
            var storage2 = new MemoryStorage(new Uri("http://tempuri.org/secondone"));
            var storage3 = new MemoryStorage(new Uri("http://tempuri.org/thirdone"));

            var aggregateStorageFactory = Create(storage1, storage2, storage3);
            var aggregateStorageRoot = aggregateStorageFactory.Create();
            var aggregateStorageSub = aggregateStorageFactory.Create("sub");

            await aggregateStorageRoot.Save(new Uri("http://tempuri.org/firstone/test.txt"), new StringStorageContent("test1"), CancellationToken.None);
            await aggregateStorageSub.Save(new Uri("http://tempuri.org/firstone/sub/test.txt"), new StringStorageContent("test2"), CancellationToken.None);

            // Act
            await aggregateStorageRoot.Delete(new Uri("http://tempuri.org/firstone/test.txt"), CancellationToken.None);

            // Assert
            Assert.Equal(1, storage1.Content.Count);
            Assert.Equal(1, storage2.Content.Count);
            Assert.Equal(1, storage3.Content.Count);

            AssertUriAndContentDoesNotExist(storage1, new Uri("http://tempuri.org/firstone/test.txt"), "test1");
            AssertUriAndContentDoesNotExist(storage2, new Uri("http://tempuri.org/secondone/test.txt"), "test1");
            AssertUriAndContentDoesNotExist(storage3, new Uri("http://tempuri.org/thirdone/test.txt"), "test1");

            AssertUriAndContentExists(storage1, new Uri("http://tempuri.org/firstone/sub/test.txt"), "test2");
            AssertUriAndContentExists(storage2, new Uri("http://tempuri.org/secondone/sub/test.txt"), "test2");
            AssertUriAndContentExists(storage3, new Uri("http://tempuri.org/thirdone/sub/test.txt"), "test2");
        }
        public void ComposePackageResourceUrl_ValidInputs(string baseAddress, string packageId, string packageVersion, string filename, string expectedAddress)
        {
            // Arrange
            Uri baseUri = new Uri(baseAddress);
            MemoryStorage storage = new MemoryStorage(baseUri);

            // Act
            Uri registrationUri = storage.ComposePackageResourceUrl(packageId, packageVersion, filename);

            // Assert
            Uri expectedUri = new Uri(expectedAddress);
            Assert.True(registrationUri.Equals(expectedUri));
        }
        public void ComposePackageResourceUrl_InvalidInputs(string baseAddress, string packageId, string packageVersion, string filename, string expectedAddress, Type expectedException)
        {
            // Arrange
            Uri baseUri = new Uri(baseAddress);
            MemoryStorage storage = new MemoryStorage(baseUri);

            // Act
            Action action = delegate
            {
                Uri registrationUri = storage.ComposePackageResourceUrl(packageId, packageVersion, filename);
            };

            // Assert
            Assert.Throws(expectedException, action);
        }
        public async Task AlwaysReadsFromPrimary()
        {
            // Arrange
            var storage1 = new MemoryStorage(new Uri("http://tempuri.org/firstone"));
            var storage2 = new MemoryStorage(new Uri("http://tempuri.org/secondone"));
            var storage3 = new MemoryStorage(new Uri("http://tempuri.org/thirdone"));

            var aggregateStorageFactory = Create(storage1, storage2, storage3);
            var aggregateStorage = aggregateStorageFactory.Create();

            await aggregateStorage.Save(new Uri("http://tempuri.org/firstone/test.txt"), new StringStorageContent("test1"), CancellationToken.None);

            // Act
            var content1 = await aggregateStorage.Load(new Uri("http://tempuri.org/firstone/test.txt"), CancellationToken.None);
            var content2 = await aggregateStorage.Load(new Uri("http://tempuri.org/secondone/test.txt"), CancellationToken.None);
            var content3 = await aggregateStorage.Load(new Uri("http://tempuri.org/thirdone/test.txt"), CancellationToken.None);

            // Assert
            Assert.NotNull(content1);
            Assert.Null(content2);
            Assert.Null(content3);
        }
        public static MemoryStorage CreateTestRegistrations()
        {
            var registrationStorage = new MemoryStorage(new Uri("https://api.nuget.org/container1/"));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "cursor.json"),
                new StringStorageContent(TestRegistrationEntries.CursorJson));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "businessframework/index.json"),
                new StringStorageContent(TestRegistrationEntries.BusinessFrameworkIndexJson));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "businessframework/0.2.0.json"),
                new StringStorageContent(TestRegistrationEntries.BusinessFrameworkVersion1));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "automapper/index.json"),
                new StringStorageContent(TestRegistrationEntries.AutomapperIndexJson));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "automapper/1.1.0.118.json"),
                new StringStorageContent(TestRegistrationEntries.AutomapperVersion1));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "antlr/index.json"),
                new StringStorageContent(TestRegistrationEntries.AntlrIndexJson));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "antlr/3.1.1.json"),
                new StringStorageContent(TestRegistrationEntries.AntlrVersion1));

            registrationStorage.Content.Add(
                new Uri(registrationStorage.BaseAddress, "antlr/3.1.3.42154.json"),
                new StringStorageContent(TestRegistrationEntries.AntlrVersion2));

            return registrationStorage;
        }
        public void Load()
        {
            // Arrange
            Uri catalog = new Uri("http://foo");
            Uri baseAddress = new Uri("http://storage");
            MemoryStorage storage = new MemoryStorage(baseAddress);
            Uri fileAddress = new Uri("http://storage/packagecatalog.json");
            storage.Content.Add(fileAddress, new StringStorageContent(inputJson));

            // Act
            PackageCatalog packageCatalog = new PackageCatalog(catalog, storage, fileAddress, null);
            packageCatalog.LoadAsync(fileAddress, storage, new CancellationToken()).Wait();

            // Assert
            PackageInfo package = packageCatalog.Packages["51Degrees.mobi"];

            Assert.Equal(3, packageCatalog.Packages.Count);
            Assert.Equal("51Degrees.mobi", package.PackageId);
            Assert.Equal("3.2.5.6", package.LatestStableVersion);
            Assert.Equal(false, package.HaveIdx);
            Assert.Equal(new Guid("788b39a0-9a58-4000-88be-599a0ad2a8a9"), package.CommitId);
            Assert.Equal(DateTime.Parse("2015-12-07T14:36:57.142124Z").ToUniversalTime(), package.CommitTimeStamp);
            Assert.Equal(new Uri("https://api.nuget.org/packages/51degrees.mobi.3.2.5.6.nupkg"), package.DownloadUrl);
        }
        public void Delist()
        {
            // Arrange
            Uri catalog = new Uri("http://foo");
            Uri baseAddress = new Uri("http://storage");
            MemoryStorage storage = new MemoryStorage(baseAddress);
            Uri fileAddress = new Uri("http://storage/packagecatalog.json");
            storage.Content.Add(fileAddress, new StringStorageContent(inputJson));

            // Act
            PackageCatalog packageCatalog = new PackageCatalog(catalog, storage, fileAddress, null);
            packageCatalog.LoadAsync(fileAddress, storage, new CancellationToken()).Wait();
            packageCatalog.DelistPackage("51Degrees.mobi");

            // Assert
            Assert.Equal(2, packageCatalog.Packages.Count);

            Action action = delegate
            {
                Assert.Null(packageCatalog.Packages["51Degrees.mobi"]);
            };

            Assert.Throws(typeof(KeyNotFoundException), action);
        }
        public async Task AppendsDeleteToExistingCatalog()
        {
            // Arrange
            var catalogStorage = Catalogs.CreateTestCatalogWithThreePackages();
            var auditingStorage = new MemoryStorage();
            auditingStorage.Content.Add(
                new Uri(auditingStorage.BaseAddress, "2015-01-01T00:01:01-deleted.audit.v1.json"),
                new StringStorageContent(TestCatalogEntries.DeleteAuditRecordForOtherPackage100));

            var mockServer = new MockServerHttpClientHandler();

            mockServer.SetAction(" / ", async request => new HttpResponseMessage(HttpStatusCode.OK));
            mockServer.SetAction("/Packages?$filter=Created%20gt%20DateTime'0001-01-01T00:00:00.0000000Z'&$top=20&$orderby=Created&$select=Created,LastEdited,Published,LicenseNames,LicenseReportUrl", GetCreatedPackages);
            mockServer.SetAction("/Packages?$filter=Created%20gt%20DateTime'2015-01-01T00:00:00.0000000Z'&$top=20&$orderby=Created&$select=Created,LastEdited,Published,LicenseNames,LicenseReportUrl", GetEmptyPackages);

            mockServer.SetAction("/Packages?$filter=LastEdited%20gt%20DateTime'0001-01-01T00:00:00.0000000Z'&$top=20&$orderby=LastEdited&$select=Created,LastEdited,Published,LicenseNames,LicenseReportUrl", GetEditedPackages);
            mockServer.SetAction("/Packages?$filter=LastEdited%20gt%20DateTime'2015-01-01T00:00:00.0000000Z'&$top=20&$orderby=LastEdited&$select=Created,LastEdited,Published,LicenseNames,LicenseReportUrl", GetEmptyPackages);

            mockServer.SetAction("/package/ListedPackage/1.0.0", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\ListedPackage.1.0.0.zip")) });
            mockServer.SetAction("/package/ListedPackage/1.0.1", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\ListedPackage.1.0.1.zip")) });
            mockServer.SetAction("/package/UnlistedPackage/1.0.0", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\UnlistedPackage.1.0.0.zip")) });

            // Act
            var target = new TestableFeed2Catalog(mockServer);
            await target.InvokeProcessFeed("http://tempuri.org", catalogStorage, auditingStorage, null, TimeSpan.FromMinutes(5), 20, true, CancellationToken.None);

            // Assert
            Assert.Equal(6, catalogStorage.Content.Count);

            // Ensure catalog has index.json
            var catalogIndex = catalogStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("index.json"));
            Assert.NotNull(catalogIndex.Key);
            Assert.Contains("\"nuget:lastCreated\": \"2015-01-01T00:00:00Z\"", catalogIndex.Value.GetContentString());
            Assert.Contains("\"nuget:lastDeleted\": \"2015-01-01T01:01:01", catalogIndex.Value.GetContentString());
            Assert.Contains("\"nuget:lastEdited\": \"2015-01-01T00:00:00", catalogIndex.Value.GetContentString());

            // Ensure catalog has page0.json
            var pageZero = catalogStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("page0.json"));
            Assert.NotNull(pageZero.Key);
            Assert.Contains("\"parent\": \"http://tempuri.org/index.json\",", pageZero.Value.GetContentString());

            Assert.Contains("/listedpackage.1.0.0.json\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:id\": \"ListedPackage\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:version\": \"1.0.0\"", pageZero.Value.GetContentString());

            Assert.Contains("/listedpackage.1.0.1.json\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:id\": \"ListedPackage\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:version\": \"1.0.1\"", pageZero.Value.GetContentString());

            Assert.Contains("/unlistedpackage.1.0.0.json\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:id\": \"UnlistedPackage\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:version\": \"1.0.0\"", pageZero.Value.GetContentString());

            Assert.Contains("/otherpackage.1.0.0.json\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:id\": \"OtherPackage\",", pageZero.Value.GetContentString());
            Assert.Contains("\"nuget:version\": \"1.0.0\"", pageZero.Value.GetContentString());

            // Check individual package entries
            var package1 = catalogStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage.1.0.0.json"));
            Assert.NotNull(package1.Key);
            Assert.Contains("\"PackageDetails\",", package1.Value.GetContentString());
            Assert.Contains("\"id\": \"ListedPackage\",", package1.Value.GetContentString());
            Assert.Contains("\"version\": \"1.0.0\",", package1.Value.GetContentString());

            var package2 = catalogStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage.1.0.1.json"));
            Assert.NotNull(package2.Key);
            Assert.Contains("\"PackageDetails\",", package2.Value.GetContentString());
            Assert.Contains("\"id\": \"ListedPackage\",", package2.Value.GetContentString());
            Assert.Contains("\"version\": \"1.0.1\",", package2.Value.GetContentString());

            var package3 = catalogStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/unlistedpackage.1.0.0.json"));
            Assert.NotNull(package3.Key);
            Assert.Contains("\"PackageDetails\",", package3.Value.GetContentString());
            Assert.Contains("\"id\": \"UnlistedPackage\",", package3.Value.GetContentString());
            Assert.Contains("\"version\": \"1.0.0\",", package3.Value.GetContentString());

            // Ensure catalog has the delete of "OtherPackage"
            var package4 = catalogStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/otherpackage.1.0.0.json"));
            Assert.NotNull(package4.Key);
            Assert.Contains("\"PackageDelete\",", package4.Value.GetContentString());
            Assert.Contains("\"id\": \"OtherPackage\",", package4.Value.GetContentString());
            Assert.Contains("\"version\": \"1.0.0\",", package4.Value.GetContentString());
        }
        public async Task CreatesFlatContainerAndRespectsDeletes()
        {
            // Arrange
            var catalogStorage = Catalogs.CreateTestCatalogWithThreePackagesAndDelete();
            var catalogToDnxStorage = new MemoryStorage();
            var catalogToDnxStorageFactory = new TestStorageFactory(name => catalogToDnxStorage.WithName(name));

            var mockServer = new MockServerHttpClientHandler();

            mockServer.SetAction("/", async request => new HttpResponseMessage(HttpStatusCode.OK));
            await mockServer.AddStorage(catalogStorage);

            mockServer.SetAction("/listedpackage.1.0.0.nupkg", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\ListedPackage.1.0.0.zip")) });
            mockServer.SetAction("/listedpackage.1.0.1.nupkg", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\ListedPackage.1.0.1.zip")) });
            mockServer.SetAction("/unlistedpackage.1.0.0.nupkg", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\UnlistedPackage.1.0.0.zip")) });
            mockServer.SetAction("/otherpackage.1.0.0.nupkg", async request => new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(File.OpenRead("Packages\\OtherPackage.1.0.0.zip")) });

            // Setup collector
            var target = new DnxCatalogCollector(new Uri("http://tempuri.org/index.json"), catalogToDnxStorageFactory, () => mockServer)
            {
                ContentBaseAddress = new Uri("http://tempuri.org/packages")
            };
            ReadWriteCursor front = new DurableCursor(catalogToDnxStorage.ResolveUri("cursor.json"), catalogToDnxStorage, MemoryCursor.Min.Value);
            ReadCursor back = MemoryCursor.Max;

            // Act
            await target.Run(front, back, CancellationToken.None);

            // Assert
            Assert.Equal(9, catalogToDnxStorage.Content.Count);

            // Ensure storage has cursor.json
            var cursorJson = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("cursor.json"));
            Assert.NotNull(cursorJson.Key);

            // Check package entries - ListedPackage
            var package1Index = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/index.json"));
            Assert.NotNull(package1Index.Key);
            Assert.Contains("\"1.0.0\"", package1Index.Value.GetContentString());
            Assert.Contains("\"1.0.1\"", package1Index.Value.GetContentString());

            var package1Nuspec = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/1.0.0/listedpackage.nuspec"));
            var package1Nupkg = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/1.0.0/listedpackage.1.0.0.nupkg"));
            Assert.NotNull(package1Nuspec.Key);
            Assert.NotNull(package1Nupkg.Key);

            var package2Nuspec = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/1.0.1/listedpackage.nuspec"));
            var package2Nupkg = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/1.0.1/listedpackage.1.0.1.nupkg"));
            Assert.NotNull(package2Nuspec.Key);
            Assert.NotNull(package2Nupkg.Key);

            // Check package entries - UnlistedPackage
            var package3Index = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/unlistedpackage/index.json"));
            Assert.NotNull(package3Index.Key);
            Assert.Contains("\"1.0.0\"", package3Index.Value.GetContentString());

            var package3Nuspec = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/unlistedpackage/1.0.0/unlistedpackage.nuspec"));
            var package3Nupkg = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/unlistedpackage/1.0.0/unlistedpackage.1.0.0.nupkg"));
            Assert.NotNull(package3Nuspec.Key);
            Assert.NotNull(package3Nupkg.Key);

            // Ensure storage does not have the deleted "OtherPackage"
            var otherPackageIndex = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/otherpackage/index.json"));
            var otherPackageNuspec = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/otherpackage/1.0.0/otherpackage.nuspec"));
            var otherPackageNupkg = catalogToDnxStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/otherpackage/1.0.0/otherpackage.1.0.0.nupkg"));
            Assert.Null(otherPackageIndex.Key);
            Assert.Null(otherPackageNuspec.Key);
            Assert.Null(otherPackageNupkg.Key);
        }
        public async Task CorrectlyReplacesRegistrationBaseUrlsInSecondaryStorage()
        {
            // Arrange
            var storageToReplay = Registrations.CreateTestRegistrations();
            var storage1 = new MemoryStorage(storageToReplay.BaseAddress);
            var storage2 = new MemoryStorage(new Uri("http://tempuri.org/secondone"));
            var storage3 = new MemoryStorage(new Uri("http://tempuri.org/thirdone"));

            var secondaryStorageBaseUrlRewriter = new SecondaryStorageBaseUrlRewriter(new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>(storage1.BaseAddress.ToString(), storage2.BaseAddress.ToString() ),
                new KeyValuePair<string, string>(storage1.BaseAddress.ToString(), storage3.BaseAddress.ToString() )
            });

            var aggregateStorageFactory = CreateWithInterceptor(secondaryStorageBaseUrlRewriter.Rewrite, storage1, storage2, storage3);
            var aggregateStorage = aggregateStorageFactory.Create();

            var storage1BaseAddress = storage1.BaseAddress.ToString();
            var storage2BaseAddress = storage2.BaseAddress.ToString();
            var storage3BaseAddress = storage3.BaseAddress.ToString();

            // Act
            foreach (var content in storageToReplay.Content)
            {
                await aggregateStorage.Save(content.Key, content.Value, CancellationToken.None);
            }

            // Assert
            Assert.Equal(storageToReplay.Content.Count, storage1.Content.Count);
            Assert.Equal(storageToReplay.Content.Count, storage2.Content.Count);
            Assert.Equal(storageToReplay.Content.Count, storage3.Content.Count);

            foreach (var content in storage1.Content)
            {
                AssertContentDoesNotContain(content.Value, storage1BaseAddress);
                AssertContentDoesNotContain(content.Value, storage2BaseAddress);
                AssertContentDoesNotContain(content.Value, storage3BaseAddress);
            }

            foreach (var content in storage2.Content)
            {
                AssertContentDoesNotContain(content.Value, storage1BaseAddress);
                AssertContentDoesNotContain(content.Value, storage2BaseAddress);
                AssertContentDoesNotContain(content.Value, storage3BaseAddress);
            }

            foreach (var content in storage3.Content)
            {
                AssertContentDoesNotContain(content.Value, storage1BaseAddress);
                AssertContentDoesNotContain(content.Value, storage2BaseAddress);
                AssertContentDoesNotContain(content.Value, storage3BaseAddress);
            }
        }
        public void UpdateLatestStablePackage(string packageId, string packageVersion, bool haveIdx, int expectedPackageCount, bool expectedHaveIdx, bool packageIsNull)
        {
            // Arrange
            Uri catalog = new Uri("http://foo");
            Uri baseAddress = new Uri("http://storage");
            MemoryStorage storage = new MemoryStorage(baseAddress);
            Uri fileAddress = new Uri("http://storage/packagecatalog.json");
            storage.Content.Add(fileAddress, new StringStorageContent(inputJson));

            // Act
            PackageCatalog packageCatalog = new PackageCatalog(catalog, storage, fileAddress, null);
            packageCatalog.LoadAsync(fileAddress, storage, new CancellationToken()).Wait();
            packageCatalog.UpdateLatestStablePackage(packageId, packageVersion, haveIdx);

            // Assert
            PackageInfo package;
            packageCatalog.Packages.TryGetValue(packageId, out package);

            Assert.Equal(expectedPackageCount, packageCatalog.Packages.Count);
            Assert.Equal(packageIsNull, package == null);

            if (!packageIsNull)
            {
                Assert.Equal(expectedHaveIdx, package.HaveIdx);
            }
        }
        protected AggregateStorageFactory CreateWithInterceptor(AggregateStorage.WriteSecondaryStorageContentInterceptor interceptor, MemoryStorage primaryStorage, MemoryStorage secondaryStorage, params MemoryStorage[] storages)
        {
            var storageFactories = new List<StorageFactory>();
            storageFactories.Add(new TestStorageFactory(name => primaryStorage.WithName(name)));
            storageFactories.Add(new TestStorageFactory(name => secondaryStorage.WithName(name)));

            foreach (var storage in storages)
            {
                storageFactories.Add(new TestStorageFactory(name => storage.WithName(name)));
            }

            return new AggregateStorageFactory(storageFactories.First(), storageFactories.Skip(1).ToArray(), interceptor);
        }
        protected void AssertUriAndContentExists(MemoryStorage storage, Uri uri, string expectedContent)
        {
            var value = storage.Content.FirstOrDefault(pair => pair.Key == uri);

            Assert.NotNull(value.Key);
            Assert.Equal(expectedContent, value.Value.GetContentString());
        }
        public async Task CreatesRegistrationsAndRespectsDeletes()
        {
            // Arrange
            var catalogStorage = Catalogs.CreateTestCatalogWithThreePackagesAndDelete();
            var catalogToRegistrationStorage = new MemoryStorage();
            var catalogToRegistrationStorageFactory = new TestStorageFactory(name => catalogToRegistrationStorage.WithName(name));

            var mockServer = new MockServerHttpClientHandler();

            mockServer.SetAction("/", async request => new HttpResponseMessage(HttpStatusCode.OK));
            await mockServer.AddStorage(catalogStorage);

            // Setup collector
            var target = new RegistrationCollector(new Uri("http://tempuri.org/index.json"), catalogToRegistrationStorageFactory, () => mockServer)
            {
                ContentBaseAddress = new Uri("http://tempuri.org/packages"),
                UnlistShouldDelete = false
            };
            ReadWriteCursor front = new DurableCursor(catalogToRegistrationStorage.ResolveUri("cursor.json"), catalogToRegistrationStorage, MemoryCursor.Min.Value);
            ReadCursor back = MemoryCursor.Max;

            // Act
            await target.Run(front, back, CancellationToken.None);

            // Assert
            Assert.Equal(6, catalogToRegistrationStorage.Content.Count);

            // Ensure storage has cursor.json
            var cursorJson = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("cursor.json"));
            Assert.NotNull(cursorJson.Key);

            // Check package entries - ListedPackage
            var package1Index = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/index.json"));
            Assert.NotNull(package1Index.Key);
            Assert.Contains("\"catalog:CatalogRoot\"", package1Index.Value.GetContentString());
            Assert.Contains("\"PackageRegistration\"", package1Index.Value.GetContentString());
            Assert.Contains("\"http://tempuri.org/data/2015.10.12.10.08.54/listedpackage.1.0.0.json\"", package1Index.Value.GetContentString());
            Assert.Contains("\"http://tempuri.org/packages/listedpackage.1.0.0.nupkg\"", package1Index.Value.GetContentString());
            Assert.Contains("\"http://tempuri.org/data/2015.10.12.10.08.55/listedpackage.1.0.1.json\"", package1Index.Value.GetContentString());
            Assert.Contains("\"http://tempuri.org/packages/listedpackage.1.0.1.nupkg\"", package1Index.Value.GetContentString());
            Assert.Contains("\"lower\": \"1.0.0\",", package1Index.Value.GetContentString());
            Assert.Contains("\"upper\": \"1.0.1\"", package1Index.Value.GetContentString());

            var package1 = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/1.0.0.json"));
            Assert.NotNull(package1.Key);

            var package2 = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/listedpackage/1.0.1.json"));
            Assert.NotNull(package2.Key);

            // Check package entries - UnlistedPackage
            var package2Index = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/unlistedpackage/index.json"));
            Assert.NotNull(package1Index.Key);
            Assert.Contains("\"catalog:CatalogRoot\"", package2Index.Value.GetContentString());
            Assert.Contains("\"PackageRegistration\"", package2Index.Value.GetContentString());
            Assert.Contains("\"http://tempuri.org/data/2015.10.12.10.08.54/unlistedpackage.1.0.0.json\"", package2Index.Value.GetContentString());
            Assert.Contains("\"http://tempuri.org/packages/unlistedpackage.1.0.0.nupkg\"", package2Index.Value.GetContentString());
            Assert.Contains("\"lower\": \"1.0.0\",", package2Index.Value.GetContentString());
            Assert.Contains("\"upper\": \"1.0.0\"", package2Index.Value.GetContentString());

            var package3 = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/unlistedpackage/1.0.0.json"));
            Assert.NotNull(package3.Key);

            // Ensure storage does not have the deleted "OtherPackage"
            var otherPackageIndex = catalogToRegistrationStorage.Content.FirstOrDefault(pair => pair.Key.PathAndQuery.EndsWith("/otherpackage/index.json"));
            Assert.Null(otherPackageIndex.Key);
        }
        protected void AssertUriAndContentDoesNotExist(MemoryStorage storage, Uri uri, string expectedContent)
        {
            var value = storage.Content.FirstOrDefault(pair => pair.Key == uri);

            Assert.Null(value.Key);
        }