diff --git a/webapp/components/features/ReportList/ReportList.spec.js b/webapp/components/features/ReportList/ReportList.spec.js new file mode 100644 index 000000000..cfd83b4a6 --- /dev/null +++ b/webapp/components/features/ReportList/ReportList.spec.js @@ -0,0 +1,77 @@ +import { config, mount } from '@vue/test-utils' +import Vuex from 'vuex' +import ReportList from './ReportList' +import { reports } from './ReportList.story' +import ReportsTable from '~/components/features/ReportsTable/ReportsTable' +import DropdownFilter from '~/components/DropdownFilter/DropdownFilter' + +const localVue = global.localVue + +config.stubs['client-only'] = '' +config.stubs['nuxt-link'] = '' + +describe('ReportList', () => { + let mocks, mutations, getters, wrapper + + beforeEach(() => { + mocks = { + $apollo: { + mutate: jest + .fn() + .mockResolvedValueOnce({ + data: { review: { disable: true, resourceId: 'some-resource', closed: true } }, + }) + .mockRejectedValue({ message: 'Unable to review' }), + }, + $t: jest.fn(), + $toast: { + error: jest.fn(message => message), + }, + } + mutations = { + 'modal/SET_OPEN': jest.fn().mockResolvedValueOnce(), + } + getters = { + 'auth/user': () => { + return { slug: 'awesome-user' } + }, + 'auth/isModerator': () => true, + } + }) + + describe('mount', () => { + const Wrapper = () => { + const store = new Vuex.Store({ + mutations, + getters, + }) + return mount(ReportList, { mocks, localVue, store }) + } + + describe('renders children components', () => { + beforeEach(async () => { + wrapper = Wrapper() + }) + + it('renders DropdownFilter', () => { + expect(wrapper.find(DropdownFilter).exists()).toBe(true) + }) + + it('renders ReportsTable', () => { + expect(wrapper.find(ReportsTable).exists()).toBe(true) + }) + }) + + describe('confirm is emitted by reports table', () => { + beforeEach(async () => { + wrapper = Wrapper() + wrapper.setData({ reports }) + wrapper.find(ReportsTable).vm.$emit('confirm', reports[0]) + }) + + it('calls modal/SET_OPEN', () => { + expect(mutations['modal/SET_OPEN']).toHaveBeenCalledTimes(1) + }) + }) + }) +}) diff --git a/webapp/components/features/ReportList/ReportList.story.js b/webapp/components/features/ReportList/ReportList.story.js new file mode 100644 index 000000000..e126f1e64 --- /dev/null +++ b/webapp/components/features/ReportList/ReportList.story.js @@ -0,0 +1,193 @@ +import { storiesOf } from '@storybook/vue' +import { withA11y } from '@storybook/addon-a11y' +import { action } from '@storybook/addon-actions' +import { post } from '~/components/PostCard/PostCard.story.js' +import { user } from '~/components/User/User.story.js' +import helpers from '~/storybook/helpers' +import ReportList from './ReportList' +import DropdownFilter from '~/components/DropdownFilter/DropdownFilter' +import ReportsTable from '~/components/features/ReportsTable/ReportsTable' +helpers.init() + +export const reports = [ + { + __typename: 'Report', + closed: false, + createdAt: '2019-10-29T15:36:02.106Z', + updatedAt: '2019-12-02T15:56:35.651Z', + disable: false, + filed: [ + { + __typename: 'FILED', + createdAt: '2019-10-02T15:56:35.676Z', + reasonCategory: 'pornographic_content_links', + reasonDescription: 'This comment is porno!!!', + submitter: { + ...user, + name: 'Community moderator', + id: 'community-moderator', + slug: 'community-moderator', + }, + }, + ], + resource: { + __typename: 'Comment', + id: 'b6b38937-3efc-4d5e-b12c-549e4d6551a5', + createdAt: '2019-10-29T15:38:25.184Z', + updatedAt: '2019-10-30T15:38:25.184Z', + disabled: false, + deleted: false, + content: + '

@peter-lustig

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra magna ac placerat. Tempor id eu nisl nunc mi ipsum faucibus vitae. Nibh praesent tristique magna sit amet purus gravida quis blandit. Magna eget est lorem ipsum dolor. In fermentum posuere urna nec. Eleifend donec pretium vulputate sapien nec sagittis aliquam. Augue interdum velit euismod in pellentesque. Id diam maecenas ultricies mi eget mauris pharetra. Donec pretium vulputate sapien nec. Dolor morbi non arcu risus quis varius quam quisque. Blandit turpis cursus in hac habitasse. Est ultricies integer quis auctor elit sed vulputate mi sit. Nunc consequat interdum varius sit amet mattis vulputate enim. Semper feugiat nibh sed pulvinar. Eget felis eget nunc lobortis mattis aliquam. Ultrices vitae auctor eu augue. Tellus molestie nunc non blandit massa enim nec dui. Pharetra massa massa ultricies mi quis hendrerit dolor. Nisl suscipit adipiscing bibendum est ultricies integer.

', + contentExcerpt: + '

@peter-lustig

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra …

', + post, + author: user, + }, + reviewed: [ + { + updatedAt: '2019-10-30T15:38:25.184Z', + moderator: { + __typename: 'User', + ...user, + name: 'Moderator', + id: 'moderator', + slug: 'moderator', + }, + }, + { + updatedAt: '2019-10-29T15:38:25.184Z', + moderator: { + __typename: 'User', + ...user, + name: 'Peter Lustig', + id: 'u3', + slug: 'peter-lustig', + }, + }, + ], + }, + { + __typename: 'Report', + closed: false, + createdAt: '2019-10-31T15:36:02.106Z', + updatedAt: '2019-12-03T15:56:35.651Z', + disable: true, + filed: [ + { + __typename: 'FILED', + createdAt: '2019-10-31T15:36:02.106Z', + reasonCategory: 'discrimination_etc', + reasonDescription: 'This post is bigoted', + submitter: { + ...user, + name: 'Modertation team', + id: 'moderation-team', + slug: 'moderation-team', + }, + }, + ], + resource: { + __typename: 'Post', + author: { + ...user, + id: 'u7', + name: 'Dagobert', + slug: 'dagobert', + }, + deleted: false, + disabled: false, + id: 'p2', + slug: 'bigoted-post', + title: "I'm a bigoted post!", + }, + reviewed: null, + }, + { + __typename: 'Report', + closed: true, + createdAt: '2019-10-30T15:36:02.106Z', + updatedAt: '2019-12-01T15:56:35.651Z', + disable: true, + filed: [ + { + __typename: 'FILED', + createdAt: '2019-10-30T15:36:02.106Z', + reasonCategory: 'discrimination_etc', + reasonDescription: 'this user is attacking me for who I am!', + submitter: { + ...user, + name: 'Helpful user', + id: 'helpful-user', + slug: 'helpful-user', + }, + }, + ], + resource: { + __typename: 'User', + commentedCount: 0, + contributionsCount: 0, + deleted: false, + disabled: true, + followedByCount: 0, + id: 'u5', + name: 'Abusive user', + slug: 'abusive-user', + }, + reviewed: [ + { + updatedAt: '2019-12-01T15:56:35.651Z', + moderator: { + __typename: 'User', + ...user, + name: 'Peter Lustig', + id: 'u3', + slug: 'peter-lustig', + }, + }, + { + updatedAt: '2019-11-30T15:56:35.651Z', + moderator: { + __typename: 'User', + ...user, + name: 'Moderator', + id: 'moderator', + slug: 'moderator', + }, + }, + ], + }, +] +const unreviewedReports = reports.filter(report => !report.reviewed) +const reviewedReports = reports.filter(report => report.reviewed) +const closedReports = reports.filter(report => report.closed) +const filterOptions = [ + { label: 'All', value: reports }, + { label: 'Unreviewed', value: unreviewedReports }, + { label: 'Reviewed', value: reviewedReports }, + { label: 'Closed', value: closedReports }, +] + +storiesOf('ReportList', module) + .addDecorator(withA11y) + .addDecorator(helpers.layout) + .add('with reports', () => ({ + components: { ReportList, DropdownFilter, ReportsTable }, + store: helpers.store, + data: () => ({ + filterOptions, + selected: filterOptions[0].label, + reports, + }), + methods: { + openModal: action('openModal'), + filter: action('filter'), + }, + template: ` +
+

Reports

+ +
+ +
`, + })) diff --git a/webapp/components/features/ReportList/ReportList.vue b/webapp/components/features/ReportList/ReportList.vue new file mode 100644 index 000000000..85b74d7cc --- /dev/null +++ b/webapp/components/features/ReportList/ReportList.vue @@ -0,0 +1,142 @@ + + + +