Added first basic comments test

This commit is contained in:
Simon Backx 2022-08-11 16:40:04 +02:00
parent 3b7d26154e
commit fd21a88d52
6 changed files with 85 additions and 65 deletions

View File

@ -1,8 +1,7 @@
import Frame from './components/Frame';
import * as Sentry from '@sentry/react';
import React from 'react';
import ActionHandler from './actions';
import {createPopupNotification,isSentryEventAllowed} from './utils/helpers';
import {createPopupNotification} from './utils/helpers';
import AppContext from './AppContext';
import {hasMode} from './utils/check-mode';
import setupGhostApi from './utils/api';
@ -21,20 +20,14 @@ function AuthFrame({adminUrl, onLoad}) {
function CommentsBoxContainer({done, appVersion}) {
return (
<Frame>
<Frame title="comments-box">
<CommentsBox done={done} />
</Frame>
);
}
function SentryErrorBoundary({dsn, children}) {
if (dsn) {
return (
<Sentry.ErrorBoundary>
{children}
</Sentry.ErrorBoundary>
);
}
// todo: add Sentry.ErrorBoundary wrapper if Sentry is enabled
return (
<>
{children}
@ -68,11 +61,10 @@ export default class App extends React.Component {
async initSetup() {
try {
// Fetch data from API, links, preview, dev sources
const {site, member} = await this.fetchApiData();
const {member} = await this.fetchApiData();
const {comments, pagination, count} = await this.fetchComments();
const state = {
site,
member,
action: 'init:success',
initStatus: 'success',
@ -159,10 +151,10 @@ export default class App extends React.Component {
try {
this.GhostApi = this.props.api || setupGhostApi({siteUrl, apiUrl, apiKey});
const {site, member} = await this.GhostApi.init();
const {member} = await this.GhostApi.init();
this.setupSentry({site});
return {site, member};
this.setupSentry();
return {member};
} catch (e) {
if (hasMode(['dev', 'test'], {customSiteUrl})) {
return {};
@ -254,30 +246,8 @@ export default class App extends React.Component {
}
/** Setup Sentry */
setupSentry({site}) {
if (hasMode(['test'])) {
return null;
}
const {portal_sentry: portalSentry, portal_version: portalVersion, version: ghostVersion} = site;
const appVersion = process.env.REACT_APP_VERSION || portalVersion;
const releaseTag = `comments@${appVersion}|ghost@${ghostVersion}`;
if (portalSentry && portalSentry.dsn) {
Sentry.init({
dsn: portalSentry.dsn,
environment: portalSentry.env || 'development',
release: releaseTag,
beforeSend: (event) => {
if (isSentryEventAllowed({event})) {
return event;
}
return null;
},
allowUrls: [
/https?:\/\/((www)\.)?unpkg\.com\/@tryghost\/comments/,
/https?:\/\/((cdn)\.)?jsdelivr\.net\/npm\/@tryghost\/comments/
]
});
}
setupSentry() {
// Not implemented yet
}
/**Get final App level context from App state*/

View File

@ -1,8 +1,78 @@
import {render} from '@testing-library/react';
import {render, within} from '@testing-library/react';
import App from './App';
import {ROOT_DIV_ID} from './utils/constants';
test('renders the auth frame', () => {
/*test('renders the auth frame', () => {
const {container} = render(<App />);
const iframeElement = container.querySelector('iframe[data-frame="admin-auth"]');
expect(iframeElement).toBeInTheDocument();
});*/
describe('Dark mode', () => {
it.todo('uses dark mode when container has a dark background');
it.todo('uses light mode when container has a light background');
it.todo('uses custom mode when custom mode has been passed as a property');
});
describe('Comments', () => {
it('renders comments', async () => {
const postId = 'my-post';
const member = null;
const api = {
init: async () => {
return {
member
};
},
comments: {
count: async () => {
return {
[postId]: 1
};
},
browse: async () => {
return {
comments: [
{
id: 'test',
html: '<p>This is a comment body</p>',
replies: [],
count: {
replies: 0,
likes: 0
},
liked: false,
created_at: '2022-08-11T09:26:34.000Z',
edited_at: null,
member: {
avatar_image: '',
bio: 'Hello world codoof',
id: '62d6c6564a14e6a4b5e97c43',
name: 'dtt2',
uuid: '613e9667-4fa2-4ff4-aa62-507220103d41'
},
status: 'published'
}
],
meta: {
pagination: {
total: 1,
next: null,
prev: null,
page: 1
}
}
};
}
}
};
const stylesUrl = '';
const {container} = render(<div><div id={ROOT_DIV_ID}></div><App api={api} stylesUrl={stylesUrl}/></div>);
const iframeElement = container.querySelector('iframe[title="comments-box"]');
expect(iframeElement).toBeInTheDocument();
const iframeDocument = iframeElement.contentDocument;
const commentBody = await within(iframeDocument).findByText(/This is a comment body/i);
expect(commentBody).toBeInTheDocument();
});
});

View File

@ -81,7 +81,7 @@ const CommentsBoxContent = (props) => {
<>
<CommentsBoxTitle title={title} showCount={showCount} count={commentCount}/>
<Pagination />
<div className={!pagination ? 'mt-4' : ''}>
<div className={!pagination ? 'mt-4' : ''} data-test="comment-elements">
{commentsElements}
</div>
<div>

View File

@ -49,7 +49,7 @@ const Frame = ({
});
};
const [cssLoaded, setCssLoaded] = useState(false);
const [cssLoaded, setCssLoaded] = useState(!stylesUrl);
const onLoadCSS = () => {
setCssLoaded(true);
@ -57,7 +57,7 @@ const Frame = ({
const head = (
<>
<link rel="stylesheet" href={stylesUrl} onLoad={onLoadCSS} />
{stylesUrl ? <link rel="stylesheet" href={stylesUrl} onLoad={onLoadCSS} /> : null}
<style dangerouslySetInnerHTML={{__html: styles}} />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
</>

View File

@ -259,20 +259,8 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) {
let [member] = await Promise.all([
api.member.sessionData()
]);
let site = {};
let settings = {};
try {
// for now we don't need to fetch all the settings (the ones we need are passed via the script tag data attributes)
//settings = await api.site.settings();
site = {
...settings
};
} catch (e) {
// Ignore
}
site = transformApiSiteData({site});
return {site, member};
return {member};
};
return api;

View File

@ -15,14 +15,6 @@ export const createPopupNotification = ({type, status, autoHide, duration = 2600
};
};
export function transformApiSiteData({site}) {
if (!site) {
return null;
}
return site;
}
export function isSentryEventAllowed({event: sentryEvent}) {
const frames = sentryEvent?.exception?.values?.[0]?.stacktrace?.frames || [];
const fileNames = frames.map(frame => frame.filename).filter(filename => !!filename);