feat(addons): finalize event addon catalog and ai styling upgrade flow
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-02-07 12:35:07 +01:00
parent 8cc0918881
commit d2808ffa4f
36 changed files with 1372 additions and 457 deletions

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { describe, expect, it, vi } from 'vitest';
import { render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
const fixtures = vi.hoisted(() => ({
event: {
@@ -23,7 +23,14 @@ const fixtures = vi.hoisted(() => ({
is_active: true,
},
invites: [],
addons: [],
addons: [
{
key: 'extend_gallery_30d',
label: 'Galerie um 30 Tage verlängern',
price_id: 'price_30d',
increments: { extra_gallery_days: 30 },
},
],
}));
vi.mock('react-router-dom', () => ({
@@ -60,7 +67,11 @@ vi.mock('../../api', () => ({
getEventQrInvites: vi.fn().mockResolvedValue(fixtures.invites),
getAddonCatalog: vi.fn().mockResolvedValue(fixtures.addons),
updateEvent: vi.fn().mockResolvedValue(fixtures.event),
createEventAddonCheckout: vi.fn(),
createEventAddonCheckout: vi.fn().mockResolvedValue({
checkout_url: null,
checkout_id: 'chk_123',
expires_at: null,
}),
getEventEngagement: vi.fn().mockResolvedValue({
summary: { totalPhotos: 0, uniqueGuests: 0, tasksSolved: 0, likesTotal: 0 },
leaderboards: { uploads: [], likes: [] },
@@ -87,7 +98,11 @@ vi.mock('../components/MobileShell', () => ({
vi.mock('../components/Primitives', () => ({
MobileCard: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
CTAButton: ({ label }: { label: string }) => <button type="button">{label}</button>,
CTAButton: ({ label, onPress }: { label: string; onPress?: () => void }) => (
<button type="button" onClick={onPress}>
{label}
</button>
),
PillBadge: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
SkeletonCard: () => <div>Loading...</div>,
}));
@@ -101,7 +116,13 @@ vi.mock('../components/FormControls', () => ({
}));
vi.mock('../components/LegalConsentSheet', () => ({
LegalConsentSheet: () => <div />,
LegalConsentSheet: ({
open,
onConfirm,
}: {
open: boolean;
onConfirm: (consents: { acceptedTerms: boolean; acceptedWaiver: boolean }) => void;
}) => (open ? <button type="button" onClick={() => onConfirm({ acceptedTerms: true, acceptedWaiver: true })}>Confirm legal</button> : null),
}));
vi.mock('@tamagui/stacks', () => ({
@@ -164,8 +185,21 @@ vi.mock('../theme', () => ({
}));
import MobileEventRecapPage from '../EventRecapPage';
import { createEventAddonCheckout } from '../../api';
describe('MobileEventRecapPage', () => {
beforeEach(() => {
fixtures.addons = [
{
key: 'extend_gallery_30d',
label: 'Galerie um 30 Tage verlängern',
price_id: 'price_30d',
increments: { extra_gallery_days: 30 },
},
];
vi.clearAllMocks();
});
it('renders recap settings toggles', async () => {
render(<MobileEventRecapPage />);
@@ -173,4 +207,26 @@ describe('MobileEventRecapPage', () => {
expect(screen.getByLabelText('Gäste dürfen Fotos laden')).toBeInTheDocument();
expect(screen.getByLabelText('Gäste dürfen Fotos teilen')).toBeInTheDocument();
});
it('requires consent and sends both legal acceptance flags for recap addon checkout', async () => {
const checkoutMock = vi.mocked(createEventAddonCheckout);
render(<MobileEventRecapPage />);
const checkoutButton = await screen.findByRole('button', { name: 'Galerie um 30 Tage verlängern' });
fireEvent.click(checkoutButton);
expect(checkoutMock).not.toHaveBeenCalled();
fireEvent.click(await screen.findByRole('button', { name: 'Confirm legal' }));
await waitFor(() => {
expect(checkoutMock).toHaveBeenCalledWith(fixtures.event.slug, {
addon_key: 'extend_gallery_30d',
success_url: window.location.href,
cancel_url: window.location.href,
accepted_terms: true,
accepted_waiver: true,
});
});
});
});