public virtual void TestSetup() { //Start the service if needed AppiumServer.Start(TestEnvironmentParameters); //Set user provided options. MobileTestContext.Set(Constants.AppiumAdditionalOptionsKey, AdditionalCapabilities); Capabilities = new DriverCapabilities(TestEnvironmentParameters); //Merge user provided options to existing default capabilities. Capabilities.MergeCapabilities(MobileTestContext.Get <AdditionalDriverOptions>(Constants.AppiumAdditionalOptionsKey, false)); // Write Runsettings to log file TestLogs.WriteLogSection("Original Test Run Parameters", () => TestLogs.Write(this.TestEnvironmentParameters.ToString())); MobileDriver.Initialize(Capabilities); //Write device configuration to log file TestLogs.WriteLogSection("DUT Configuration", () => TestLogs.Write(MobileDriver.Instance.Capabilities.ToString())); //Capture enviroment parameters for all futures uses. MobileTestContext.Set(Constants.TestEnvironmentKey, TestEnvironmentParameters); TestLogs.AddSection($"Test {TestContext.CurrentContext.Test.Name} Starts"); }
public async Task <T> TestApiAgainstAccessToken <T>(string apikey, string url, HttpClient client) { var uri = new Uri(client.BaseAddress, url); var httpRequest = new HttpRequestMessage(HttpMethod.Get, uri); httpRequest.Headers.Authorization = new AuthenticationHeaderValue("token", apikey); TestLogs.LogInformation($"Testing {uri}"); var result = await client.SendAsync(httpRequest); TestLogs.LogInformation($"Testing {uri} status: {result.StatusCode}"); result.EnsureSuccessStatusCode(); var rawJson = await result.Content.ReadAsStringAsync(); TestLogs.LogInformation($"Testing {uri} result: {rawJson}"); if (typeof(T).IsPrimitive || typeof(T) == typeof(string)) { return((T)Convert.ChangeType(rawJson, typeof(T))); } return(JsonConvert.DeserializeObject <T>(rawJson)); }
public (string storeName, string storeId) CreateNewStore(bool keepId = true) { // If there's no store yet, there is no dropdown toggle if (Driver.PageSource.Contains("id=\"StoreSelectorToggle\"")) { Driver.FindElement(By.Id("StoreSelectorToggle")).Click(); } Driver.WaitForElement(By.Id("StoreSelectorCreate")).Click(); var name = "Store" + RandomUtils.GetUInt64(); TestLogs.LogInformation($"Created store {name}"); Driver.WaitForElement(By.Id("Name")).SendKeys(name); Driver.WaitForElement(By.Id("Create")).Click(); Driver.FindElement(By.Id("StoreNav-StoreSettings")).Click(); Driver.FindElement(By.Id($"SectionNav-{StoreNavPages.General.ToString()}")).Click(); var storeId = Driver.WaitForElement(By.Id("Id")).GetAttribute("value"); if (keepId) { StoreId = storeId; } return(name, storeId); }
private void OverrideRunSettingsParams(AdditionalDriverOptions driverOptions) { TestLogs.WriteLogSection("Overriding RunSettings", () => { foreach (KeyValuePair <string, object> runSetting in driverOptions.GetCapabilities().Where(k => k.Key.Contains("RS_"))) { System.Reflection.PropertyInfo contextProperty = this.context.GetType().GetProperty(runSetting.Key); if (contextProperty != null && contextProperty.CanWrite) { if (contextProperty.PropertyType == typeof(ApplicationType)) { contextProperty.SetValue(this.context, (ApplicationType)Enum.Parse(typeof(ApplicationType), runSetting.Value.ToString())); isCapabilityRefreshNeeded = true; continue; } contextProperty.SetValue(this.context, runSetting.Value); isCapabilityRefreshNeeded = true; TestLogs.Write($"Overriding RunSettings Key: [{runSetting.Key}], New Value = [{runSetting.Value}]"); } } }); RefreshCapabilities(); }
public async Task CanPayWithTwoCurrencies() { using (var tester = CreateServerTester()) { tester.ActivateLTC(); await tester.StartAsync(); var user = tester.NewAccount(); user.GrantAccess(); user.RegisterDerivationScheme("BTC"); // First we try payment with a merchant having only BTC var invoice = user.BitPay.CreateInvoice( new Invoice() { Price = 5000.0m, Currency = "USD", PosData = "posData", OrderId = "orderId", ItemDesc = "Some description", FullNotifications = true }, Facade.Merchant); var cashCow = tester.ExplorerNode; cashCow.Generate(2); // get some money in case var invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); var firstPayment = Money.Coins(0.04m); cashCow.SendToAddress(invoiceAddress, firstPayment); TestUtils.Eventually(() => { invoice = user.BitPay.GetInvoice(invoice.Id); Assert.True(invoice.BtcPaid == firstPayment); }); Assert.Single(invoice.CryptoInfo); // Only BTC should be presented var controller = tester.PayTester.GetController <UIInvoiceController>(null); var checkout = (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id, null) .GetAwaiter().GetResult()).Value; Assert.Single(checkout.AvailableCryptos); Assert.Equal("BTC", checkout.CryptoCode); Assert.Single(invoice.PaymentCodes); Assert.Single(invoice.SupportedTransactionCurrencies); Assert.Single(invoice.SupportedTransactionCurrencies); Assert.Single(invoice.PaymentSubtotals); Assert.Single(invoice.PaymentTotals); Assert.True(invoice.PaymentCodes.ContainsKey("BTC")); Assert.True(invoice.SupportedTransactionCurrencies.ContainsKey("BTC")); Assert.True(invoice.SupportedTransactionCurrencies["BTC"].Enabled); Assert.True(invoice.PaymentSubtotals.ContainsKey("BTC")); Assert.True(invoice.PaymentTotals.ContainsKey("BTC")); ////////////////////// // Retry now with LTC enabled user.RegisterDerivationScheme("LTC"); invoice = user.BitPay.CreateInvoice( new Invoice() { Price = 5000.0m, Currency = "USD", PosData = "posData", OrderId = "orderId", ItemDesc = "Some description", FullNotifications = true }, Facade.Merchant); cashCow = tester.ExplorerNode; invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); firstPayment = Money.Coins(0.04m); cashCow.SendToAddress(invoiceAddress, firstPayment); TestLogs.LogInformation("First payment sent to " + invoiceAddress); TestUtils.Eventually(() => { invoice = user.BitPay.GetInvoice(invoice.Id); Assert.True(invoice.BtcPaid == firstPayment); }); cashCow = tester.LTCExplorerNode; var ltcCryptoInfo = invoice.CryptoInfo.FirstOrDefault(c => c.CryptoCode == "LTC"); Assert.NotNull(ltcCryptoInfo); invoiceAddress = BitcoinAddress.Create(ltcCryptoInfo.Address, cashCow.Network); var secondPayment = Money.Coins(decimal.Parse(ltcCryptoInfo.Due, CultureInfo.InvariantCulture)); cashCow.Generate(4); // LTC is not worth a lot, so just to make sure we have money... cashCow.SendToAddress(invoiceAddress, secondPayment); TestLogs.LogInformation("Second payment sent to " + invoiceAddress); TestUtils.Eventually(() => { invoice = user.BitPay.GetInvoice(invoice.Id); Assert.Equal(Money.Zero, invoice.BtcDue); var ltcPaid = invoice.CryptoInfo.First(c => c.CryptoCode == "LTC"); Assert.Equal(Money.Zero, ltcPaid.Due); Assert.Equal(secondPayment, ltcPaid.CryptoPaid); Assert.Equal("paid", invoice.Status); Assert.False((bool)((JValue)invoice.ExceptionStatus).Value); }); controller = tester.PayTester.GetController <UIInvoiceController>(null); checkout = (Models.InvoicingModels.PaymentModel)((JsonResult)controller.GetStatus(invoice.Id, "LTC") .GetAwaiter().GetResult()).Value; Assert.Equal(2, checkout.AvailableCryptos.Count); Assert.Equal("LTC", checkout.CryptoCode); Assert.Equal(2, invoice.PaymentCodes.Count()); Assert.Equal(2, invoice.SupportedTransactionCurrencies.Count()); Assert.Equal(2, invoice.SupportedTransactionCurrencies.Count()); Assert.Equal(2, invoice.PaymentSubtotals.Count()); Assert.Equal(2, invoice.PaymentTotals.Count()); Assert.True(invoice.PaymentCodes.ContainsKey("LTC")); Assert.True(invoice.SupportedTransactionCurrencies.ContainsKey("LTC")); Assert.True(invoice.SupportedTransactionCurrencies["LTC"].Enabled); Assert.True(invoice.PaymentSubtotals.ContainsKey("LTC")); Assert.True(invoice.PaymentTotals.ContainsKey("LTC")); // Check if we can disable LTC invoice = user.BitPay.CreateInvoice( new Invoice() { Price = 5000.0m, Currency = "USD", PosData = "posData", OrderId = "orderId", ItemDesc = "Some description", FullNotifications = true, SupportedTransactionCurrencies = new Dictionary <string, InvoiceSupportedTransactionCurrency>() { { "BTC", new InvoiceSupportedTransactionCurrency() { Enabled = true } } } }, Facade.Merchant); Assert.Single(invoice.CryptoInfo.Where(c => c.CryptoCode == "BTC")); Assert.Empty(invoice.CryptoInfo.Where(c => c.CryptoCode == "LTC")); } }
public async Task CanCreateApiKeys() { //there are 2 ways to create api keys: //as a user through your profile //as an external application requesting an api key from a user using var s = CreateSeleniumTester(); await s.StartAsync(); var tester = s.Server; var user = tester.NewAccount(); await user.GrantAccessAsync(); await user.MakeAdmin(false); s.GoToLogin(); s.LogIn(user.RegisterDetails.Email, user.RegisterDetails.Password); s.GoToProfile(ManageNavPages.APIKeys); s.Driver.FindElement(By.Id("AddApiKey")).Click(); TestLogs.LogInformation("Checking admin permissions"); //not an admin, so this permission should not show Assert.DoesNotContain("btcpay.server.canmodifyserversettings", s.Driver.PageSource); await user.MakeAdmin(); s.Logout(); s.GoToLogin(); s.LogIn(user.RegisterDetails.Email, user.RegisterDetails.Password); s.GoToProfile(ManageNavPages.APIKeys); s.Driver.FindElement(By.Id("AddApiKey")).Click(); Assert.Contains("btcpay.server.canmodifyserversettings", s.Driver.PageSource); //server management should show now s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true); s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true); s.Driver.SetCheckbox(By.Id("btcpay.user.canviewprofile"), true); s.Driver.FindElement(By.Id("Generate")).Click(); var superApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text; TestLogs.LogInformation("Checking super admin key"); //this api key has access to everything await TestApiAgainstAccessToken(superApiKey, tester, user, Policies.CanModifyServerSettings, Policies.CanModifyStoreSettings, Policies.CanViewProfile); s.Driver.FindElement(By.Id("AddApiKey")).Click(); s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true); s.Driver.FindElement(By.Id("Generate")).Click(); var serverOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text; TestLogs.LogInformation("Checking CanModifyServerSettings permissions"); await TestApiAgainstAccessToken(serverOnlyApiKey, tester, user, Policies.CanModifyServerSettings); s.Driver.FindElement(By.Id("AddApiKey")).Click(); s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true); s.Driver.FindElement(By.Id("Generate")).Click(); var allStoreOnlyApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text; TestLogs.LogInformation("Checking CanModifyStoreSettings permissions"); await TestApiAgainstAccessToken(allStoreOnlyApiKey, tester, user, Policies.CanModifyStoreSettings); s.Driver.FindElement(By.Id("AddApiKey")).Click(); s.Driver.FindElement(By.CssSelector("button[value='btcpay.store.canmodifystoresettings:change-store-mode']")).Click(); //there should be a store already by default in the dropdown var getPermissionValueIndex = s.Driver.FindElement(By.CssSelector("input[value='btcpay.store.canmodifystoresettings']")) .GetAttribute("name") .Replace(".Permission", ".SpecificStores[0]"); var dropdown = s.Driver.FindElement(By.Name(getPermissionValueIndex)); var option = dropdown.FindElement(By.TagName("option")); var storeId = option.GetAttribute("value"); option.Click(); s.Driver.WaitForAndClick(By.Id("Generate")); var selectiveStoreApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text; TestLogs.LogInformation("Checking CanModifyStoreSettings with StoreId permissions"); await TestApiAgainstAccessToken(selectiveStoreApiKey, tester, user, Permission.Create(Policies.CanModifyStoreSettings, storeId).ToString()); TestLogs.LogInformation("Adding API key for no permissions"); s.Driver.WaitForAndClick(By.Id("AddApiKey")); TestLogs.LogInformation("Generating API key for no permissions"); s.Driver.WaitForAndClick(By.Id("Generate")); var noPermissionsApiKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text; TestLogs.LogInformation($"Checking no permissions: {noPermissionsApiKey}"); await TestApiAgainstAccessToken(noPermissionsApiKey, tester, user); await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>("incorrect key", $"{TestApiPath}/me/id", tester.PayTester.HttpClient); }); TestLogs.LogInformation("Checking authorize screen"); //let's test the authorized screen now //options for authorize are: //applicationName //redirect //permissions //strict //selectiveStores //redirect //appidentifier var appidentifier = "testapp"; var callbackUrl = s.ServerUri + "postredirect-callback-test"; var authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString(); TestLogs.LogInformation($"Going to auth URL {authUrl}"); s.GoToUrl(authUrl); Assert.Contains(appidentifier, s.Driver.PageSource); Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant()); Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant()); Assert.DoesNotContain("change-store-mode", s.Driver.PageSource); TestLogs.LogInformation("Going to callback URL"); s.Driver.WaitForAndClick(By.Id("consent-yes")); Assert.Equal(callbackUrl, s.Driver.Url); TestLogs.LogInformation("On callback URL"); var apiKeyRepo = s.Server.PayTester.GetService <APIKeyRepository>(); var accessToken = GetAccessTokenFromCallbackResult(s.Driver); TestLogs.LogInformation($"Access token: {accessToken}"); await TestApiAgainstAccessToken(accessToken, tester, user, (await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions); authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, applicationDetails: (null, new Uri(callbackUrl))).ToString(); TestLogs.LogInformation($"Going to auth URL 2 {authUrl}"); s.GoToUrl(authUrl); TestLogs.LogInformation("On auth URL 2"); Assert.DoesNotContain("kukksappname", s.Driver.PageSource); Assert.Equal("checkbox", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant()); Assert.Equal("checkbox", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant()); s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), false); Assert.Contains("change-store-mode", s.Driver.PageSource); TestLogs.LogInformation("Going to callback URL 2"); s.Driver.WaitForAndClick(By.Id("consent-yes")); Assert.Equal(callbackUrl, s.Driver.Url); TestLogs.LogInformation("On callback URL 2"); accessToken = GetAccessTokenFromCallbackResult(s.Driver); TestLogs.LogInformation($"Access token: {accessToken}"); TestLogs.LogInformation("Checking authorized permissions"); await TestApiAgainstAccessToken(accessToken, tester, user, (await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions); //let's test the app identifier system TestLogs.LogInformation("Checking app identifier system"); authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri(callbackUrl))).ToString(); //if it's the same, go to the confirm page TestLogs.LogInformation($"Going to auth URL 3 {authUrl}"); s.GoToUrl(authUrl); TestLogs.LogInformation("On auth URL 3"); s.Driver.WaitForAndClick(By.Id("continue")); TestLogs.LogInformation("Going to callback URL 3"); Assert.Equal(callbackUrl, s.Driver.Url); TestLogs.LogInformation("On callback URL 3"); //same app but different redirect = nono authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri("https://international.local/callback"))).ToString(); TestLogs.LogInformation($"Going to auth URL 4 {authUrl}"); s.GoToUrl(authUrl); TestLogs.LogInformation("On auth URL 4"); Assert.False(s.Driver.Url.StartsWith("https://international.com/callback")); // Make sure we can check all permissions when not an admin TestLogs.LogInformation("Make sure we can check all permissions when not an admin"); await user.MakeAdmin(false); s.Logout(); s.GoToLogin(); s.LogIn(user.RegisterDetails.Email, user.RegisterDetails.Password); TestLogs.LogInformation("Go to API Keys page"); s.GoToUrl("/account/apikeys"); TestLogs.LogInformation("On API Keys page"); s.Driver.WaitForAndClick(By.Id("AddApiKey")); int checkedPermissionCount = s.Driver.FindElements(By.ClassName("form-check-input")).Count; TestLogs.LogInformation($"Adding API key: {checkedPermissionCount} permissions"); s.Driver.ExecuteJavaScript("document.querySelectorAll('#Permissions .form-check-input').forEach(i => i.click())"); TestLogs.LogInformation($"Clicked {checkedPermissionCount}"); TestLogs.LogInformation("Generating API key"); s.Driver.WaitForAndClick(By.Id("Generate")); var allAPIKey = s.FindAlertMessage().FindElement(By.TagName("code")).Text; TestLogs.LogInformation($"Checking API key permissions: {allAPIKey}"); var apikeydata = await TestApiAgainstAccessToken <ApiKeyData>(allAPIKey, "api/v1/api-keys/current", tester.PayTester.HttpClient); Assert.Equal(checkedPermissionCount, apikeydata.Permissions.Length); }
async Task TestApiAgainstAccessToken(string accessToken, ServerTester tester, TestAccount testAccount, params string[] expectedPermissionsArr) { var expectedPermissions = Permission.ToPermissions(expectedPermissionsArr).ToArray(); expectedPermissions ??= new Permission[0]; var apikeydata = await TestApiAgainstAccessToken <ApiKeyData>(accessToken, $"api/v1/api-keys/current", tester.PayTester.HttpClient); var permissions = apikeydata.Permissions; TestLogs.LogInformation($"TestApiAgainstAccessToken: Permissions {permissions.Length}"); Assert.Equal(expectedPermissions.Length, permissions.Length); foreach (var expectPermission in expectedPermissions) { Assert.True(permissions.Any(p => p == expectPermission), $"Missing expected permission {expectPermission}"); } TestLogs.LogInformation("Testing CanViewProfile"); if (permissions.Contains(Permission.Create(Policies.CanViewProfile))) { var resultUser = await TestApiAgainstAccessToken <string>(accessToken, $"{TestApiPath}/me/id", tester.PayTester.HttpClient); Assert.Equal(testAccount.UserId, resultUser); } else { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <string>(accessToken, $"{TestApiPath}/me/id", tester.PayTester.HttpClient); }); } //create a second user to see if any of its data gets messed up in our results. TestLogs.LogInformation("Testing second user"); var secondUser = tester.NewAccount(); await secondUser.GrantAccessAsync(); var canModifyAllStores = Permission.Create(Policies.CanModifyStoreSettings, null); var canModifyServer = Permission.Create(Policies.CanModifyServerSettings, null); var unrestricted = Permission.Create(Policies.Unrestricted, null); var selectiveStorePermissions = permissions.Where(p => p.Scope != null && p.Policy == Policies.CanModifyStoreSettings); TestLogs.LogInformation("Testing can edit store for first user"); if (permissions.Contains(canModifyAllStores) || selectiveStorePermissions.Any()) { var resultStores = await TestApiAgainstAccessToken <StoreData[]>(accessToken, $"{TestApiPath}/me/stores", tester.PayTester.HttpClient); foreach (var selectiveStorePermission in selectiveStorePermissions) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{selectiveStorePermission.Scope}/can-edit", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(selectiveStorePermission.Scope, StringComparison.InvariantCultureIgnoreCase)); } bool shouldBeAuthorized = false; if (permissions.Contains(canModifyAllStores) || selectiveStorePermissions.Contains(Permission.Create(Policies.CanViewStoreSettings, testAccount.StoreId))) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-view", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); shouldBeAuthorized = true; } if (permissions.Contains(canModifyAllStores) || selectiveStorePermissions.Contains(Permission.Create(Policies.CanModifyStoreSettings, testAccount.StoreId))) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-view", tester.PayTester.HttpClient)); Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient)); Assert.Contains(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); shouldBeAuthorized = true; } if (!shouldBeAuthorized) { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); }); await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-view", tester.PayTester.HttpClient); }); Assert.DoesNotContain(resultStores, data => data.Id.Equals(testAccount.StoreId, StringComparison.InvariantCultureIgnoreCase)); } } else if (!permissions.Contains(unrestricted)) { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); }); } else { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{testAccount.StoreId}/can-edit", tester.PayTester.HttpClient); } TestLogs.LogInformation("Testing can edit store for second user"); if (!permissions.Contains(unrestricted)) { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{secondUser.StoreId}/can-edit", tester.PayTester.HttpClient); }); } else { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/stores/{secondUser.StoreId}/can-edit", tester.PayTester.HttpClient); } TestLogs.LogInformation("Testing can edit store for second user expectation met"); TestLogs.LogInformation($"Testing CanModifyServer with {permissions.Contains(canModifyServer)}"); if (permissions.Contains(canModifyServer)) { Assert.True(await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/is-admin", tester.PayTester.HttpClient)); } else { await Assert.ThrowsAnyAsync <HttpRequestException>(async() => { await TestApiAgainstAccessToken <bool>(accessToken, $"{TestApiPath}/me/is-admin", tester.PayTester.HttpClient); }); } TestLogs.LogInformation("Testing CanModifyServer expectation met"); }
public Mnemonic GenerateWallet(string cryptoCode = "BTC", string seed = "", bool?importkeys = null, bool isHotWallet = false, ScriptPubKeyType format = ScriptPubKeyType.Segwit) { var isImport = !string.IsNullOrEmpty(seed); GoToWalletSettings(cryptoCode); // Replace previous wallet case if (Driver.PageSource.Contains("id=\"ChangeWalletLink\"")) { Driver.FindElement(By.Id("ActionsDropdownToggle")).Click(); Driver.WaitForElement(By.Id("ChangeWalletLink")).Click(); Driver.WaitForElement(By.Id("ConfirmInput")).SendKeys("REPLACE"); Driver.FindElement(By.Id("ConfirmContinue")).Click(); } if (isImport) { TestLogs.LogInformation("Progressing with existing seed"); Driver.FindElement(By.Id("ImportWalletOptionsLink")).Click(); Driver.FindElement(By.Id("ImportSeedLink")).Click(); Driver.FindElement(By.Id("ExistingMnemonic")).SendKeys(seed); Driver.SetCheckbox(By.Id("SavePrivateKeys"), isHotWallet); } else { var option = isHotWallet ? "Hotwallet" : "Watchonly"; TestLogs.LogInformation($"Generating new seed ({option})"); Driver.FindElement(By.Id("GenerateWalletLink")).Click(); Driver.FindElement(By.Id($"Generate{option}Link")).Click(); } Driver.FindElement(By.Id("ScriptPubKeyType")).Click(); Driver.FindElement(By.CssSelector($"#ScriptPubKeyType option[value={format}]")).Click(); Driver.ToggleCollapse("AdvancedSettings"); if (importkeys is bool v) { Driver.SetCheckbox(By.Id("ImportKeysToRPC"), v); } Driver.FindElement(By.Id("Continue")).Click(); if (isImport) { // Confirm addresses Driver.FindElement(By.Id("Confirm")).Click(); } else { // Seed backup FindAlertMessage(); if (string.IsNullOrEmpty(seed)) { seed = Driver.FindElements(By.Id("RecoveryPhrase")).First().GetAttribute("data-mnemonic"); } // Confirm seed backup Driver.FindElement(By.Id("confirm")).Click(); Driver.FindElement(By.Id("submit")).Click(); } WalletId = new WalletId(StoreId, cryptoCode); return(new Mnemonic(seed)); }
public async Task CanComputeCrowdfundModel() { using var tester = CreateServerTester(); await tester.StartAsync(); var user = tester.NewAccount(); await user.GrantAccessAsync(); user.RegisterDerivationScheme("BTC"); await user.SetNetworkFeeMode(NetworkFeeMode.Never); var apps = user.GetController <UIAppsController>(); var vm = Assert.IsType <CreateAppViewModel>(Assert.IsType <ViewResult>(apps.CreateApp(user.StoreId)).Model); var appType = AppType.Crowdfund.ToString(); vm.AppName = "test"; vm.SelectedAppType = appType; Assert.IsType <RedirectToActionResult>(apps.CreateApp(user.StoreId, vm).Result); var appList = Assert.IsType <ListAppsViewModel>(Assert.IsType <ViewResult>(apps.ListApps(user.StoreId).Result).Model); var app = appList.Apps[0]; apps.HttpContext.SetAppData(new AppData { Id = app.Id, StoreDataId = app.StoreId, Name = app.AppName, AppType = appType }); TestLogs.LogInformation("We create an invoice with a hardcap"); var crowdfundViewModel = await apps.UpdateCrowdfund(app.Id).AssertViewModelAsync <UpdateCrowdfundViewModel>(); crowdfundViewModel.Enabled = true; crowdfundViewModel.EndDate = null; crowdfundViewModel.TargetAmount = 100; crowdfundViewModel.TargetCurrency = "BTC"; crowdfundViewModel.UseAllStoreInvoices = true; crowdfundViewModel.EnforceTargetAmount = true; Assert.IsType <RedirectToActionResult>(apps.UpdateCrowdfund(app.Id, crowdfundViewModel, "save").Result); var anonAppPubsController = tester.PayTester.GetController <UIAppsPublicController>(); var publicApps = user.GetController <UIAppsPublicController>(); var model = Assert.IsType <ViewCrowdfundViewModel>(Assert .IsType <ViewResult>(publicApps.ViewCrowdfund(app.Id, String.Empty).Result).Model); Assert.Equal(crowdfundViewModel.TargetAmount, model.TargetAmount); Assert.Equal(crowdfundViewModel.EndDate, model.EndDate); Assert.Equal(crowdfundViewModel.StartDate, model.StartDate); Assert.Equal(crowdfundViewModel.TargetCurrency, model.TargetCurrency); Assert.Equal(0m, model.Info.CurrentAmount); Assert.Equal(0m, model.Info.CurrentPendingAmount); Assert.Equal(0m, model.Info.ProgressPercentage); TestLogs.LogInformation("Unpaid invoices should show as pending contribution because it is hardcap"); TestLogs.LogInformation("Because UseAllStoreInvoices is true, we can manually create an invoice and it should show as contribution"); var invoice = await user.BitPay.CreateInvoiceAsync(new Invoice { Buyer = new Buyer() { email = "*****@*****.**" }, Price = 1m, Currency = "BTC", PosData = "posData", ItemDesc = "Some description", TransactionSpeed = "high", FullNotifications = true }, Facade.Merchant); model = Assert.IsType <ViewCrowdfundViewModel>(Assert .IsType <ViewResult>(publicApps.ViewCrowdfund(app.Id, string.Empty).Result).Model); Assert.Equal(0m, model.Info.CurrentAmount); Assert.Equal(1m, model.Info.CurrentPendingAmount); Assert.Equal(0m, model.Info.ProgressPercentage); Assert.Equal(1m, model.Info.PendingProgressPercentage); TestLogs.LogInformation("Let's check current amount change once payment is confirmed"); var invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, tester.ExplorerNode.Network); tester.ExplorerNode.SendToAddress(invoiceAddress, invoice.BtcDue); tester.ExplorerNode.Generate(1); // By default invoice confirmed at 1 block TestUtils.Eventually(() => { model = Assert.IsType <ViewCrowdfundViewModel>(Assert .IsType <ViewResult>(publicApps.ViewCrowdfund(app.Id, String.Empty).Result).Model); Assert.Equal(1m, model.Info.CurrentAmount); Assert.Equal(0m, model.Info.CurrentPendingAmount); }); TestLogs.LogInformation("Because UseAllStoreInvoices is true, let's make sure the invoice is tagged"); var invoiceEntity = tester.PayTester.InvoiceRepository.GetInvoice(invoice.Id).GetAwaiter().GetResult(); Assert.True(invoiceEntity.Version >= InvoiceEntity.InternalTagSupport_Version); Assert.Contains(AppService.GetAppInternalTag(app.Id), invoiceEntity.InternalTags); crowdfundViewModel.UseAllStoreInvoices = false; Assert.IsType <RedirectToActionResult>(apps.UpdateCrowdfund(app.Id, crowdfundViewModel, "save").Result); TestLogs.LogInformation("Because UseAllStoreInvoices is false, let's make sure the invoice is not tagged"); invoice = await user.BitPay.CreateInvoiceAsync(new Invoice { Buyer = new Buyer { email = "*****@*****.**" }, Price = 1m, Currency = "BTC", PosData = "posData", ItemDesc = "Some description", TransactionSpeed = "high", FullNotifications = true }, Facade.Merchant); invoiceEntity = tester.PayTester.InvoiceRepository.GetInvoice(invoice.Id).GetAwaiter().GetResult(); Assert.DoesNotContain(AppService.GetAppInternalTag(app.Id), invoiceEntity.InternalTags); TestLogs.LogInformation("After turning setting a softcap, let's check that only actual payments are counted"); crowdfundViewModel.EnforceTargetAmount = false; crowdfundViewModel.UseAllStoreInvoices = true; Assert.IsType <RedirectToActionResult>(apps.UpdateCrowdfund(app.Id, crowdfundViewModel, "save").Result); invoice = await user.BitPay.CreateInvoiceAsync(new Invoice { Buyer = new Buyer { email = "*****@*****.**" }, Price = 1m, Currency = "BTC", PosData = "posData", ItemDesc = "Some description", TransactionSpeed = "high", FullNotifications = true }, Facade.Merchant); Assert.Equal(0m, model.Info.CurrentPendingAmount); invoiceAddress = BitcoinAddress.Create(invoice.CryptoInfo[0].Address, tester.ExplorerNode.Network); await tester.ExplorerNode.SendToAddressAsync(invoiceAddress, Money.Coins(0.5m)); await tester.ExplorerNode.SendToAddressAsync(invoiceAddress, Money.Coins(0.2m)); TestUtils.Eventually(() => { model = Assert.IsType <ViewCrowdfundViewModel>(Assert .IsType <ViewResult>(publicApps.ViewCrowdfund(app.Id, string.Empty).Result).Model); Assert.Equal(0.7m, model.Info.CurrentPendingAmount); }); }
public void ServerLogsCanBeCapturedSuccessfully() { Assert.NotNull(TestLogs.WriteDeviceLogs().Find(f => f.Contains("server")), "Server logs should be generated"); }
/// <summary> /// Basic checks since all capabilities have been set /// </summary> internal void PreReqChecks() { Dictionary <string, object> caps = options.ToDictionary(); object values; TestLogs.WriteLogSection("Prerequisite Checks", () => { TestLogs.Write("Starting checks..."); if (this.isNativeApp || this.isHybridApp) { //Browser should be null if (caps.TryGetValue(MobileCapabilityType.BrowserName, out values)) { if (!Helper.IsNullOrEmpty(values.ToString(), false)) { throw new InvalidCapabilityException($"Capability combination: [{MobileCapabilityType.BrowserName}] = [{values?.ToString()}] is invalid for application type [{this.context.RS_AppType}]"); } } values = null; //Check App package or AppActivity is set or not if (this.context.RS_DeviceGroup.Contains("ANDROID", StringComparison.OrdinalIgnoreCase)) { if (caps.TryGetValue(AndroidMobileCapabilityType.AppPackage, out values)) { if (values == null || values.Equals("io.android.testapp")) { throw new InvalidCapabilityException($"Capability combination: [{AndroidMobileCapabilityType.AppPackage}] = [{values?.ToString()}] is invalid for application type [{this.context.RS_AppType}]"); } } values = null; if (caps.TryGetValue(AndroidMobileCapabilityType.AppActivity, out values)) { if (values == null || values.Equals(".HomeScreenActivity")) { throw new InvalidCapabilityException($"Capability combination: [{AndroidMobileCapabilityType.AppActivity}] = [{values?.ToString()}] is invalid for application type [{this.context.RS_AppType}]"); } } values = null; } if (this.context.RS_DeviceGroup.Contains("IOS", StringComparison.OrdinalIgnoreCase)) { if (caps.TryGetValue(IOSMobileCapabilityType.BundleId, out values)) { if (values == null || values.Equals("io.android.testapp")) { throw new InvalidCapabilityException($"Capability combination: [{IOSMobileCapabilityType.AppName}] = [{values?.ToString()}] is invalid for application type [{this.context.RS_AppType}]"); } } } values = null; } else //Web app //Browser should not be null { if (caps.TryGetValue(MobileCapabilityType.BrowserName, out values)) { if (string.IsNullOrEmpty(values.ToString())) { throw new InvalidCapabilityException($"Capability combination: [{MobileCapabilityType.BrowserName}] = [{values?.ToString()}] is invalid for application type [{this.context.RS_AppType}]"); } } } TestLogs.Write("No issues found!!"); }); }