Fix null pointer exception on receipt print page (#6045) (#6085)

This commit is contained in:
d11n 2024-07-10 17:11:04 +02:00 committed by GitHub
parent 372688b723
commit d73e26e0c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 30 deletions

View file

@ -2696,6 +2696,33 @@ namespace BTCPayServer.Tests
Assert.Contains("Total", sums[3].FindElement(By.CssSelector("th")).Text); Assert.Contains("Total", sums[3].FindElement(By.CssSelector("th")).Text);
Assert.Contains("1 222,21 €", sums[3].FindElement(By.CssSelector("td")).Text); Assert.Contains("1 222,21 €", sums[3].FindElement(By.CssSelector("td")).Text);
// Receipt print
s.Driver.FindElement(By.Id("ReceiptLinkPrint")).Click();
windows = s.Driver.WindowHandles;
Assert.Equal(3, windows.Count);
s.Driver.SwitchTo().Window(windows[2]);
var paymentDetails = s.Driver.WaitForElement(By.CssSelector("#PaymentDetails table"));
items = paymentDetails.FindElements(By.CssSelector("tr.cart-data"));
sums = paymentDetails.FindElements(By.CssSelector("tr.sums-data"));
Assert.Equal(2, items.Count);
Assert.Equal(4, sums.Count);
Assert.Contains("Manual entry 1", items[0].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("1 234,00 €", items[0].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Manual entry 2", items[1].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("0,56 €", items[1].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Subtotal", sums[0].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("1 234,56 €", sums[0].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Discount", sums[1].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("10% = 123,46 €", sums[1].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Tip", sums[2].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("10% = 111,11 €", sums[2].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Total", sums[3].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("1 222,21 €", sums[3].FindElement(By.CssSelector(".val")).Text);
s.Driver.Close();
s.Driver.SwitchTo().Window(windows[1]);
s.Driver.Close();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
// Once more with items // Once more with items
s.GoToUrl(editUrl); s.GoToUrl(editUrl);
s.Driver.FindElement(By.Id("ShowItems")).Click(); s.Driver.FindElement(By.Id("ShowItems")).Click();
@ -2733,7 +2760,6 @@ namespace BTCPayServer.Tests
// Receipt // Receipt
s.Driver.WaitForElement(By.Id("ReceiptLink")).Click(); s.Driver.WaitForElement(By.Id("ReceiptLink")).Click();
cartData = s.Driver.FindElement(By.CssSelector("#CartData table")); cartData = s.Driver.FindElement(By.CssSelector("#CartData table"));
items = cartData.FindElements(By.CssSelector("tbody tr")); items = cartData.FindElements(By.CssSelector("tbody tr"));
sums = cartData.FindElements(By.CssSelector("tfoot tr")); sums = cartData.FindElements(By.CssSelector("tfoot tr"));
@ -2748,6 +2774,27 @@ namespace BTCPayServer.Tests
Assert.Contains("Total", sums[0].FindElement(By.CssSelector("th")).Text); Assert.Contains("Total", sums[0].FindElement(By.CssSelector("th")).Text);
Assert.Contains("4,23 €", sums[0].FindElement(By.CssSelector("td")).Text); Assert.Contains("4,23 €", sums[0].FindElement(By.CssSelector("td")).Text);
// Receipt print
s.Driver.FindElement(By.Id("ReceiptLinkPrint")).Click();
windows = s.Driver.WindowHandles;
Assert.Equal(2, windows.Count);
s.Driver.SwitchTo().Window(windows[1]);
paymentDetails = s.Driver.WaitForElement(By.CssSelector("#PaymentDetails table"));
items = paymentDetails.FindElements(By.CssSelector("tr.cart-data"));
sums = paymentDetails.FindElements(By.CssSelector("tr.sums-data"));
Assert.Equal(3, items.Count);
Assert.Single(sums);
Assert.Contains("Black Tea", items[0].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("1 x 1,00 € = 1,00 €", items[0].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Green Tea", items[1].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("2 x 1,00 € = 2,00 €", items[1].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Manual entry 1", items[2].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("1,23 €", items[2].FindElement(By.CssSelector(".val")).Text);
Assert.Contains("Total", sums[0].FindElement(By.CssSelector(".key")).Text);
Assert.Contains("4,23 €", sums[0].FindElement(By.CssSelector(".val")).Text);
s.Driver.Close();
s.Driver.SwitchTo().Window(s.Driver.WindowHandles.First());
// Guest user can access recent transactions // Guest user can access recent transactions
s.GoToHome(); s.GoToHome();
s.Logout(); s.Logout();

View file

@ -82,7 +82,7 @@
</div> </div>
} }
</dl> </dl>
<a href="?print=true" class="flex-grow-0 align-self-start btn btn-secondary d-print-none fs-4" target="_blank">Print</a> <a href="?print=true" class="flex-grow-0 align-self-start btn btn-secondary d-print-none fs-4" target="_blank" id="ReceiptLinkPrint">Print</a>
</div> </div>
} }
</div> </div>

View file

@ -104,7 +104,7 @@
{ {
@foreach (var (key, value) in Model.AdditionalData) @foreach (var (key, value) in Model.AdditionalData)
{ {
<tr> <tr class="additional-data">
<td class="text-secondary">@key</td> <td class="text-secondary">@key</td>
<td class="text-end">@value</td> <td class="text-end">@value</td>
</tr> </tr>
@ -113,7 +113,7 @@
<td colspan="2"><hr class="w-100 my-0"/></td> <td colspan="2"><hr class="w-100 my-0"/></td>
</tr> </tr>
} }
@if (hasCart) @if (hasCart)
{ {
_ = Model.CartData.TryGetValue("cart", out var cart) || Model.CartData.TryGetValue("Cart", out cart); _ = Model.CartData.TryGetValue("cart", out var cart) || Model.CartData.TryGetValue("Cart", out cart);
var hasTotal = Model.CartData.TryGetValue("total", out var total) || Model.CartData.TryGetValue("Total", out total); var hasTotal = Model.CartData.TryGetValue("total", out var total) || Model.CartData.TryGetValue("Total", out total);
@ -124,9 +124,9 @@
{ {
@foreach (var (key, value) in cartDict) @foreach (var (key, value) in cartDict)
{ {
<tr> <tr class="cart-data">
<td class="text-secondary">@key</td> <td class="key text-secondary">@key</td>
<td class="text-end">@value</td> <td class="val text-end">@value</td>
</tr> </tr>
} }
} }
@ -135,7 +135,7 @@
@foreach (var value in cartCollection) @foreach (var value in cartCollection)
{ {
<tr> <tr>
<td class="text-end">@value</td> <td class="val text-end">@value</td>
</tr> </tr>
} }
} }
@ -144,23 +144,23 @@
<tr> <tr>
<td colspan="2"><hr class="w-100 my-0"/></td> <td colspan="2"><hr class="w-100 my-0"/></td>
</tr> </tr>
<tr> <tr class="sums-data">
<td class="text-secondary">Subtotal</td> <td class="key text-secondary">Subtotal</td>
<td class="text-end">@subtotal</td> <td class="val text-end">@subtotal</td>
</tr> </tr>
} }
if (hasDiscount) if (hasDiscount)
{ {
<tr> <tr class="sums-data">
<td class="text-secondary">Discount</td> <td class="key text-secondary">Discount</td>
<td class="text-end">@discount</td> <td class="val text-end">@discount</td>
</tr> </tr>
} }
if (hasTip) if (hasTip)
{ {
<tr> <tr class="sums-data">
<td class="text-secondary">Tip</td> <td class="key text-secondary">Tip</td>
<td class="text-end">@tip</td> <td class="val text-end">@tip</td>
</tr> </tr>
} }
if (hasTotal) if (hasTotal)
@ -168,17 +168,17 @@
<tr> <tr>
<td colspan="2"><hr class="w-100 my-0"/></td> <td colspan="2"><hr class="w-100 my-0"/></td>
</tr> </tr>
<tr> <tr class="sums-data">
<th class="text-secondary">Total</th> <td class="key text-secondary">Total</td>
<td class="text-end fw-semibold">@total</td> <td class="val text-end fw-semibold">@total</td>
</tr> </tr>
} }
} }
else else
{ {
<tr> <tr class="sums-data">
<td class="text-nowrap text-secondary">Total</td> <td class="key text-nowrap text-secondary">Total</td>
<td class="text-end fw-semibold">@DisplayFormatter.Currency(Model.Amount, Model.Currency, DisplayFormatter.CurrencyFormat.Symbol)</td> <td class="val text-end fw-semibold">@DisplayFormatter.Currency(Model.Amount, Model.Currency, DisplayFormatter.CurrencyFormat.Symbol)</td>
</tr> </tr>
} }
@if (Model.Payments?.Any() is true) @if (Model.Payments?.Any() is true)
@ -194,25 +194,25 @@
<tr> <tr>
<td colspan="2" class="text-nowrap text-secondary">Payment @(i + 1)</td> <td colspan="2" class="text-nowrap text-secondary">Payment @(i + 1)</td>
</tr> </tr>
<tr> <tr class="payment-data">
<td class="text-nowrap">Received</td> <td class="text-nowrap">Received</td>
<td>@payment.ReceivedDate.ToBrowserDate()</td> <td>@payment.ReceivedDate.ToBrowserDate()</td>
</tr> </tr>
} }
<tr> <tr class="payment-data">
<td class="text-nowrap text-secondary">@(Model.Payments.Count == 1 ? "Paid" : "")</td> <td class="text-nowrap text-secondary">@(Model.Payments.Count == 1 ? "Paid" : "")</td>
<td class="text-end">@payment.AmountFormatted</td> <td class="text-end">@payment.AmountFormatted</td>
</tr> </tr>
<tr> <tr class="payment-data">
<td colspan="2" class="text-end">@payment.PaidFormatted</td> <td colspan="2" class="text-end">@payment.PaidFormatted</td>
</tr> </tr>
<tr> <tr class="payment-data">
<td class="text-nowrap text-secondary">Rate</td> <td class="text-nowrap text-secondary">Rate</td>
<td class="text-end">@payment.RateFormatted</td> <td class="text-end">@payment.RateFormatted</td>
</tr> </tr>
@if (!string.IsNullOrEmpty(payment.Destination)) @if (!string.IsNullOrEmpty(payment.Destination))
{ {
<tr> <tr class="payment-data">
<td class="text-nowrap text-secondary">Destination</td> <td class="text-nowrap text-secondary">Destination</td>
<td class="text-break"> <td class="text-break">
@if (payment.Destination.Length > 69) @if (payment.Destination.Length > 69)
@ -232,7 +232,7 @@
} }
@if (!string.IsNullOrEmpty(payment.PaymentProof)) @if (!string.IsNullOrEmpty(payment.PaymentProof))
{ {
<tr> <tr class="payment-data">
<td class="text-nowrap text-secondary">Pay Proof</td> <td class="text-nowrap text-secondary">Pay Proof</td>
<td class="text-break">@payment.PaymentProof</td> <td class="text-break">@payment.PaymentProof</td>
</tr> </tr>