forked from Qortal/q-blog
140 lines
4.7 KiB
TypeScript
140 lines
4.7 KiB
TypeScript
import React from 'react';
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
import { configureStore } from '@reduxjs/toolkit';
|
|
import { Provider } from 'react-redux';
|
|
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
|
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { http, HttpResponse } from 'msw';
|
|
|
|
import { CreatePost } from '@/pages/CreatePost/CreatePost';
|
|
import notificationsReducer from '@/state/features/notificationsSlice';
|
|
import authReducer, { addUser } from '@/state/features/authSlice';
|
|
import globalReducer, { setCurrentBlog } from '@/state/features/globalSlice';
|
|
import blogReducer from '@/state/features/blogSlice';
|
|
import mailReducer from '@/state/features/mailSlice';
|
|
import bookmarksReducer from '@/state/features/bookmarksSlice';
|
|
import { server } from '../msw/server';
|
|
|
|
const createTestStore = () =>
|
|
configureStore({
|
|
reducer: {
|
|
notifications: notificationsReducer,
|
|
auth: authReducer,
|
|
global: globalReducer,
|
|
blog: blogReducer,
|
|
mail: mailReducer,
|
|
bookmarks: bookmarksReducer,
|
|
},
|
|
middleware: (getDefaultMiddleware) =>
|
|
getDefaultMiddleware({
|
|
serializableCheck: false,
|
|
}),
|
|
});
|
|
|
|
type TestStore = ReturnType<typeof createTestStore>;
|
|
|
|
const renderCreatePost = (store: TestStore) =>
|
|
render(
|
|
<Provider store={store}>
|
|
<ThemeProvider theme={createTheme()}>
|
|
<MemoryRouter initialEntries={[`/post/new`]}>
|
|
<Routes>
|
|
<Route path="/post/new" element={<CreatePost />} />
|
|
</Routes>
|
|
</MemoryRouter>
|
|
</ThemeProvider>
|
|
</Provider>,
|
|
);
|
|
|
|
const selectMinimalEditor = async () => {
|
|
const user = userEvent.setup();
|
|
const option = await screen.findByText('Minimal Editor');
|
|
await user.click(option);
|
|
await screen.findByPlaceholderText('Title');
|
|
return user;
|
|
};
|
|
|
|
describe('CreatePost (new publish flow)', () => {
|
|
const categoriesHandler = http.get('/arbitrary/categories', () => HttpResponse.json([]));
|
|
|
|
it('surfaces an error when no blog is selected', async () => {
|
|
server.use(categoriesHandler);
|
|
const store = createTestStore();
|
|
globalThis.qortalRequest = vi.fn().mockResolvedValue({ ok: true });
|
|
store.dispatch(addUser({ address: 'QADDR', publicKey: 'PUB', name: 'alice' }));
|
|
|
|
renderCreatePost(store);
|
|
const user = await selectMinimalEditor();
|
|
|
|
const titleField = await screen.findByPlaceholderText('Title');
|
|
await user.type(titleField, 'Unsaved Draft');
|
|
|
|
const publishTrigger = await screen.findByRole('button', { name: /^Publish$/i });
|
|
await user.click(publishTrigger);
|
|
|
|
const submitButton = await screen.findByRole('button', { name: /Submit/i });
|
|
await user.click(submitButton);
|
|
|
|
await waitFor(() => {
|
|
expect(store.getState().notifications.alertTypes.alertError).toBe(
|
|
'Cannot determine which blog to publish to. Open your blog and try again.',
|
|
);
|
|
});
|
|
expect(globalThis.qortalRequest).not.toHaveBeenCalled();
|
|
}, 10000);
|
|
|
|
it('publishes a new post when currentBlog is available', async () => {
|
|
server.use(categoriesHandler);
|
|
const store = createTestStore();
|
|
globalThis.qortalRequest = vi.fn().mockResolvedValue({ ok: true });
|
|
store.dispatch(addUser({ address: 'QADDR', publicKey: 'PUB', name: 'alice' }));
|
|
store.dispatch(
|
|
setCurrentBlog({
|
|
createdAt: Date.now(),
|
|
blogId: 'q-blog-myblog',
|
|
title: 'My Blog',
|
|
description: '',
|
|
blogImage: '',
|
|
category: '',
|
|
tags: [],
|
|
wikiEnabled: false,
|
|
editorWhitelist: [],
|
|
editorBlacklist: [],
|
|
}),
|
|
);
|
|
|
|
renderCreatePost(store);
|
|
const user = await selectMinimalEditor();
|
|
|
|
const titleField = await screen.findByPlaceholderText('Title');
|
|
await user.type(titleField, 'My New Post');
|
|
|
|
const publishTrigger = await screen.findByRole('button', { name: /^Publish$/i });
|
|
await user.click(publishTrigger);
|
|
|
|
const submitButton = await screen.findByRole('button', { name: /Submit/i });
|
|
await user.click(submitButton);
|
|
|
|
await waitFor(() => {
|
|
expect(globalThis.qortalRequest).toHaveBeenCalled();
|
|
});
|
|
|
|
const publishCall = (globalThis.qortalRequest as any).mock.calls.find(
|
|
(call: any[]) => call[0]?.action === 'PUBLISH_QDN_RESOURCE',
|
|
);
|
|
expect(publishCall).toBeTruthy();
|
|
expect(publishCall?.[0]).toMatchObject({
|
|
action: 'PUBLISH_QDN_RESOURCE',
|
|
service: 'BLOG_POST',
|
|
});
|
|
expect(publishCall?.[0]?.identifier.startsWith('q-blog-myblog-post-')).toBe(true);
|
|
await waitFor(() => {
|
|
expect(store.getState().notifications.alertTypes.alertSuccess).toBe(
|
|
'Blog post successfully published',
|
|
);
|
|
});
|
|
}, 10000);
|
|
});
|