public async Task CanUseAzureBlobStorage()
        {
            using var tester = CreateServerTester();
            await tester.StartAsync();

            var user = tester.NewAccount();

            user.GrantAccess();
            var controller = tester.PayTester.GetController <UIServerController>(user.UserId, user.StoreId);
            var azureBlobStorageConfiguration = Assert.IsType <AzureBlobStorageConfiguration>(Assert
                                                                                              .IsType <ViewResult>(await controller.StorageProvider(StorageProvider.AzureBlobStorage.ToString()))
                                                                                              .Model);

            azureBlobStorageConfiguration.ConnectionString = FactWithSecretAttribute.GetFromSecrets("AzureBlobStorageConnectionString");
            azureBlobStorageConfiguration.ContainerName    = "testscontainer";
            Assert.IsType <ViewResult>(
                await controller.EditAzureBlobStorageStorageProvider(azureBlobStorageConfiguration));


            var shouldBeRedirectingToAzureStorageConfigPage =
                Assert.IsType <RedirectToActionResult>(await controller.Storage());

            Assert.Equal(nameof(StorageProvider), shouldBeRedirectingToAzureStorageConfigPage.ActionName);
            Assert.Equal(StorageProvider.AzureBlobStorage,
                         shouldBeRedirectingToAzureStorageConfigPage.RouteValues["provider"]);

            //seems like azure config worked, let's see if the conn string was actually saved

            Assert.Equal(azureBlobStorageConfiguration.ConnectionString, Assert
                         .IsType <AzureBlobStorageConfiguration>(Assert
                                                                 .IsType <ViewResult>(
                                                                     await controller.StorageProvider(StorageProvider.AzureBlobStorage.ToString()))
                                                                 .Model).ConnectionString);



            await UnitTest1.CanUploadRemoveFiles(controller);
        }
        public async Task PullTransifexTranslations()
        {
            // 1. Generate an API Token on https://www.transifex.com/user/settings/api/
            // 2. Run "dotnet user-secrets set TransifexAPIToken <youapitoken>"
            var client = new TransifexClient(FactWithSecretAttribute.GetFromSecrets("TransifexAPIToken"));
            var json   = await client.GetTransifexAsync("https://api.transifex.com/organizations/btcpayserver/projects/btcpayserver/resources/enjson/");

            var langs = new[] { "en" }.Concat(((JObject)json["stats"]).Properties().Select(n => n.Name)).ToArray();

            var langsDir = Path.Combine(TestUtils.TryGetSolutionDirectoryInfo().FullName, "BTCPayServer", "wwwroot", "locales");

            JObject sourceLang = null;

            Task.WaitAll(langs.Select(async l =>
            {
                bool isSourceLang = l == "en";
                var j             = await client.GetTransifexAsync($"https://www.transifex.com/api/2/project/btcpayserver/resource/enjson/translation/{l}/");
                if (!isSourceLang)
                {
                    while (sourceLang == null)
                    {
                        await Task.Delay(10);
                    }
                }
                var content = j["content"].Value <string>();
                if (l == "ne_NP")
                {
                    l = "np_NP";
                }
                if (l == "zh_CN")
                {
                    l = "zh-SP";
                }
                if (l == "kk")
                {
                    l = "kk-KZ";
                }

                var langCode = l.Replace("_", "-");
                var langFile = Path.Combine(langsDir, langCode + ".json");
                var jobj     = JObject.Parse(content);
                jobj["code"] = langCode;

                if ((string)jobj["currentLanguage"] == "English" && !isSourceLang)
                {
                    return; // Not translated
                }
                if ((string)jobj["currentLanguage"] == "disable")
                {
                    return; // Not translated
                }
                jobj.AddFirst(new JProperty("NOTICE_WARN", "THIS CODE HAS BEEN AUTOMATICALLY GENERATED FROM TRANSIFEX, IF YOU WISH TO HELP TRANSLATION COME ON THE SLACK http://slack.btcpayserver.org TO REQUEST PERMISSION TO https://www.transifex.com/btcpayserver/btcpayserver/"));
                if (isSourceLang)
                {
                    sourceLang = jobj;
                }
                else
                {
                    if (jobj["InvoiceExpired_Body_3"].Value <string>() == sourceLang["InvoiceExpired_Body_3"].Value <string>())
                    {
                        jobj["InvoiceExpired_Body_3"] = string.Empty;
                    }
                }
                content = jobj.ToString(Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(Path.Combine(langsDir, langFile), content);
            }).ToArray());
        }