diff --git a/app/controllers/moderations_controller.rb b/app/controllers/moderations_controller.rb index 9d534163d..0f68e4e6a 100644 --- a/app/controllers/moderations_controller.rb +++ b/app/controllers/moderations_controller.rb @@ -4,7 +4,7 @@ class ModerationsController < ApplicationController JSON_OPTIONS = { only: %i[id title published_at cached_tag_list path], include: { - user: { only: %i[username name path articles_count] } + user: { only: %i[username name path articles_count id] } } }.freeze diff --git a/app/javascript/modCenter/__tests__/moderationArticles.test.jsx b/app/javascript/modCenter/__tests__/moderationArticles.test.jsx new file mode 100644 index 000000000..bc59cd6ac --- /dev/null +++ b/app/javascript/modCenter/__tests__/moderationArticles.test.jsx @@ -0,0 +1,112 @@ +import { h } from 'preact'; +import { render, fireEvent } from '@testing-library/preact'; +import { ModerationArticles } from '../moderationArticles'; + +const getTestArticles = () => { + const articles = [ + { + id: 1, + title: 'An article title', + path: 'an-article-title-di3', + published_at: '2019-06-22T16:11:10.590Z', + cached_tag_list: 'discuss, javascript, beginners', + user: { + articles_count: 1, + name: 'hello', + id: 1, + }, + }, + { + id: 2, + title: + 'An article title that is quite very actually rather extremely long with all things considered', + path: + 'an-article-title-that-is-quite-very-actually-rather-extremely-long-with-all-things-considered-fi8', + published_at: '2019-06-24T09:32:10.590Z', + cached_tag_list: '', + user: { + articles_count: 3, + name: 'howdy', + id: 2, + }, + }, + ]; + return JSON.stringify(articles); +}; + +describe('', () => { + beforeEach(() => { + render( +
+ , + ); + }); + + it('renders a list of 2 articles', () => { + render(); + + const listOfArticles = document.querySelectorAll( + '[data-testid^="mod-article-"]', + ); + expect(listOfArticles.length).toEqual(2); + }); + + it('renders the iframes on click', () => { + const { getByTestId } = render(); + const singleArticle = getByTestId('mod-article-1'); + singleArticle.click(); + const iframes = singleArticle.querySelectorAll('iframe'); + expect(iframes.length).toEqual(2); + }); + + it('toggles the "opened" class when opening or closing an article', () => { + const { getByTestId } = render(); + const singleArticle = getByTestId('mod-article-2'); + + fireEvent.click(singleArticle); + expect( + singleArticle.querySelector('.article-iframes-container').classList, + ).toContain('opened'); + + fireEvent.click(singleArticle); + expect( + singleArticle.querySelector('.article-iframes-container').classList, + ).not.toContain('opened'); + }); + + it('adds the FlagUser Modal HTML associated with author when article opened', async () => { + const { getByTestId, findByTestId } = render(); + const expectedArticleId = 2; + + expect( + document.querySelector('[data-testid="flag-user-modal"]'), + ).toBeNull(); + + const singleArticle = getByTestId(`mod-article-${expectedArticleId}`); + + singleArticle.click(); + + // We need the iframe to load first before checking for the modal having been loaded. + await findByTestId(`mod-iframe-${expectedArticleId}`); + + const flagUserModal = document.querySelector( + '[data-testid="flag-user-modal"]', + ); + + expect(flagUserModal).not.toBeNull(); + + const actualArticleId = Number( + flagUserModal.querySelector('input').dataset.reactableId, + ); + + expect(actualArticleId).toEqual(expectedArticleId); + }); +}); diff --git a/app/javascript/modCenter/moderationArticles.jsx b/app/javascript/modCenter/moderationArticles.jsx index 455b804b3..03192e20d 100644 --- a/app/javascript/modCenter/moderationArticles.jsx +++ b/app/javascript/modCenter/moderationArticles.jsx @@ -6,10 +6,36 @@ export class ModerationArticles extends Component { articles: JSON.parse( document.getElementById('mod-index-list').dataset.articles, ), + prevSelectedArticleId: undefined, + selectedArticleId: undefined, + }; + + toggleArticle = (id, path) => { + const { prevSelectedArticleId } = this.state; + const selectedArticle = document.getElementById(`article-iframe-${id}`); + + if (prevSelectedArticleId > 0) { + document.getElementById( + `article-iframe-${prevSelectedArticleId}`, + ).innerHTML = ''; + } + + this.setState({ selectedArticleId: id, prevSelectedArticleId: id }); + + if ( + id === prevSelectedArticleId && + document.querySelectorAll('.opened').length > 0 + ) { + selectedArticle.classList.remove('opened'); + return; + } + + selectedArticle.classList.add('opened'); + selectedArticle.innerHTML = ``; }; render() { - const { articles } = this.state; + const { articles, selectedArticleId } = this.state; return (
@@ -31,6 +57,8 @@ export class ModerationArticles extends Component { key={id} publishedAt={publishedAt} user={user} + articleOpened={id === selectedArticleId} + toggleArticle={this.toggleArticle} /> ); })} diff --git a/app/javascript/modCenter/singleArticle/__tests__/singleArticle.test.jsx b/app/javascript/modCenter/singleArticle/__tests__/singleArticle.test.jsx index 91236336c..2f4fc6fc1 100644 --- a/app/javascript/modCenter/singleArticle/__tests__/singleArticle.test.jsx +++ b/app/javascript/modCenter/singleArticle/__tests__/singleArticle.test.jsx @@ -1,11 +1,10 @@ /* eslint-disable jest/expect-expect */ import { h } from 'preact'; import { axe } from 'jest-axe'; -import { render, getNodeText, fireEvent } from '@testing-library/preact'; - +import { render, getNodeText } from '@testing-library/preact'; import SingleArticle from '../index'; -const testArticle1 = { +const getTestArticle = () => ({ id: 1, title: 'An article title', path: 'an-article-title-di3', @@ -15,49 +14,48 @@ const testArticle1 = { articles_count: 1, name: 'hello', }, -}; - -const testArticle2 = { - id: 2, - title: - 'An article title that is quite very actually rather extremely long with all things considered', - path: - 'an-article-title-that-is-quite-very-actually-rather-extremely-long-with-all-things-considered-fi8', - publishedAt: '2019-06-24T09:32:10.590Z', - cachedTagList: '', - user: { - articles_count: 1, - name: 'howdy', - }, -}; +}); describe('', () => { - const renderSingleArticle = (article = testArticle1) => - render( - , - ); - it('should have no a11y violations', async () => { - const { container } = renderSingleArticle(); + const { container } = render( + <> + + {/* Div below needed for this test to pass while preserve FlagUserModal functionality */} +