using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BTCPayServer.Abstractions.Form; using BTCPayServer.Forms; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Primitives; using Newtonsoft.Json.Linq; using Xunit; using Xunit.Abstractions; namespace BTCPayServer.Tests; [Collection(nameof(NonParallelizableCollectionDefinition))] [Trait("Integration", "Integration")] public class FormTests : UnitTestBase { public FormTests(ITestOutputHelper helper) : base(helper) { } [Fact(Timeout = TestUtils.TestTimeout)] [Trait("Integration", "Integration")] public async Task CanParseForm() { using var tester = CreateServerTester(); await tester.StartAsync(); var user = tester.NewAccount(); user.GrantAccess(); var service = tester.PayTester.GetService(); var form = new Form() { Fields = new List { Field.Create("Enter your email", "item1", 1.ToString(), true, null, "email"), Field.Create("Name", "item2", 2.ToString(), true, null), Field.Create("Name", "invoice_test", 2.ToString(), true, null), new Field { Name = "invoice", Type = "fieldset", Fields = new List { Field.Create("Name", "test", 3.ToString(), true, null), Field.Create("Name", "item4", 4.ToString(), true, null), Field.Create("Name", "item5", 5.ToString(), true, null), } } } }; Assert.False(service.IsFormSchemaValid(form.ToString(), out _, out _)); form = new Form { Fields = new List { Field.Create("Enter your email", "item1", 1.ToString(), true, null, "email"), Field.Create("Name", "item2", 2.ToString(), true, null), Field.Create("Name", "invoice_item3", 2.ToString(), true, null), new Field { Name = "invoice", Type = "fieldset", Fields = new List {Field.Create("Name", "test", 3.ToString(), true, null),} } } }; Assert.True(service.IsFormSchemaValid(form.ToString(), out _, out _)); form.ApplyValuesFromForm(new FormCollection(new Dictionary() { {"item1", new StringValues("updated")}, {"item2", new StringValues("updated")}, {"invoice_item3", new StringValues("updated")}, {"invoice_test", new StringValues("updated")} })); foreach (var f in form.GetAllFields()) { if (f.Field.Type == "fieldset") continue; Assert.Equal("updated", f.Field.Value); } form = new Form() { Fields = new List { Field.Create("Enter your email", "item1", 1.ToString(), true, null, "email"), Field.Create("Name", "item2", 2.ToString(), true, null), Field.Create("Name", "invoice_item3", 2.ToString(), true, null), new Field { Name = "invoice", Type = "fieldset", Fields = new List { new() {Name = "test", Type = "text", Constant = true, Value = "original"} } } } }; form.ApplyValuesFromForm(new FormCollection(new Dictionary() { {"item1", new StringValues("updated")}, {"item2", new StringValues("updated")}, {"invoice_item3", new StringValues("updated")}, {"invoice_test", new StringValues("updated")} })); foreach (var f in form.GetAllFields()) { var field = f.Field; if (field.Type == "fieldset") continue; switch (f.FullName) { case "invoice_test": Assert.Equal("original", field.Value); break; default: Assert.Equal("updated", field.Value); break; } } form = new Form() { Fields = new List { Field.Create("Enter your email", "item1", 1.ToString(), true, null, "email"), Field.Create("Name", "item2", 2.ToString(), true, null), Field.Create("Name", "invoice_item3", 2.ToString(), true, null), new Field { Name = "invoice", Type = "fieldset", Constant = true, Fields = new List { new() {Name = "test", Type = "text", Value = "original"} } } } }; form.ApplyValuesFromForm(new FormCollection(new Dictionary() { {"item1", new StringValues("updated")}, {"item2", new StringValues("updated")}, {"invoice_item3", new StringValues("updated")}, {"invoice_test", new StringValues("updated")} })); foreach (var f in form.GetAllFields()) { var field = f.Field; if (field.Type == "fieldset") continue; switch (f.FullName) { case "invoice_test": Assert.Equal("original", field.Value); break; default: Assert.Equal("updated", field.Value); break; } } var obj = service.GetValues(form); Assert.Equal("original", obj["invoice"]["test"].Value()); Assert.Equal("updated", obj["invoice_item3"].Value()); Clear(form); service.SetValues(form, obj); obj = service.GetValues(form); Assert.Equal("original", obj["invoice"]["test"].Value()); Assert.Equal("updated", obj["invoice_item3"].Value()); form = new Form() { Fields = new List(){ new Field { Type = "fieldset", Fields = new List { new() {Name = "test", Type = "text"} } } } }; service.SetValues(form, obj); obj = service.GetValues(form); Assert.Null(obj["test"].Value()); service.SetValues(form, new JObject { ["test"] = "hello" }); obj = service.GetValues(form); Assert.Equal("hello", obj["test"].Value()); } private void Clear(Form form) { foreach (var f in form.Fields.Where(f => !f.Constant)) f.Value = null; } }