public void PopularityTransfersAreNotTransitive()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 100);
                DownloadData.SetDownloadCount("C", "1.0.0", 100);

                DownloadChanges["A"] = 100;

                PopularityTransfers.AddTransfer("A", "B");
                PopularityTransfers.AddTransfer("B", "C");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                // A transfers downloads to B.
                // B transfers downloads to C.
                // B and C should reject downloads from A.
                Assert.Equal(new[] { "A", "B" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(0, result["B"]);
            }
            public void RemovesIncomingPopularityTransfer()
            {
                // A used to transfer to both B and C.
                // A now transfers to just B.
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);
                DownloadData.SetDownloadCount("C", "1.0.0", 0);

                PopularityTransfers.AddTransfer("A", "B");

                TransferChanges["A"] = new[] { "B" };
                OldTransfers.AddTransfer("A", "B");
                OldTransfers.AddTransfer("A", "C");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B", "C" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(105, result["B"]);
                Assert.Equal(0, result["C"]);
            }
            public void PackageWithOutgoingTransferRejectsIncomingTransfer()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 0);
                DownloadData.SetDownloadCount("C", "1.0.0", 0);

                DownloadChanges["A"] = 100;

                PopularityTransfers.AddTransfer("A", "B");
                PopularityTransfers.AddTransfer("A", "C");
                PopularityTransfers.AddTransfer("B", "C");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                // B has incoming and outgoing popularity transfers. It should reject the incoming transfer.
                Assert.Equal(new[] { "A", "B", "C" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(0, result["B"]);
                Assert.Equal(50, result["C"]);
            }
            public void OutgoingTransfersNewDownloads()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 20);
                DownloadData.SetDownloadCount("C", "1.0.0", 1);

                DownloadChanges["A"] = 100;

                PopularityTransfers.AddTransfer("A", "C");
                PopularityTransfers.AddTransfer("B", "C");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                // C receives downloads from A and B
                // A has download changes
                // B has no changes
                Assert.Equal(new[] { "A", "C" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(121, result["C"]);
            }
            public void UnknownPackagesTransferZeroDownloads()
            {
                PopularityTransfer = 1;

                PopularityTransfers.AddTransfer("A", "B");

                var result = Target.InitializeDownloadTransfers(
                    DownloadData,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(0, result["B"]);
            }
            public void PopularityTransferRoundsDown()
            {
                PopularityTransfer = 0.5;

                DownloadData.SetDownloadCount("A", "1.0.0", 3);
                DownloadData.SetDownloadCount("B", "1.0.0", 0);

                PopularityTransfers.AddTransfer("A", "B");

                var result = Target.InitializeDownloadTransfers(
                    DownloadData,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B" }, result.Keys);
                Assert.Equal(1, result["A"]);
                Assert.Equal(1, result["B"]);
            }
            public void DoesNothingIfNoChanges()
            {
                PopularityTransfer = 0.5;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);

                PopularityTransfers.AddTransfer("A", "B");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                Assert.Empty(result);
            }
            public void SupportsZeroPopularityTransfer()
            {
                PopularityTransfer = 0;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);

                PopularityTransfers.AddTransfer("A", "B");

                var result = Target.InitializeDownloadTransfers(
                    DownloadData,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B" }, result.Keys);
                Assert.Equal(100, result["A"]);
                Assert.Equal(5, result["B"]);
            }
            public void RejectsCyclicalPopularityTransfers()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 100);

                PopularityTransfers.AddTransfer("A", "B");
                PopularityTransfers.AddTransfer("B", "A");

                var result = Target.InitializeDownloadTransfers(
                    DownloadData,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(0, result["B"]);
            }
            public void SplitsPopularity()
            {
                PopularityTransfer = 0.5;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);
                DownloadData.SetDownloadCount("C", "1.0.0", 1);

                PopularityTransfers.AddTransfer("A", "B");
                PopularityTransfers.AddTransfer("A", "C");

                var result = Target.InitializeDownloadTransfers(
                    DownloadData,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B", "C" }, result.Keys);
                Assert.Equal(50, result["A"]);
                Assert.Equal(30, result["B"]);
                Assert.Equal(26, result["C"]);
            }
            public void AcceptsPopularityFromMultipleSources()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 20);
                DownloadData.SetDownloadCount("C", "1.0.0", 1);

                PopularityTransfers.AddTransfer("A", "C");
                PopularityTransfers.AddTransfer("B", "C");

                var result = Target.InitializeDownloadTransfers(
                    DownloadData,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B", "C" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(0, result["B"]);
                Assert.Equal(121, result["C"]);
            }
            public void NewOrUpdatedPopularityTransfer()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);

                PopularityTransfers.AddTransfer("A", "B");

                TransferChanges["A"] = new[] { "B" };

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(105, result["B"]);
            }
            public void IncomingTransfersAddedToNewDownloads()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);
                DownloadData.SetDownloadCount("C", "1.0.0", 0);

                DownloadChanges["B"] = 5;

                PopularityTransfers.AddTransfer("A", "B");
                PopularityTransfers.AddTransfer("A", "C");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                // B has new downloads and receives downloads from A.
                Assert.Equal(new[] { "B" }, result.Keys);
                Assert.Equal(55, result["B"]);
            }
            public void OutgoingTransfersSplitsNewDownloads()
            {
                PopularityTransfer = 1;

                DownloadData.SetDownloadCount("A", "1.0.0", 100);
                DownloadData.SetDownloadCount("B", "1.0.0", 5);
                DownloadData.SetDownloadCount("C", "1.0.0", 0);

                DownloadChanges["A"] = 100;

                PopularityTransfers.AddTransfer("A", "B");
                PopularityTransfers.AddTransfer("A", "C");

                var result = Target.UpdateDownloadTransfers(
                    DownloadData,
                    DownloadChanges,
                    OldTransfers,
                    PopularityTransfers);

                Assert.Equal(new[] { "A", "B", "C" }, result.Keys);
                Assert.Equal(0, result["A"]);
                Assert.Equal(55, result["B"]);
                Assert.Equal(50, result["C"]);
            }