Inheritance: TemporaryDirectory
        public void TestAddAccessPoints()
        {
            var capabilityList = CapabilityListTest.CreateTestCapabilityList();
            var feed1 = new Feed {Name = "Test", CapabilityLists = {capabilityList}};
            var feed2 = new Feed {Name = "Test", CapabilityLists = {capabilityList}};
            using (var applyFlag1 = new TemporaryFlagFile("0install-unit-tests"))
            using (var applyFlag2 = new TemporaryFlagFile("0install-unit-tests"))
            {
                var accessPoints1 = new AccessPoint[] {new MockAccessPoint {ID = "id1", Capability = "my_ext1", ApplyFlagPath = applyFlag1}};
                var accessPoints2 = new AccessPoint[] {new MockAccessPoint {ID = "id2", Capability = "my_ext2", ApplyFlagPath = applyFlag2}};

                Assert.AreEqual(0, _integrationManager.AppList.Entries.Count);
                var appEntry1 = _integrationManager.AddApp(new FeedTarget(FeedTest.Test1Uri, feed1));
                _integrationManager.AddAccessPoints(appEntry1, feed1, accessPoints1);
                Assert.AreEqual(1, _integrationManager.AppList.Entries.Count, "Should implicitly create missing AppEntries");
                Assert.IsTrue(applyFlag1.Set, "Should apply AccessPoint");
                applyFlag1.Set = false;

                Assert.DoesNotThrow(() => _integrationManager.AddAccessPoints(appEntry1, feed1, accessPoints1), "Duplicate access points should be silently reapplied");
                Assert.IsTrue(applyFlag1.Set, "Duplicate access points should be silently reapplied");

                _integrationManager.AddAccessPoints(appEntry1, feed1, accessPoints2);
                applyFlag2.Set = false;

                var appEntry2 = _integrationManager.AddApp(new FeedTarget(FeedTest.Test2Uri, feed2));
                Assert.Throws<ConflictException>(() => _integrationManager.AddAccessPoints(appEntry2, feed2, accessPoints2), "Should prevent access point conflicts");
                Assert.IsFalse(applyFlag2.Set, "Should prevent access point conflicts");
            }
        }
        public void TestRemoveApp()
        {
            var target = new FeedTarget(FeedTest.Test1Uri, new Feed {Name = "Test"});
            var appEntry = _integrationManager.AddApp(target);

            // Inject access point into AppEntry (without running integration)
            using (var unapplyFlag = new TemporaryFlagFile("0install-unit-tests"))
            {
                appEntry.AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {UnapplyFlagPath = unapplyFlag}}};

                _integrationManager.RemoveApp(appEntry);
                _integrationManager.AppList.Entries.Should().BeEmpty();

                unapplyFlag.Set.Should().BeTrue(because: "Access points should be unapplied when their AppEntry is removed");
                _integrationManager.Invoking(x => x.RemoveApp(appEntry))
                    .ShouldNotThrow(because: "Allow multiple removals of applications.");
            }
        }
        public void TestAddedLocal()
        {
            using (var apApplied = new TemporaryFlagFile("ap-applied"))
            using (var apUnapplied = new TemporaryFlagFile("ap-unapplied"))
            {
                var appListLocal = new AppList
                {
                    Entries =
                    {
                        new AppEntry
                        {
                            InterfaceUri = FeedTest.Test1Uri,
                            AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = apApplied, UnapplyFlagPath = apUnapplied}}}
                        }
                    }
                };

                TestSync(SyncResetMode.None, appListLocal, new AppList(), new AppList());

                Assert.IsFalse(apApplied.Set, "Locally existing access point should not be reapplied");
                Assert.IsFalse(apUnapplied.Set, "Locally existing access point should not be removed");
            }
        }
        public void TestRemovedLocal()
        {
            using (var apApplied = new TemporaryFlagFile("ap-applied"))
            using (var apUnapplied = new TemporaryFlagFile("ap-unapplied"))
            {
                var appListServer = new AppList
                {
                    Entries =
                    {
                        new AppEntry
                        {
                            InterfaceUri = FeedTest.Test1Uri,
                            AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = apApplied, UnapplyFlagPath = apUnapplied}}}
                        }
                    }
                };

                TestSync(SyncResetMode.None, new AppList(), appListServer.Clone(), appListServer);

                apApplied.Set.Should().BeFalse(because: "Locally removed access point should not be reapplied");
                apUnapplied.Set.Should().BeFalse(because: "Locally removed access point should not be unapplied again");
            }
        }
        public void TestAddedRemote()
        {
            using (var apApplied = new TemporaryFlagFile("ap-applied"))
            using (var apUnapplied = new TemporaryFlagFile("ap-unapplied"))
            {
                var appListRemote = new AppList
                {
                    Entries =
                    {
                        new AppEntry
                        {
                            InterfaceUri = FeedTest.Test1Uri,
                            AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = apApplied, UnapplyFlagPath = apUnapplied}, new MockAccessPoint()}}
                        }
                    }
                };

                TestSync(SyncResetMode.None, new AppList(), new AppList(), appListRemote);

                Assert.IsTrue(apApplied.Set, "New access point should be applied");
                Assert.IsFalse(apUnapplied.Set, "New access point should not be unapplied");
            }
        }
        /// <summary>
        /// Tests the sync logic with pre-defined <see cref="AppList"/>s.
        /// local add: appEntry1, local remove: appEntry2, remote add: appEntry3, remote remove: appEntry4
        /// </summary>
        /// <param name="resetMode">The <see cref="SyncResetMode"/> to pass to <see cref="SyncIntegrationManager.Sync"/>.</param>
        /// <param name="ap1Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry1.</param>
        /// <param name="ap1Unapplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry1.</param>
        /// <param name="ap2Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry2.</param>
        /// <param name="ap2Unapplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry2.</param>
        /// <param name="ap3Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry3.</param>
        /// <param name="ap3Unapplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry3.</param>
        /// <param name="ap4Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry4.</param>
        /// <param name="ap4Unapplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry4.</param>
        private void TestSync(SyncResetMode resetMode,
            TemporaryFlagFile ap1Applied, TemporaryFlagFile ap1Unapplied,
            TemporaryFlagFile ap2Applied, TemporaryFlagFile ap2Unapplied,
            TemporaryFlagFile ap3Applied, TemporaryFlagFile ap3Unapplied,
            TemporaryFlagFile ap4Applied, TemporaryFlagFile ap4Unapplied)
        {
            var appEntry1 = new AppEntry
            {
                InterfaceUri = FeedTest.Test1Uri,
                AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = ap1Applied, UnapplyFlagPath = ap1Unapplied}}}
            };
            var appEntry2 = new AppEntry
            {
                InterfaceUri = FeedTest.Test2Uri,
                AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = ap2Applied, UnapplyFlagPath = ap2Unapplied}}}
            };
            var appEntry3 = new AppEntry
            {
                InterfaceUri = FeedTest.Test3Uri,
                AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = ap3Applied, UnapplyFlagPath = ap3Unapplied}}}
            };
            var appEntry4 = new AppEntry
            {
                InterfaceUri = new FeedUri("http://0install.de/feeds/test/test4.xml"),
                AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = ap4Applied, UnapplyFlagPath = ap4Unapplied}}}
            };
            var appListLocal = new AppList {Entries = {appEntry1, appEntry4}};
            var appListLast = new AppList {Entries = {appEntry2, appEntry4}};
            var appListServer = new AppList {Entries = {appEntry2, appEntry3}};

            TestSync(resetMode, appListLocal, appListLast, appListServer);
        }
 public void TestResetServer()
 {
     using (var ap1Applied = new TemporaryFlagFile("ap1-applied"))
     using (var ap1Unapplied = new TemporaryFlagFile("ap1-unapplied"))
     using (var ap2Applied = new TemporaryFlagFile("ap2-applied"))
     using (var ap2Unapplied = new TemporaryFlagFile("ap2-unapplied"))
     using (var ap3Applied = new TemporaryFlagFile("ap3-applied"))
     using (var ap3Unapplied = new TemporaryFlagFile("ap3-unapplied"))
     using (var ap4Applied = new TemporaryFlagFile("ap4-applied"))
     using (var ap4Unapplied = new TemporaryFlagFile("ap4-unapplied"))
     {
         TestSync(SyncResetMode.Server, ap1Applied, ap1Unapplied, ap2Applied, ap2Unapplied, ap3Applied, ap3Unapplied, ap4Applied, ap4Unapplied);
         Assert.IsFalse(ap1Applied.Set);
         Assert.IsFalse(ap1Unapplied.Set);
         Assert.IsFalse(ap2Applied.Set);
         Assert.IsFalse(ap2Unapplied.Set);
         Assert.IsFalse(ap3Applied.Set);
         Assert.IsFalse(ap3Unapplied.Set);
         Assert.IsFalse(ap4Applied.Set);
         Assert.IsFalse(ap4Unapplied.Set);
     }
 }
 public void TestResetClient()
 {
     using (var ap1Applied = new TemporaryFlagFile("ap1-applied"))
     using (var ap1Unapplied = new TemporaryFlagFile("ap1-unapplied"))
     using (var ap2Applied = new TemporaryFlagFile("ap2-applied"))
     using (var ap2Unapplied = new TemporaryFlagFile("ap2-unapplied"))
     using (var ap3Applied = new TemporaryFlagFile("ap3-applied"))
     using (var ap3Unapplied = new TemporaryFlagFile("ap3-unapplied"))
     using (var ap4Applied = new TemporaryFlagFile("ap4-applied"))
     using (var ap4Unapplied = new TemporaryFlagFile("ap4-unapplied"))
     {
         TestSync(SyncResetMode.Client, ap1Applied, ap1Unapplied, ap2Applied, ap2Unapplied, ap3Applied, ap3Unapplied, ap4Applied, ap4Unapplied);
         Assert.IsFalse(ap1Applied.Set);
         Assert.IsTrue(ap1Unapplied.Set, "undo: local add: appEntry1");
         Assert.IsTrue(ap2Applied.Set, "undo: local remove: appEntry2");
         Assert.IsFalse(ap2Unapplied.Set);
         Assert.IsTrue(ap3Applied.Set, "remote add: appEntry3");
         Assert.IsFalse(ap3Unapplied.Set);
         Assert.IsFalse(ap4Applied.Set);
         Assert.IsTrue(ap4Unapplied.Set, "remote remove: appEntry4");
     }
 }
        public void TestModifiedRemote()
        {
            using (var apLocalApplied = new TemporaryFlagFile("ap-local-applied"))
            using (var apLocalUnapplied = new TemporaryFlagFile("ap-local-unapplied"))
            using (var apRemoteApplied = new TemporaryFlagFile("ap-remote-applied"))
            using (var apRemoteUnapplied = new TemporaryFlagFile("ap-remote-unapplied"))
            {
                var appListLocal = new AppList
                {
                    Entries =
                    {
                        new AppEntry
                        {
                            InterfaceUri = FeedTest.Test1Uri, AutoUpdate = true, Timestamp = new DateTime(2000, 1, 1),
                            AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = apLocalApplied, UnapplyFlagPath = apLocalUnapplied}}}
                        }
                    }
                };

                var appListServer = new AppList
                {
                    Entries =
                    {
                        new AppEntry
                        {
                            InterfaceUri = FeedTest.Test1Uri, AutoUpdate = false, Timestamp = new DateTime(2001, 1, 1),
                            AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = apRemoteApplied, UnapplyFlagPath = apRemoteUnapplied}}}
                        }
                    }
                };

                TestSync(SyncResetMode.None, appListLocal, null, appListServer);

                Assert.IsFalse(apLocalApplied.Set, "Outdated access point should not be reapplied");
                Assert.IsTrue(apLocalUnapplied.Set, "Outdated access point should be removed");
                Assert.IsTrue(apRemoteApplied.Set, "New access point should be applied");
                Assert.IsFalse(apRemoteUnapplied.Set, "New access point should not be unapplied");
            }
        }
        public void TestRepair()
        {
            var target = new FeedTarget(FeedTest.Test1Uri, new Feed {Name = "Test"});
            var appEntry = _integrationManager.AddApp(target);

            using (var applyFlag = new TemporaryFlagFile("0install-unit-tests"))
            {
                // Inject access point into AppEntry (without running integration)
                appEntry.AccessPoints = new AccessPointList {Entries = {new MockAccessPoint {ApplyFlagPath = applyFlag}}};
                _integrationManager.Repair(uri => new Feed());

                Assert.IsTrue(applyFlag.Set, "Access points should be reapplied");
            }
        }
        public void TestRemoveAccessPoints()
        {
            var capabilityList = CapabilityListTest.CreateTestCapabilityList();
            var testApp = new Feed {Name = "Test", CapabilityLists = {capabilityList}};

            using (var unapplyFlag = new TemporaryFlagFile("0install-unit-tests"))
            {
                var accessPoint = new MockAccessPoint {ID = "id1", Capability = "my_ext1", UnapplyFlagPath = unapplyFlag};

                // Inject access point into AppEntry (without running integration)
                var appEntry = _integrationManager.AddApp(new FeedTarget(FeedTest.Test1Uri, testApp));
                appEntry.AccessPoints = new AccessPointList {Entries = {accessPoint}};

                _integrationManager.RemoveAccessPoints(appEntry, new[] {accessPoint});
                Assert.IsEmpty(_integrationManager.AppList.Entries[0].AccessPoints.Entries);

                Assert.IsTrue(unapplyFlag.Set, "Unapply() should be called");

                Assert.DoesNotThrow(() => _integrationManager.RemoveAccessPoints(appEntry, new[] {accessPoint}), "Allow multiple removals of access points.");
            }
        }
 public void TestResetClient()
 {
     using (var ap1Applied = new TemporaryFlagFile("ap1-applied"))
     using (var ap1Unapplied = new TemporaryFlagFile("ap1-unapplied"))
     using (var ap2Applied = new TemporaryFlagFile("ap2-applied"))
     using (var ap2Unapplied = new TemporaryFlagFile("ap2-unapplied"))
     using (var ap3Applied = new TemporaryFlagFile("ap3-applied"))
     using (var ap3Unapplied = new TemporaryFlagFile("ap3-unapplied"))
     using (var ap4Applied = new TemporaryFlagFile("ap4-applied"))
     using (var ap4Unapplied = new TemporaryFlagFile("ap4-unapplied"))
     {
         TestSync(SyncResetMode.Client, ap1Applied, ap1Unapplied, ap2Applied, ap2Unapplied, ap3Applied, ap3Unapplied, ap4Applied, ap4Unapplied);
         ap1Applied.Set.Should().BeFalse();
         ap1Unapplied.Set.Should().BeTrue(because: "undo: local add: appEntry1");
         ap2Applied.Set.Should().BeTrue(because: "undo: local remove: appEntry2");
         ap2Unapplied.Set.Should().BeFalse();
         ap3Applied.Set.Should().BeTrue(because: "remote add: appEntry3");
         ap3Unapplied.Set.Should().BeFalse();
         ap4Applied.Set.Should().BeFalse();
         ap4Unapplied.Set.Should().BeTrue(because: "remote remove: appEntry4");
     }
 }
        public void TestAddAccessPoints()
        {
            var capabilityList = CapabilityListTest.CreateTestCapabilityList();
            var feed1 = new Feed {Name = "Test", CapabilityLists = {capabilityList}};
            var feed2 = new Feed {Name = "Test", CapabilityLists = {capabilityList}};
            using (var applyFlag1 = new TemporaryFlagFile("0install-unit-tests"))
            using (var applyFlag2 = new TemporaryFlagFile("0install-unit-tests"))
            {
                var accessPoints1 = new AccessPoint[] {new MockAccessPoint {ID = "id1", Capability = "my_ext1", ApplyFlagPath = applyFlag1}};
                var accessPoints2 = new AccessPoint[] {new MockAccessPoint {ID = "id2", Capability = "my_ext2", ApplyFlagPath = applyFlag2}};

                _integrationManager.AppList.Entries.Count.Should().Be(0);
                var appEntry1 = _integrationManager.AddApp(new FeedTarget(FeedTest.Test1Uri, feed1));
                _integrationManager.AddAccessPoints(appEntry1, feed1, accessPoints1);
                _integrationManager.AppList.Entries.Count.Should().Be(1, because: "Should implicitly create missing AppEntries");
                applyFlag1.Set.Should().BeTrue(because: "Should apply AccessPoint");
                applyFlag1.Set = false;

                _integrationManager.Invoking(x => x.AddAccessPoints(appEntry1, feed1, accessPoints1))
                    .ShouldNotThrow(because: "Duplicate access points should be silently reapplied");
                applyFlag1.Set.Should().BeTrue(because: "Duplicate access points should be silently reapplied");

                _integrationManager.AddAccessPoints(appEntry1, feed1, accessPoints2);
                applyFlag2.Set = false;

                var appEntry2 = _integrationManager.AddApp(new FeedTarget(FeedTest.Test2Uri, feed2));
                _integrationManager.Invoking(x => x.AddAccessPoints(appEntry2, feed2, accessPoints2))
                    .ShouldThrow<ConflictException>(because: "Should prevent access point conflicts");
                applyFlag2.Set.Should().BeFalse(because: "Should prevent access point conflicts");
            }
        }