public void When_a_download_is_failing_error_condition_shall_be_shown_instead_if_status()
        {
            TestPrerequisite[] TestPrerequisites = { new TestPrerequisite("Name1", false, false, "Down1"), new TestPrerequisite("Name2", false, false, "Down2") };

            InstallWindowModel Model = new InstallWindowModel(TestPrerequisites, (downloadId, progressCallback, downloadedCallback) => this.DownloadFunc(downloadId, progressCallback, downloadedCallback, TestPrerequisites.First(_ => _.DownloadId == downloadId)));

            Assert.That(Model.Status, Is.TypeOf <InstallWindowModel.PreperationStatus>());
            ((InstallWindowModel.PreperationStatus)Model.Status).SetUpSystemCommand.Execute(null);
            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus>(Model);
            ManualResetEvent StatusChangeEvent = new ManualResetEvent(false);

            Model.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == nameof(InstallWindowModel.Status))
                {
                    StatusChangeEvent.Set();
                }
            };


            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Installation, Is.TypeOf <InstallWindowModel.InstallationStatus.InstallationWaitingForDownloadStatus>());
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadingStatus>());

            TestPrerequisites[1].MarkDownloaded(false);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationErrorStatus>(Model);

            InstallWindowModel.StatusBase Status = Model.Status;
            //Shall not throw exception, but leave the status a-is
            TestPrerequisites[0].UpdateProgress(.5);
            TestPrerequisites[0].MarkDownloaded(true);

            Assert.That(Model.Status, Is.SameAs(Status));
        }
        public void When_install_of_a_prerequisite_fails_the_state_shall_move_into_error_status()
        {
            TestPrerequisite[] TestPrerequisites = { new TestPrerequisite("Name1", false, false, null) };
            InstallWindowModel Model             = new InstallWindowModel(TestPrerequisites, (downloadId, progressCallback, downloadedCallback) => this.DownloadFunc(downloadId, progressCallback, downloadedCallback, TestPrerequisites.First(_ => _.DownloadId == downloadId)));

            Assert.That(Model.Status, Is.TypeOf <InstallWindowModel.PreperationStatus>());
            ((InstallWindowModel.PreperationStatus)Model.Status).SetUpSystemCommand.Execute(null);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus>(Model);

            TestPrerequisites[0].MarkInstalled(false);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationErrorStatus>(Model);
            Assert.That(((InstallWindowModel.InstallationErrorStatus)Model.Status).Message, Is.EqualTo("Install FAIL!"));
        }
        public void When_administrative_rights_are_needded_those_prerequisites_shall_be_delegated_to_child_process_with_admin_rights()
        {
            TestPrerequisite[] TestPrerequisites = { new TestPrerequisite("Name1", true, false, null), new TestPrerequisite("Name2", false, false, null) };
            AdminProcess       AdminProcess      = new AdminProcess();
            InstallWindowModel Model             = new InstallWindowModel(TestPrerequisites, (downloadId, progressCallback, downloadedCallback) => this.DownloadFunc(downloadId, progressCallback, downloadedCallback, TestPrerequisites.First(_ => _.DownloadId == downloadId)), AdminProcess);

            Assert.That(Model.Status, Is.TypeOf <InstallWindowModel.PreperationStatus>());
            Assert.That(((InstallWindowModel.PreperationStatus)Model.Status).IsAdminRequired, Is.True);
            ((InstallWindowModel.PreperationStatus)Model.Status).SetUpSystemCommand.Execute(null);
            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus>(Model);

            AdminProcess.WaitInstallStarted();
            AdminProcess.MarkInstalled(true);

            TestPrerequisites[1].MarkInstalled(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationSuccessStatus>(Model);
        }
        public void When_download_is_needed_installation_shall_wait_but_if_download_is_finished_while_installation_happens_it_shall_continue_immediately()
        {
            TestPrerequisite[] TestPrerequisites = { new TestPrerequisite("Name1", false, false, "Down1"), new TestPrerequisite("Name2", false, false, "Down2") };

            InstallWindowModel Model = new InstallWindowModel(TestPrerequisites, (downloadId, progressCallback, downloadedCallback) => this.DownloadFunc(downloadId, progressCallback, downloadedCallback, TestPrerequisites.First(_ => _.DownloadId == downloadId)));

            Assert.That(Model.Status, Is.TypeOf <InstallWindowModel.PreperationStatus>());
            ((InstallWindowModel.PreperationStatus)Model.Status).SetUpSystemCommand.Execute(null);
            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus>(Model);
            ManualResetEvent StatusChangeEvent = new ManualResetEvent(false);

            Model.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == nameof(InstallWindowModel.Status))
                {
                    StatusChangeEvent.Set();
                }
            };


            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Installation, Is.TypeOf <InstallWindowModel.InstallationStatus.InstallationWaitingForDownloadStatus>());
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadingStatus>());

            TestPrerequisites[1].MarkDownloaded(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus.InstallingStatus>(Model);

            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).InstallationStatus, Is.EqualTo("Name2"));
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadingStatus>());

            TestPrerequisites[0].MarkDownloaded(true);
            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus.DownloadFinishedStatus>(Model);

            StatusChangeEvent.Reset();
            TestPrerequisites[1].MarkInstalled(true);
            StatusChangeEvent.WaitOne(TimeSpan.FromSeconds(10));

            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).InstallationStatus, Is.EqualTo("Name1"));
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadFinishedStatus>());

            TestPrerequisites[0].MarkInstalled(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationSuccessStatus>(Model);
        }
        public void When_download_is_needed_installation_shall_wait_but_first_downloaded_shall_be_installed_first()
        {
            TestPrerequisite[] TestPrerequisites = { new TestPrerequisite("Name1", false, false, "Down1"), new TestPrerequisite("Name2", false, false, "Down2") };

            InstallWindowModel Model = new InstallWindowModel(TestPrerequisites, (downloadId, progressCallback, downloadedCallback) => this.DownloadFunc(downloadId, progressCallback, downloadedCallback, TestPrerequisites.First(_ => _.DownloadId == downloadId)));

            Assert.That(Model.Status, Is.TypeOf <InstallWindowModel.PreperationStatus>());
            ((InstallWindowModel.PreperationStatus)Model.Status).SetUpSystemCommand.Execute(null);
            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus>(Model);

            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Installation, Is.TypeOf <InstallWindowModel.InstallationStatus.InstallationWaitingForDownloadStatus>());
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadingStatus>());

            TestPrerequisites[1].MarkDownloaded(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus.InstallingStatus>(Model);

            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).InstallationStatus, Is.EqualTo("Name2"));
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadingStatus>());
            Assert.That(((InstallWindowModel.InstallationStatus.DownloadingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Download).AcquiredPackages, Is.EqualTo(1));

            TestPrerequisites[1].MarkInstalled(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus.InstallationWaitingForDownloadStatus>(Model);

            TestPrerequisites[0].MarkDownloaded(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus.InstallingStatus>(Model);

            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).InstallationStatus, Is.EqualTo("Name1"));
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.TypeOf <InstallWindowModel.InstallationStatus.DownloadFinishedStatus>());

            TestPrerequisites[0].MarkInstalled(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationSuccessStatus>(Model);
        }
        public void When_Install_needed_without_download_installation_shall_begin_immediately_after_start()
        {
            TestPrerequisite[] TestPrerequisites = { new TestPrerequisite("Name1", false, false, null) };
            InstallWindowModel Model             = new InstallWindowModel(TestPrerequisites, (downloadId, progressCallback, downloadedCallback) => this.DownloadFunc(downloadId, progressCallback, downloadedCallback, TestPrerequisites.First(_ => _.DownloadId == downloadId)));

            Assert.That(Model.Status, Is.TypeOf <InstallWindowModel.PreperationStatus>());
            Assert.That(((InstallWindowModel.PreperationStatus)Model.Status).IsAdminRequired, Is.False);
            Assert.That(((InstallWindowModel.PreperationStatus)Model.Status).MissingSoftware.Length, Is.EqualTo(1));
            Assert.That(((InstallWindowModel.PreperationStatus)Model.Status).MissingSoftware[0], Is.EqualTo("Name1"));

            ((InstallWindowModel.PreperationStatus)Model.Status).SetUpSystemCommand.Execute(null);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationStatus>(Model);

            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Download, Is.Null);
            Assert.That(((InstallWindowModel.InstallationStatus)Model.Status).Installation, Is.TypeOf <InstallWindowModel.InstallationStatus.InstallingStatus>());
            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).NumberOfPackagesToInstall, Is.EqualTo(1));
            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).InstalledPackages, Is.EqualTo(0));
            Assert.That(((InstallWindowModel.InstallationStatus.InstallingStatus)((InstallWindowModel.InstallationStatus)Model.Status).Installation).InstallationStatus, Is.EqualTo("Name1"));

            TestPrerequisites[0].MarkInstalled(true);

            InstallWindowModelTest.WaitForStateChange <InstallWindowModel.InstallationSuccessStatus>(Model);
        }