diff --git a/frontend/src/pages/Admin/FeedPreview.js b/frontend/src/pages/Admin/FeedPreview.js new file mode 100644 index 0000000000..a9e4ab2528 --- /dev/null +++ b/frontend/src/pages/Admin/FeedPreview.js @@ -0,0 +1,158 @@ +import React, { useState, useRef } from 'react'; +import { + ButtonGroup, + Button, + Form, + FormGroup, + Label, + TextInput, +} from '@trussworks/react-uswds'; +import ContentFromFeedByTag from '../../components/ContentFromFeedByTag'; +import Container from '../../components/Container'; +import DrawerTriggerButton from '../../components/DrawerTriggerButton'; +import Drawer from '../../components/Drawer'; + +export default function FeedPreview() { + const [title, setTitle] = useState(''); + const [tag, setTag] = useState(''); + const [contentSelector, setContentSelector] = useState(''); + const [cssClass, setCssClass] = useState(''); + const drawerTriggerRef = useRef(null); + + const onSubmit = (e) => { + e.preventDefault(); + const data = new FormData(e.target); + setTitle(data.get('title')); + setTag(data.get('tag')); + setContentSelector(data.get('contentSelector')); + setCssClass(data.get('cssClass')); + }; + + const onReset = () => { + setTitle(''); + setTag(''); + setContentSelector(''); + setCssClass(''); + }; + + return ( + +

Preview confluence RSS feed

+ {' '} + {tag && ( + <> + + Preview drawer + + + + + + + )} +
+
+ More info +

+ The CSS class is used to style the feed preview by the engineers. + The option to add it here is so that you can preview changes to existing feeds. + (It won't do anything unless an engineer has already + added corresponding styles.) +

+
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Existing drawer configuration +
Drawer titleTagContent selectorCSS class
Support typettahub-tta-support-typetablettahub-drawer--objective-support-type-guidance
Objective topicsttahub-topictablettahub-drawer--objective-topics-guidance
Class review first sectionttahub-class-thresholdsdiv:nth-child(3)ttahub-class-feed-article
Class review second sectionttahub-class-thresholdsdiv:nth-child(4)ttahub-class-feed-article
+ +
+ ); +} diff --git a/frontend/src/pages/Admin/__tests__/FeedPreview.js b/frontend/src/pages/Admin/__tests__/FeedPreview.js new file mode 100644 index 0000000000..52c28f6918 --- /dev/null +++ b/frontend/src/pages/Admin/__tests__/FeedPreview.js @@ -0,0 +1,51 @@ +import '@testing-library/jest-dom'; +import React from 'react'; +import { + render, screen, act, + waitFor, +} from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import fetchMock from 'fetch-mock'; +import join from 'url-join'; +import FeedPreview from '../FeedPreview'; +import { mockRSSData } from '../../../testHelpers'; + +const tagUrl = join('/', 'api', 'feeds', 'item', '?tag=tag'); + +describe('FeedPreview', () => { + const renderTest = () => { + render(); + }; + + afterEach(() => fetchMock.restore()); + + it('renders page and submits form', async () => { + fetchMock.get(tagUrl, mockRSSData()); + act(() => { + renderTest(); + }); + + userEvent.type(await screen.findByLabelText('Tag'), 'tag'); + userEvent.type(await screen.findByLabelText('Title'), 'title'); + userEvent.type(await screen.findByLabelText('Content selector'), 'contentSelector'); + userEvent.type(await screen.findByLabelText('CSS class'), 'cssClass'); + + userEvent.click(await screen.findByRole('button', { name: 'Reset' })); + + expect(await screen.findByLabelText('Tag')).toHaveValue(''); + expect(await screen.findByLabelText('Title')).toHaveValue(''); + expect(await screen.findByLabelText('Content selector')).toHaveValue(''); + expect(await screen.findByLabelText('CSS class')).toHaveValue(''); + + userEvent.type(await screen.findByLabelText('Tag'), 'tag'); + userEvent.type(await screen.findByLabelText('Title'), 'title'); + userEvent.type(await screen.findByLabelText('Content selector'), 'contentSelector'); + userEvent.type(await screen.findByLabelText('CSS class'), 'cssClass'); + + act(() => { + userEvent.click(screen.getByRole('button', { name: 'Save changes' })); + }); + + await waitFor(() => expect(fetchMock.called(tagUrl)).toBe(true)); + }); +}); diff --git a/frontend/src/pages/Admin/__tests__/index.js b/frontend/src/pages/Admin/__tests__/index.js index 2f47dbaa57..06250b80b5 100644 --- a/frontend/src/pages/Admin/__tests__/index.js +++ b/frontend/src/pages/Admin/__tests__/index.js @@ -97,4 +97,16 @@ describe('Admin landing page', () => { const heading = await screen.findByRole('heading', { name: /national centers/i }); expect(heading).toBeVisible(); }); + + it('displays the feed preview page', async () => { + history.push('/admin/feed-preview'); + render( + + + , + ); + + const heading = await screen.findByRole('heading', { name: /Preview confluence RSS feed/i }); + expect(heading).toBeVisible(); + }); }); diff --git a/frontend/src/pages/Admin/index.js b/frontend/src/pages/Admin/index.js index bf90a595c6..e0c76fce71 100644 --- a/frontend/src/pages/Admin/index.js +++ b/frontend/src/pages/Admin/index.js @@ -13,13 +13,14 @@ import SS from './SS'; import TrainingReports from './TrainingReports'; import Courses from './Courses'; import CourseEdit from './CourseEdit'; +import FeedPreview from './FeedPreview'; function Admin() { return ( <>

Admin

Support

-
+
CDI grants @@ -50,6 +51,9 @@ function Admin() { SS + + Confluence feed preview +

Engineer only

@@ -106,6 +110,10 @@ function Admin() { path="/admin/course/:courseId" render={({ match }) => } /> + } + /> );