Selenium Tests
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
namespace Duplicati.Library.RestAPI.Abstractions;
|
||||
|
||||
public interface IModernHttpRequestAccess
|
||||
{
|
||||
public string GetQueryParam(string name);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using Duplicati.Server.Serialization.Interface;
|
||||
using Duplicati.Library.RestAPI;
|
||||
using Duplicati.Library.RestAPI.Abstractions;
|
||||
|
||||
namespace Duplicati.Server.WebServer.RESTMethods
|
||||
{
|
||||
@@ -636,7 +637,7 @@ namespace Duplicati.Server.WebServer.RESTMethods
|
||||
return;
|
||||
}
|
||||
|
||||
var delete_remote_files = Library.Utility.Utility.ParseBool(info.Request.Param["delete-remote-files"].Value, false);
|
||||
var delete_remote_files = info.Request is IModernHttpRequestAccess request && Library.Utility.Utility.ParseBool(request.GetQueryParam("delete-remote-files"), false);
|
||||
|
||||
if (delete_remote_files)
|
||||
{
|
||||
|
||||
@@ -224,8 +224,19 @@ namespace Duplicati.Server.WebServer.RESTMethods
|
||||
{
|
||||
string url;
|
||||
|
||||
using(var sr = new System.IO.StreamReader(info.Request.Body, System.Text.Encoding.UTF8, true))
|
||||
url = sr.ReadToEnd();
|
||||
using (var sr = new System.IO.StreamReader(info.Request.Body, System.Text.Encoding.UTF8, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
url = sr.ReadToEnd();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
url = sr.ReadLineAsync().Result;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine(url);
|
||||
|
||||
switch (key)
|
||||
{
|
||||
|
||||
@@ -1,50 +1,133 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Edge;
|
||||
|
||||
namespace Duplicati.Browser.Test.Drivers
|
||||
namespace Duplicati.Browser.Test.Drivers;
|
||||
|
||||
/// <summary>
|
||||
/// Manages a browser instance using Selenium
|
||||
/// </summary>
|
||||
public class BrowserDriver : IDisposable
|
||||
{
|
||||
private readonly Lazy<IWebDriver> _currentWebDriverLazy = new(CreateWebDriver);
|
||||
private bool _isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Manages a browser instance using Selenium
|
||||
/// The Selenium IWebDriver instance
|
||||
/// </summary>
|
||||
public class BrowserDriver : IDisposable
|
||||
public IWebDriver Current => _currentWebDriverLazy.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the Selenium web driver (opens a browser)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static EdgeDriver CreateWebDriver()
|
||||
{
|
||||
private readonly Lazy<IWebDriver> _currentWebDriverLazy = new(CreateWebDriver);
|
||||
private bool _isDisposed;
|
||||
//We use the Chrome browser
|
||||
var chromeDriverService = EdgeDriverService.CreateDefaultService(".", "msedgedriver");
|
||||
|
||||
/// <summary>
|
||||
/// The Selenium IWebDriver instance
|
||||
/// </summary>
|
||||
public IWebDriver Current => _currentWebDriverLazy.Value;
|
||||
return new EdgeDriver(chromeDriverService, new EdgeOptions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the Selenium web driver (opens a browser)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static EdgeDriver CreateWebDriver()
|
||||
/// <summary>
|
||||
/// Disposes the Selenium web driver (closing the browser)
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_isDisposed)
|
||||
{
|
||||
//We use the Chrome browser
|
||||
var chromeDriverService = EdgeDriverService.CreateDefaultService(".", "msedgedriver");
|
||||
|
||||
return new EdgeDriver(chromeDriverService, new EdgeOptions());
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the Selenium web driver (closing the browser)
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
if (_currentWebDriverLazy.IsValueCreated)
|
||||
{
|
||||
if (_isDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentWebDriverLazy.IsValueCreated)
|
||||
{
|
||||
Current.Quit();
|
||||
}
|
||||
|
||||
_isDisposed = true;
|
||||
Current.Quit();
|
||||
}
|
||||
|
||||
_isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DriverExtensions
|
||||
{
|
||||
public static int SingleLoopWait = 100;
|
||||
public static TimeSpan DefaultMaxWait = TimeSpan.FromSeconds(30);
|
||||
|
||||
public static IWebElement WaitForElement(this ISearchContext driver, By selector, TimeSpan? maxWait = null)
|
||||
{
|
||||
maxWait ??= DefaultMaxWait;
|
||||
var i = 0;
|
||||
while (i < maxWait.Value.TotalMilliseconds)
|
||||
{
|
||||
try
|
||||
{
|
||||
return driver.FindElement(selector);
|
||||
}
|
||||
catch (NoSuchElementException)
|
||||
{
|
||||
//swallow and wait for another loop
|
||||
}
|
||||
|
||||
i += SingleLoopWait;
|
||||
Thread.Sleep(TimeSpan.FromMilliseconds(SingleLoopWait));
|
||||
}
|
||||
|
||||
return driver.FindElement(selector);
|
||||
}
|
||||
|
||||
public static bool WaitForElementBeing(this IWebElement element, Func<IWebElement, bool> predicate,
|
||||
TimeSpan? maxWait = null)
|
||||
{
|
||||
maxWait ??= DefaultMaxWait;
|
||||
var i = 0;
|
||||
while (i < maxWait.Value.TotalMilliseconds)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (predicate.Invoke(element))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (NoSuchElementException)
|
||||
{
|
||||
//swallow and wait for another loop
|
||||
}
|
||||
|
||||
i += SingleLoopWait;
|
||||
Thread.Sleep(TimeSpan.FromMilliseconds(SingleLoopWait));
|
||||
}
|
||||
|
||||
throw new Exception($"Timout of waiting for element to satisfy predicate: {predicate}!");
|
||||
}
|
||||
|
||||
public static void SendKeysAndCheck(this IWebElement element, string text, TimeSpan? maxWait = null)
|
||||
{
|
||||
maxWait ??= DefaultMaxWait;
|
||||
var i = 0;
|
||||
while (i < maxWait.Value.TotalMilliseconds)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (element.GetAttribute("value") != text)
|
||||
{
|
||||
element.SendKeys(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (NoSuchElementException)
|
||||
{
|
||||
//swallow and wait for another loop
|
||||
}
|
||||
|
||||
i += SingleLoopWait;
|
||||
Thread.Sleep(TimeSpan.FromMilliseconds(SingleLoopWait));
|
||||
}
|
||||
|
||||
throw new Exception("Could not set text value of element!");
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,12 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Drivers\" />
|
||||
<Folder Include="test-backup-source\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="msedgedriver">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@ Link to a feature: [Calculator](Duplicati.Browser.Test/Features/LocalBackup.feat
|
||||
***Further read***: **[Learn more about how to generate Living Documentation](https://docs.specflow.org/projects/specflow-livingdoc/en/latest/LivingDocGenerator/Generating-Documentation.html)**
|
||||
|
||||
Scenario: Configure Backup
|
||||
Given the first number is 50
|
||||
And the second number is 70
|
||||
When the two numbers are added
|
||||
Given there is local backup defined
|
||||
When you run the backup
|
||||
Then the result should be 120
|
||||
|
||||
|
||||
|
||||
@@ -105,15 +105,12 @@ this.ScenarioInitialize(scenarioInfo);
|
||||
{
|
||||
this.ScenarioStart();
|
||||
#line 7
|
||||
testRunner.Given("the first number is 50", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
|
||||
testRunner.Given("there is local backup defined", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
|
||||
#line hidden
|
||||
#line 8
|
||||
testRunner.And("the second number is 70", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
|
||||
testRunner.When("you run the backup", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
|
||||
#line hidden
|
||||
#line 9
|
||||
testRunner.When("the two numbers are added", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
|
||||
#line hidden
|
||||
#line 10
|
||||
testRunner.Then("the result should be 120", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
|
||||
#line hidden
|
||||
}
|
||||
@@ -133,7 +130,7 @@ this.ScenarioInitialize(scenarioInfo);
|
||||
argumentsOfScenario.Add("Second number", secondNumber);
|
||||
argumentsOfScenario.Add("Expected result", expectedResult);
|
||||
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Add two numbers permutations", null, tagsOfScenario, argumentsOfScenario, this._featureTags);
|
||||
#line 13
|
||||
#line 12
|
||||
this.ScenarioInitialize(scenarioInfo);
|
||||
#line hidden
|
||||
bool isScenarioIgnored = default(bool);
|
||||
@@ -153,16 +150,16 @@ this.ScenarioInitialize(scenarioInfo);
|
||||
else
|
||||
{
|
||||
this.ScenarioStart();
|
||||
#line 14
|
||||
#line 13
|
||||
testRunner.Given(string.Format("the first number is {0}", firstNumber), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
|
||||
#line hidden
|
||||
#line 15
|
||||
#line 14
|
||||
testRunner.And(string.Format("the second number is {0}", secondNumber), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
|
||||
#line hidden
|
||||
#line 16
|
||||
#line 15
|
||||
testRunner.When("the two numbers are added", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
|
||||
#line hidden
|
||||
#line 17
|
||||
#line 16
|
||||
testRunner.Then(string.Format("the result should be {0}", expectedResult), ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
|
||||
#line hidden
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
using System.Threading;
|
||||
using Duplicati.Browser.Test.Drivers;
|
||||
using OpenQA.Selenium;
|
||||
|
||||
namespace Duplicati.Browser.Test.PageObjects;
|
||||
|
||||
public class AddBackupPage(IWebDriver webDriver)
|
||||
{
|
||||
private IWebElement NextButtonElement => webDriver.WaitForElement(By.ClassName("submit"));
|
||||
|
||||
public GeneralBackupSettingsPage ToGeneralSettings()
|
||||
{
|
||||
NextButtonElement.Click();
|
||||
|
||||
return new GeneralBackupSettingsPage(webDriver);
|
||||
}
|
||||
}
|
||||
|
||||
public class GeneralBackupSettingsPage(IWebDriver webDriver)
|
||||
{
|
||||
private IWebElement NameTextboxElement => webDriver.WaitForElement(By.Id("name"));
|
||||
private IWebElement NextButtonElement => webDriver.WaitForElement(By.ClassName("submit"));
|
||||
private IWebElement GeneratePasswordLink => webDriver.WaitForElement(By.PartialLinkText("Generuj"));
|
||||
|
||||
public GeneralBackupSettingsPage SetName(string name)
|
||||
{
|
||||
if (NameTextboxElement.WaitForElementBeing(e => e.GetAttribute("placeholder") is "Moje Zdjęcia" or "My Photos"))
|
||||
{
|
||||
NameTextboxElement.Clear();
|
||||
NameTextboxElement.SendKeysAndCheck(name);
|
||||
Thread.Sleep(1000);
|
||||
NameTextboxElement.SendKeysAndCheck(name);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeneralBackupSettingsPage GenerateRandomPassword()
|
||||
{
|
||||
GeneratePasswordLink.Click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public BackupTargetSettingsPage ToBackupTarget()
|
||||
{
|
||||
NextButtonElement.Click();
|
||||
|
||||
return new BackupTargetSettingsPage(webDriver);
|
||||
}
|
||||
}
|
||||
|
||||
public class BackupTargetSettingsPage(IWebDriver webDriver)
|
||||
{
|
||||
private IWebElement NextButtonElement => webDriver.WaitForElement(By.CssSelector("#nextStep2.submit"));
|
||||
private IWebElement ManualPathLink => webDriver.WaitForElement(By.LinkText("Podaj ścieżkę ręcznie"));
|
||||
private IWebElement FilePathTextbox => webDriver.WaitForElement(By.Id("file_path"));
|
||||
|
||||
public BackupTargetSettingsPage ChoosePathManually()
|
||||
{
|
||||
ManualPathLink.Click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public BackupTargetSettingsPage SetManualPath(string path)
|
||||
{
|
||||
if (FilePathTextbox.WaitForElementBeing(e => e.GetAttribute("placeholder") is "Wprowadź ścieżkę docelową"))
|
||||
{
|
||||
FilePathTextbox.Clear();
|
||||
FilePathTextbox.SendKeysAndCheck(path);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public BackupSourceSettingsPage ToBackupSource()
|
||||
{
|
||||
NextButtonElement.Click();
|
||||
|
||||
return new BackupSourceSettingsPage(webDriver);
|
||||
}
|
||||
}
|
||||
|
||||
public class BackupSourceSettingsPage(IWebDriver webDriver)
|
||||
{
|
||||
private IWebElement NextButtonElement => webDriver.WaitForElement(By.CssSelector("#nextStep3.submit"));
|
||||
private IWebElement FilePathTextbox => webDriver.WaitForElement(By.Id("sourcePath"));
|
||||
private IWebElement AddFilePathButton => webDriver.WaitForElement(By.Id("sourceFolderPathAdd"));
|
||||
private IWebElement ConfirmAddPathButton => webDriver.WaitForElement(By.PartialLinkText("Tak"));
|
||||
|
||||
public BackupSourceSettingsPage AddSourceManually(string path)
|
||||
{
|
||||
if (FilePathTextbox.WaitForElementBeing(e => e.GetAttribute("placeholder") is "Dodaj ścieżkę bezpośrednio"))
|
||||
{
|
||||
FilePathTextbox.Clear();
|
||||
FilePathTextbox.SendKeysAndCheck(path);
|
||||
}
|
||||
AddFilePathButton.Click();
|
||||
ConfirmAddPathButton.Click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScheduleSettingsPage ToSchedule()
|
||||
{
|
||||
Thread.Sleep(20000);
|
||||
NextButtonElement.Click();
|
||||
|
||||
return new ScheduleSettingsPage(webDriver);
|
||||
}
|
||||
}
|
||||
|
||||
public class ScheduleSettingsPage(IWebDriver webDriver)
|
||||
{
|
||||
private IWebElement NextButtonElement => webDriver.WaitForElement(By.CssSelector("#nextStep4.submit"));
|
||||
private IWebElement AutoRunCheckbox => webDriver.WaitForElement(By.Id("useScheduleRun"));
|
||||
|
||||
public ScheduleSettingsPage DisableAutorun()
|
||||
{
|
||||
if (AutoRunCheckbox.Selected)
|
||||
{
|
||||
AutoRunCheckbox.Click();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ToOptionsSettingsPage ToOptions()
|
||||
{
|
||||
NextButtonElement.Click();
|
||||
|
||||
return new ToOptionsSettingsPage(webDriver);
|
||||
}
|
||||
}
|
||||
|
||||
public class ToOptionsSettingsPage(IWebDriver webDriver)
|
||||
{
|
||||
private IWebElement SaveButtonElement => webDriver.WaitForElement(By.CssSelector("#save"));
|
||||
|
||||
public ToOptionsSettingsPage Save()
|
||||
{
|
||||
SaveButtonElement.Click();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Duplicati.Browser.Test.Drivers;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
|
||||
@@ -18,23 +19,15 @@ namespace Duplicati.Browser.Test.PageObjects
|
||||
public const int DefaultWaitInSeconds = 5;
|
||||
|
||||
//Finding elements by ID
|
||||
private IWebElement AddBackupElement => webDriver.FindElement(By.ClassName("add"));
|
||||
private IWebElement SecondNumberElement => webDriver.FindElement(By.Id("second-number"));
|
||||
private IWebElement AddButtonElement => webDriver.FindElement(By.Id("add-button"));
|
||||
private IWebElement ResultElement => webDriver.FindElement(By.Id("result"));
|
||||
private IWebElement ResetButtonElement => webDriver.FindElement(By.Id("reset-button"));
|
||||
private IWebElement AddBackupElement => webDriver.WaitForElement(By.ClassName("add"));
|
||||
private IWebElement AddButtonElement => webDriver.WaitForElement(By.Id("add-button"));
|
||||
private IWebElement ResultElement => webDriver.WaitForElement(By.Id("result"));
|
||||
private IWebElement ResetButtonElement => webDriver.WaitForElement(By.Id("reset-button"));
|
||||
|
||||
public void NavigateToBackupCreation()
|
||||
public AddBackupPage NavigateToBackupCreation()
|
||||
{
|
||||
AddBackupElement.Click();
|
||||
}
|
||||
|
||||
public void EnterSecondNumber(string number)
|
||||
{
|
||||
//Clear text box
|
||||
SecondNumberElement.Clear();
|
||||
//Enter text
|
||||
SecondNumberElement.SendKeys(number);
|
||||
return new AddBackupPage(webDriver);
|
||||
}
|
||||
|
||||
public void ClickAdd()
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Duplicati.Browser.Test.Drivers;
|
||||
using System.IO;
|
||||
using Duplicati.Browser.Test.Drivers;
|
||||
using Duplicati.Browser.Test.PageObjects;
|
||||
using FluentAssertions;
|
||||
using OpenQA.Selenium.Support.Extensions;
|
||||
using TechTalk.SpecFlow;
|
||||
|
||||
namespace Duplicati.Browser.Test.Steps
|
||||
@@ -11,22 +13,29 @@ namespace Duplicati.Browser.Test.Steps
|
||||
//Page Object for Calculator
|
||||
private readonly DuplicatiPageObject _duplicatiPageObject = new(browserDriver.Current);
|
||||
|
||||
[Given("the first number is (.*)")]
|
||||
public void GivenTheFirstNumberIs(int number)
|
||||
[Given("there is local backup defined")]
|
||||
public void GivenLocalBackupDefined()
|
||||
{
|
||||
browserDriver.Current.TakeScreenshot();
|
||||
//delegate to Page Object
|
||||
_duplicatiPageObject.NavigateToBackupCreation();
|
||||
_duplicatiPageObject.NavigateToBackupCreation()
|
||||
.ToGeneralSettings()
|
||||
.SetName("Local Backup")
|
||||
.GenerateRandomPassword()
|
||||
.ToBackupTarget()
|
||||
.ChoosePathManually()
|
||||
.SetManualPath(Path.Combine(Directory.GetCurrentDirectory(), "test-backup-target"))
|
||||
.ToBackupSource()
|
||||
.AddSourceManually(Path.Combine(Directory.GetCurrentDirectory(), "test-backup-source")+"/")
|
||||
.ToSchedule()
|
||||
.DisableAutorun()
|
||||
.ToOptions()
|
||||
.Save()
|
||||
;
|
||||
}
|
||||
|
||||
[Given("the second number is (.*)")]
|
||||
public void GivenTheSecondNumberIs(int number)
|
||||
{
|
||||
//delegate to Page Object
|
||||
_duplicatiPageObject.EnterSecondNumber(number.ToString());
|
||||
}
|
||||
|
||||
[When("the two numbers are added")]
|
||||
public void WhenTheTwoNumbersAreAdded()
|
||||
[When("you run the backup")]
|
||||
public void WhenBackupIsRun()
|
||||
{
|
||||
//delegate to Page Object
|
||||
_duplicatiPageObject.ClickAdd();
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Duplicati.Library.AutoUpdater;
|
||||
|
||||
public interface IUpdateManagerAccessor
|
||||
{
|
||||
bool HasUpdateInstalled { get; }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Duplicati.Library.AutoUpdater;
|
||||
|
||||
public class UpdateManagerAccessor : IUpdateManagerAccessor
|
||||
{
|
||||
public bool HasUpdateInstalled => UpdaterManager.HasUpdateInstalled;
|
||||
}
|
||||
@@ -203,18 +203,6 @@ namespace Duplicati.Server
|
||||
[STAThread]
|
||||
public static int Main(string[] _args)
|
||||
{
|
||||
// var methodInfo = typeof(TemporaryIoCAccessor).Assembly.EntryPoint;
|
||||
// var program = Activator.CreateInstance(methodInfo!.DeclaringType!);
|
||||
// methodInfo.Invoke(program, [Array.Empty<string>()]);
|
||||
return Duplicati.Library.AutoUpdater.UpdaterManager.RunFromMostRecent(typeof(Program).GetMethod("RealMain"), args, Duplicati.Library.AutoUpdater.AutoUpdateStrategy.Never);
|
||||
}
|
||||
|
||||
public static int RealMain(string[] _args)
|
||||
{
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debugger.Launch();
|
||||
#endif
|
||||
|
||||
//If we are on Windows, append the bundled "win-tools" programs to the search path
|
||||
//We add it last, to allow the user to override with other versions
|
||||
if (Platform.IsClientWindows)
|
||||
|
||||
@@ -19,6 +19,6 @@ public class ServerStatusDto : IServerStatus
|
||||
public long LastNotificationUpdateID { get; init; }
|
||||
public string? UpdatedVersion { get; init; }
|
||||
public UpdatePollerStates UpdaterState { get; init; }
|
||||
public bool UpdateReady { get; init; }
|
||||
public string UpdateDownloadLink { get; set; }
|
||||
public double UpdateDownloadProgress { get; init; }
|
||||
}
|
||||
@@ -26,7 +26,6 @@ public static class ServiceCollectionsExtensions
|
||||
services.AddSingleton<EventPollNotify>();
|
||||
|
||||
//transitional part - services that act as a proxy to old part for various reasons (not accessible in assembly i.e.)
|
||||
services.AddSingleton<IUpdateManagerAccessor, UpdateManagerAccessor>();
|
||||
services.AddSingleton<ILiveControls>(c => c.GetRequiredService<LiveControls>());
|
||||
services.AddSingleton<IBoolParser, BoolParser>();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using Duplicati.Library.RestAPI.Abstractions;
|
||||
using HttpServer;
|
||||
using HttpServer.FormDecoders;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
@@ -8,7 +9,7 @@ using HttpRequest = Microsoft.AspNetCore.Http.HttpRequest;
|
||||
|
||||
namespace Duplicati.WebserverCore;
|
||||
|
||||
class LegacyHttpRequestShim : HttpServer.IHttpRequest
|
||||
class LegacyHttpRequestShim : HttpServer.IHttpRequest, IModernHttpRequestAccess
|
||||
{
|
||||
HttpRequest request;
|
||||
public LegacyHttpRequestShim(HttpRequest request) { this.request = request; }
|
||||
@@ -147,4 +148,9 @@ class LegacyHttpRequestShim : HttpServer.IHttpRequest
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string? GetQueryParam(string name)
|
||||
{
|
||||
return request.Query[name].FirstOrDefault();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
using Duplicati.Library.AutoUpdater;
|
||||
using Duplicati.Library.RestAPI;
|
||||
using Duplicati.Library.RestAPI.Abstractions;
|
||||
using Duplicati.Server;
|
||||
@@ -14,7 +13,6 @@ public class StatusService : IStatusService
|
||||
private readonly LiveControls m_liveControls;
|
||||
private readonly UpdatePollThread m_updatePollThread;
|
||||
private readonly IUpdateService m_updateService;
|
||||
private readonly IUpdateManagerAccessor m_updateManager;
|
||||
private readonly IWorkerThreadsManager m_workerThreadsManager;
|
||||
private readonly ISettingsService m_settingsService;
|
||||
private readonly IScheduler m_scheduler;
|
||||
@@ -24,7 +22,6 @@ public class StatusService : IStatusService
|
||||
public StatusService(LiveControls liveControls,
|
||||
UpdatePollThread updatePollThread,
|
||||
IUpdateService updateService,
|
||||
IUpdateManagerAccessor updateManager,
|
||||
IWorkerThreadsManager workerThreadsManager,
|
||||
ISettingsService settingsService,
|
||||
IScheduler scheduler,
|
||||
@@ -35,7 +32,6 @@ public class StatusService : IStatusService
|
||||
m_liveControls = liveControls;
|
||||
m_updatePollThread = updatePollThread;
|
||||
m_updateService = updateService;
|
||||
m_updateManager = updateManager;
|
||||
m_workerThreadsManager = workerThreadsManager;
|
||||
m_settingsService = settingsService;
|
||||
m_scheduler = scheduler;
|
||||
@@ -52,7 +48,6 @@ public class StatusService : IStatusService
|
||||
UpdatedVersion = GetUpdatedVersion(),
|
||||
UpdaterState = m_updatePollThread.ThreadState,
|
||||
UpdateDownloadProgress = m_updatePollThread.DownloadProgess,
|
||||
UpdateReady = m_updateManager.HasUpdateInstalled,
|
||||
ActiveTask = m_workerThreadsManager.CurrentTask,
|
||||
SchedulerQueueIds = m_scheduler.GetSchedulerQueueIds(),
|
||||
LastEventID = m_eventPollNotify.EventNo,
|
||||
@@ -98,6 +93,7 @@ public class StatusService : IStatusService
|
||||
{
|
||||
status.HasError = m_settingsService.GetSettings().UnackedError;
|
||||
status.HasWarning = m_settingsService.GetSettings().UnackedWarning;
|
||||
status.UpdateDownloadLink = m_settingsService.GetSettings().UpdateCheckNewVersion;
|
||||
}
|
||||
|
||||
private string? GetUpdatedVersion()
|
||||
|
||||
Reference in New Issue
Block a user