fix(guest): make Swish QR scannable on guest payment page (#22) #25

Open
hermes wants to merge 1 commit from fix/guest-qr-scannability into master
2 changed files with 16 additions and 6 deletions
Showing only changes of commit b4fdcbff9e - Show all commits

View file

@ -124,12 +124,16 @@ describe('GuestPaymentRedirect', () => {
}) })
}) })
it('renders QR code after loading swish info', async () => { it('renders QR code with spec-compliant settings', async () => {
const { wrapper } = await mountPage() const { wrapper } = await mountPage()
await vi.waitFor(() => { await vi.waitFor(() => {
expect(wrapper.find('.payment__qr-img').exists()).toBe(true) expect(wrapper.find('.payment__qr-img').exists()).toBe(true)
}) })
expect(mockToDataURL).toHaveBeenCalledTimes(1) expect(mockToDataURL).toHaveBeenCalledTimes(1)
const options = mockToDataURL.mock.calls[0][1]
expect(options.margin).toBe(4)
expect(options.width).toBe(288)
expect(options.color).toEqual({ dark: '#000000', light: '#ffffff' })
}) })
it('renders Swish payment link', async () => { it('renders Swish payment link', async () => {

View file

@ -52,9 +52,15 @@ onMounted(async () => {
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
if (swishPaymentUrl.value) { if (swishPaymentUrl.value) {
qrDataUrl.value = await QRCode.toDataURL(swishPaymentUrl.value, { qrDataUrl.value = await QRCode.toDataURL(swishPaymentUrl.value, {
width: 224, // Swish requires a reliably scannable black-on-white QR. The previous
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
margin: 2, // settings (margin 2, #111827, 224px) produced a 2-module quiet zone
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
color: { dark: '#111827', light: '#ffffff' }, // half the QR spec minimum which the Swish app's scanner fails to
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// read when scanning off a screen. Use the spec-compliant 4-module
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
// quiet zone, pure black, and larger modules.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
width: 288,
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
margin: 4,
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
errorCorrectionLevel: 'M',
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
color: { dark: '#000000', light: '#ffffff' },
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
}) })
} }
} catch { } catch {
@ -269,8 +275,8 @@ async function confirmPayment() {
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
} }
.payment__qr-img { .payment__qr-img {
width: 224px; width: 288px;
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
height: 224px; height: 288px;
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
border-radius: var(--radius-md); border-radius: var(--radius-md);
margin: 0 auto var(--space-sm); margin: 0 auto var(--space-sm);
} }

Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.
Review

💡 Suggestion: The test asserts margin, width, and color but not errorCorrectionLevel: 'M'. Consider adding expect(options.errorCorrectionLevel).toBe('M') to GuestPaymentRedirect.spec.ts to guard against silent regression on this parameter.

💡 **Suggestion:** The test asserts `margin`, `width`, and `color` but not `errorCorrectionLevel: 'M'`. Consider adding `expect(options.errorCorrectionLevel).toBe('M')` to `GuestPaymentRedirect.spec.ts` to guard against silent regression on this parameter.
Review

💡 Suggestion (DRY): The QR options object (width, margin, errorCorrectionLevel, color) is now duplicated verbatim between this file and PaymentRedirect.vue. This duplication is how the original bug happened. Consider extracting a shared QR_OPTIONS constant (e.g., in @/api/payment.ts) so both payment pages use the same source of truth.

💡 **Suggestion (DRY):** The QR options object (`width`, `margin`, `errorCorrectionLevel`, `color`) is now duplicated verbatim between this file and `PaymentRedirect.vue`. This duplication is how the original bug happened. Consider extracting a shared `QR_OPTIONS` constant (e.g., in `@/api/payment.ts`) so both payment pages use the same source of truth.