Verse of the day with picture backgrounds, shareable image, and study covers
Build and Push Docker Image / build-and-push (push) Failing after 21s
Build and Push Docker Image / build-and-push (push) Failing after 21s
- Verse of the day: card over a picture (a different one each day, or chosen), 12 drawn scenes plus photos from public/verse-backgrounds, and "Share as image" (also on the Reader's verse panel) that saves or shares a PNG with the same background, a theme look, or a photo from the device - Study cards get a cover banner named for the book, coloured by kind of book - Outline "Build from my notes": abbreviations like "A.D. 63." no longer end a sentence Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d2bbf1feb4
commit
aabd4267b8
15 files changed
+826
-8
No files matched your search
@@ -0,0 +1,65 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { vi, test, expect, beforeEach } from 'vitest';
|
||||
|
||||
vi.mock('../utils/verseCard.js', async (orig) => ({
|
||||
...(await orig()),
|
||||
renderVerseCard: vi.fn(async () => new Blob(['png'], { type: 'image/png' })),
|
||||
shareOrSaveImage: vi.fn(async () => 'saved'),
|
||||
}));
|
||||
vi.mock('./Toasts.jsx', () => ({ useToast: () => ({ toast: vi.fn() }) }));
|
||||
import VerseShareImage from './VerseShareImage.jsx';
|
||||
import { renderVerseCard, shareOrSaveImage } from '../utils/verseCard.js';
|
||||
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
vi.clearAllMocks();
|
||||
URL.createObjectURL = vi.fn(() => 'blob:card');
|
||||
URL.revokeObjectURL = vi.fn();
|
||||
});
|
||||
|
||||
const props = { text: 'For God so loved the world.', reference: 'John 3:16', translation: 'BSB' };
|
||||
|
||||
test('previews the card, redraws when the look changes, and remembers the look', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<VerseShareImage {...props} />);
|
||||
expect(await screen.findByAltText(/John 3:16 \(BSB\) as a picture/)).toBeInTheDocument();
|
||||
expect(renderVerseCard).toHaveBeenLastCalledWith(expect.objectContaining({ themeId: 'paper', reference: 'John 3:16' }));
|
||||
await user.click(screen.getByRole('button', { name: 'Dark' }));
|
||||
await screen.findByAltText(/as a picture/);
|
||||
expect(renderVerseCard).toHaveBeenLastCalledWith(expect.objectContaining({ themeId: 'dark' }));
|
||||
expect(localStorage.getItem('verse-card-style')).toBe('dark');
|
||||
});
|
||||
|
||||
test('Save/Share sends the image under a file name from the reference', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<VerseShareImage {...props} />);
|
||||
await screen.findByAltText(/as a picture/);
|
||||
await user.click(screen.getByRole('button', { name: /save image|share image/i }));
|
||||
expect(shareOrSaveImage).toHaveBeenCalledWith(expect.any(Blob), 'john-3-16.png', expect.objectContaining({ title: 'John 3:16' }));
|
||||
});
|
||||
|
||||
test('says so if the picture can\'t be drawn', async () => {
|
||||
renderVerseCard.mockRejectedValueOnce(new Error('This browser can’t draw the image.'));
|
||||
render(<VerseShareImage {...props} />);
|
||||
expect(await screen.findByRole('alert')).toHaveTextContent(/can’t draw/);
|
||||
});
|
||||
|
||||
test('a background picture can be chosen, and is passed to the card; the plain looks come back with Plain', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<VerseShareImage {...props} />);
|
||||
await screen.findByAltText(/as a picture/);
|
||||
expect(screen.getByRole('group', { name: /image style/i })).toBeInTheDocument();
|
||||
await user.selectOptions(screen.getByLabelText('Image background'), 'sea');
|
||||
await screen.findByAltText(/as a picture/);
|
||||
expect(renderVerseCard).toHaveBeenLastCalledWith(expect.objectContaining({ background: { kind: 'scene', id: 'sea' } }));
|
||||
expect(screen.queryByRole('group', { name: /image style/i })).toBeNull(); // theme looks only apply to the plain card
|
||||
await user.selectOptions(screen.getByLabelText('Image background'), 'plain');
|
||||
expect(renderVerseCard).toHaveBeenLastCalledWith(expect.objectContaining({ background: null }));
|
||||
});
|
||||
|
||||
test('the picture of the day is used when the Home card passes it in', async () => {
|
||||
render(<VerseShareImage {...props} defaultBackground="auto" />);
|
||||
await screen.findByAltText(/as a picture/);
|
||||
expect(renderVerseCard).toHaveBeenLastCalledWith(expect.objectContaining({ background: expect.objectContaining({ kind: 'scene' }) }));
|
||||
});
|
||||
Reference in new issue
Block a user