mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Add story/spec for ReportsTable component/refactor
- use data-test to target elements in tests
This commit is contained in:
parent
46b6483c90
commit
e1c56346cc
@ -1,36 +1,216 @@
|
||||
import { config, mount } from '@vue/test-utils'
|
||||
import { config, mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import Vuex from 'vuex'
|
||||
import ReportsTable from './ReportsTable.vue'
|
||||
import Styleguide from '@human-connection/styleguide'
|
||||
import { reports } from './ReportsTable.story.js'
|
||||
import BaseIcon from '~/components/_new/generic/BaseIcon/BaseIcon'
|
||||
|
||||
const localVue = global.localVue
|
||||
localVue.use(Styleguide)
|
||||
|
||||
config.stubs['client-only'] = '<span><slot /></span>'
|
||||
|
||||
describe('ReportsTable', () => {
|
||||
let propsData
|
||||
let mocks
|
||||
let propsData, mocks, stubs, getters, wrapper, reportsTable
|
||||
|
||||
beforeEach(() => {
|
||||
propsData = {}
|
||||
mocks = {
|
||||
$t: jest.fn(t => t),
|
||||
$t: jest.fn(string => string),
|
||||
}
|
||||
stubs = {
|
||||
NuxtLink: RouterLinkStub,
|
||||
}
|
||||
getters = {
|
||||
'auth/user': () => {
|
||||
return { slug: 'awesome-user' }
|
||||
},
|
||||
'auth/isModerator': () => true,
|
||||
}
|
||||
})
|
||||
|
||||
describe('mount', () => {
|
||||
const Wrapper = () => {
|
||||
return mount(ReportsTable, { propsData, mocks, localVue })
|
||||
const store = new Vuex.Store({
|
||||
getters,
|
||||
})
|
||||
return mount(ReportsTable, { propsData, mocks, stubs, localVue, store })
|
||||
}
|
||||
|
||||
describe('no reports', () => {
|
||||
describe('given no reports', () => {
|
||||
beforeEach(() => {
|
||||
propsData = { ...propsData, reports: [] }
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('shows a placeholder', () => {
|
||||
const wrapper = Wrapper()
|
||||
expect(wrapper.text()).toContain('moderation.reports.empty')
|
||||
})
|
||||
})
|
||||
|
||||
describe('given reports', () => {
|
||||
beforeEach(() => {
|
||||
propsData = { ...propsData, reports }
|
||||
wrapper = Wrapper()
|
||||
reportsTable = wrapper.find('.ds-table')
|
||||
})
|
||||
|
||||
it('renders a table', () => {
|
||||
expect(reportsTable.exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('Comment', () => {
|
||||
let commentRow
|
||||
beforeEach(() => {
|
||||
commentRow = wrapper.find('[data-test="Comment"]')
|
||||
})
|
||||
|
||||
it('renders a comments icon', () => {
|
||||
const commentsIcon = commentRow.find(BaseIcon).props().name
|
||||
expect(commentsIcon).toEqual('comments')
|
||||
})
|
||||
|
||||
it('renders a link to the post, with the comment contentExcerpt', () => {
|
||||
const postLink = commentRow.find('[data-test="post-link"]')
|
||||
expect(postLink.text()).toEqual('@peter-lustig Lorem ipsum dolor sit amet, …')
|
||||
})
|
||||
|
||||
it('renders the author', () => {
|
||||
const username = commentRow.find('[data-test="louie"] b')
|
||||
expect(username.text()).toEqual('Louie')
|
||||
})
|
||||
|
||||
describe('given it has been reviewed', () => {
|
||||
it('renders the enabled icon', () => {
|
||||
const enabledIcon = commentRow
|
||||
.findAll(BaseIcon)
|
||||
.filter(icon => icon.props().name === 'eye')
|
||||
expect(enabledIcon.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('renders its current status', () => {
|
||||
expect(commentRow.find('[data-test="enabled"]').text()).toEqual(
|
||||
'moderation.reports.enabledBy',
|
||||
)
|
||||
})
|
||||
|
||||
it('renders the moderator who reviewed the resource', () => {
|
||||
const username = commentRow.find('[data-test="moderator"] b')
|
||||
expect(username.text()).toEqual('Moderator')
|
||||
})
|
||||
})
|
||||
|
||||
describe('give report has not been closed', () => {
|
||||
let confirmButton
|
||||
beforeEach(() => {
|
||||
confirmButton = commentRow.find('button.confirm')
|
||||
})
|
||||
it('renders a confirm button', () => {
|
||||
expect(confirmButton.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('emits confirm event', () => {
|
||||
confirmButton.trigger('click')
|
||||
expect(wrapper.emitted().confirm[0][0]).toEqual(reports[0])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Post', () => {
|
||||
let postRow
|
||||
beforeEach(() => {
|
||||
postRow = wrapper.find('[data-test="Post"]')
|
||||
})
|
||||
|
||||
it('renders a bookmark icon', () => {
|
||||
const postIcon = postRow.find(BaseIcon).props().name
|
||||
expect(postIcon).toEqual('bookmark')
|
||||
})
|
||||
|
||||
it('renders a link to the post', () => {
|
||||
const postLink = postRow.find('[data-test="post-link"]')
|
||||
expect(postLink.text()).toEqual("I'm a bigoted post!")
|
||||
})
|
||||
|
||||
it('renders the author', () => {
|
||||
const username = postRow.find('[data-test="dagobert"] b')
|
||||
expect(username.text()).toEqual('Dagobert')
|
||||
})
|
||||
|
||||
describe('given it has not been reviewed', () => {
|
||||
it('renders the enabled icon', () => {
|
||||
const enabledIcon = postRow
|
||||
.findAll(BaseIcon)
|
||||
.filter(icon => icon.props().name === 'eye')
|
||||
expect(enabledIcon.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('renders its current status', () => {
|
||||
expect(postRow.find('[data-test="unreviewed"]').text()).toEqual(
|
||||
'moderation.reports.enabled',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('give report has not been closed', () => {
|
||||
let confirmButton
|
||||
beforeEach(() => {
|
||||
confirmButton = postRow.find('button.confirm')
|
||||
})
|
||||
|
||||
it('renders a confirm button', () => {
|
||||
expect(confirmButton.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('emits confirm event', () => {
|
||||
confirmButton.trigger('click')
|
||||
expect(wrapper.emitted().confirm[0][0]).toEqual(reports[1])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('User', () => {
|
||||
let userRow
|
||||
beforeEach(() => {
|
||||
userRow = wrapper.find('[data-test="User"]')
|
||||
})
|
||||
|
||||
it('renders a bookmark icon', () => {
|
||||
const userIcon = userRow.find(BaseIcon).props().name
|
||||
expect(userIcon).toEqual('user')
|
||||
})
|
||||
|
||||
it('renders a link to the user profile', () => {
|
||||
const userLink = userRow.find('[data-test="abusive-user"] b')
|
||||
expect(userLink.text()).toEqual('Abusive user')
|
||||
})
|
||||
|
||||
describe('given it has been reviewed', () => {
|
||||
it('renders the disabled icon', () => {
|
||||
const disabledIcon = userRow
|
||||
.findAll(BaseIcon)
|
||||
.filter(icon => icon.props().name === 'eye-slash')
|
||||
expect(disabledIcon.exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('renders its current status', () => {
|
||||
expect(userRow.find('[data-test="disabled"]').text()).toEqual(
|
||||
'moderation.reports.disabledBy',
|
||||
)
|
||||
})
|
||||
|
||||
it('renders the moderator who reviewed the resource', () => {
|
||||
const username = userRow.find('[data-test="peter-lustig"] b')
|
||||
expect(username.text()).toEqual('Peter Lustig')
|
||||
})
|
||||
})
|
||||
|
||||
describe('give report has been closed', () => {
|
||||
it('renders Decided text', () => {
|
||||
expect(userRow.find('[data-test="closed"]').text()).toEqual(
|
||||
'moderation.reports.decided',
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -0,0 +1,169 @@
|
||||
import { storiesOf } from '@storybook/vue'
|
||||
import { withA11y } from '@storybook/addon-a11y'
|
||||
import { action } from '@storybook/addon-actions'
|
||||
import ReportsTable from '~/components/_new/features/ReportsTable/ReportsTable'
|
||||
import helpers from '~/storybook/helpers'
|
||||
import { post } from '~/components/PostCard/PostCard.story.js'
|
||||
import { user } from '~/components/User/User.story.js'
|
||||
|
||||
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-12-02T15:56:35.676Z',
|
||||
reasonCategory: 'pornographic_content_links',
|
||||
reasonDescription: 'This comment is porno!!!',
|
||||
submitter: {
|
||||
...user,
|
||||
},
|
||||
},
|
||||
],
|
||||
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:
|
||||
'<p><a class="mention" href="/profile/u1" data-mention-id="u1" target="_blank">@peter-lustig</a> </p><p>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.</p>',
|
||||
contentExcerpt:
|
||||
'<p><a href="/profile/u1" target="_blank">@peter-lustig</a> </p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra …</p>',
|
||||
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,
|
||||
},
|
||||
},
|
||||
],
|
||||
resource: {
|
||||
__typename: 'Post',
|
||||
author: {
|
||||
...user,
|
||||
id: 'u7',
|
||||
name: 'Dagobert',
|
||||
slug: 'dagobert',
|
||||
},
|
||||
deleted: false,
|
||||
disabled: true,
|
||||
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,
|
||||
},
|
||||
},
|
||||
],
|
||||
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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
storiesOf('ReportsTable', module)
|
||||
.addDecorator(withA11y)
|
||||
.addDecorator(helpers.layout)
|
||||
.add('with reports', () => ({
|
||||
components: { ReportsTable },
|
||||
store: helpers.store,
|
||||
data: () => ({
|
||||
reports,
|
||||
}),
|
||||
methods: {
|
||||
confirm: action('confirm'),
|
||||
},
|
||||
template: `<reports-table :reports="reports" @confirm="confirm" />`,
|
||||
}))
|
||||
.add('without reports', () => ({
|
||||
components: { ReportsTable },
|
||||
store: helpers.store,
|
||||
template: `<reports-table />`,
|
||||
}))
|
||||
@ -34,7 +34,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody :key="'tbody-' + report.resource.id">
|
||||
<tr valign="top">
|
||||
<tr valign="top" :data-test="report.resource.__typename">
|
||||
<td class="ds-table-col">
|
||||
<ds-text color="soft">
|
||||
<base-icon
|
||||
@ -57,18 +57,29 @@
|
||||
<td class="ds-table-col ">
|
||||
<div v-if="isPost(report.resource) || isComment(report.resource)">
|
||||
<nuxt-link
|
||||
data-test="post-link"
|
||||
:to="{
|
||||
name: 'post-id-slug',
|
||||
params: params(report.resource),
|
||||
hash: hashParam(report.resource),
|
||||
}"
|
||||
>
|
||||
<b>{{ report.resource.title || report.resource.contentExcerpt | truncate(50) }}</b>
|
||||
<b>
|
||||
{{
|
||||
report.resource.title ||
|
||||
$filters.removeHtml(report.resource.contentExcerpt) | truncate(50)
|
||||
}}
|
||||
</b>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div v-else>
|
||||
<client-only>
|
||||
<hc-user :user="report.resource" :showAvatar="false" :trunc="30" />
|
||||
<hc-user
|
||||
:user="report.resource"
|
||||
:showAvatar="false"
|
||||
:trunc="30"
|
||||
:data-test="report.resource.slug"
|
||||
/>
|
||||
</client-only>
|
||||
</div>
|
||||
</td>
|
||||
@ -79,6 +90,7 @@
|
||||
:user="report.resource.author"
|
||||
:showAvatar="false"
|
||||
:trunc="30"
|
||||
:data-test="report.resource.author.slug"
|
||||
/>
|
||||
<span v-else>—</span>
|
||||
</client-only>
|
||||
@ -86,38 +98,35 @@
|
||||
<td>
|
||||
<div v-if="report.reviewed">
|
||||
<br />
|
||||
<div v-if="report.resource.disabled">
|
||||
<div v-if="report.resource.disabled" data-test="disabled">
|
||||
<base-icon name="eye-slash" class="ban" />
|
||||
{{ $t('moderation.reports.disabledBy') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-else data-test="enabled">
|
||||
<base-icon name="eye" class="no-ban" />
|
||||
{{ $t('moderation.reports.enabledBy') }}
|
||||
</div>
|
||||
<client-only>
|
||||
<hc-user
|
||||
:user="report.reviewed[0].moderator"
|
||||
:user="moderatorOfLatestReview(report)"
|
||||
:showAvatar="false"
|
||||
:trunc="30"
|
||||
:date-time="report.updatedAt"
|
||||
positionDatetime="below"
|
||||
:data-test="moderatorOfLatestReview(report).slug"
|
||||
/>
|
||||
</client-only>
|
||||
</div>
|
||||
<div v-else>
|
||||
<br />
|
||||
<div v-if="report.resource.disabled">
|
||||
<base-icon name="eye-slash" class="ban" />
|
||||
{{ $t('moderation.reports.disabled') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div data-test="unreviewed">
|
||||
<base-icon name="eye" class="no-ban" />
|
||||
{{ $t('moderation.reports.enabled') }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="ds-table-col">
|
||||
<b v-if="report.closed">
|
||||
<b v-if="report.closed" data-test="closed">
|
||||
{{ $t('moderation.reports.decided') }}
|
||||
</b>
|
||||
<ds-button
|
||||
@ -187,6 +196,9 @@ export default {
|
||||
isUser(resource) {
|
||||
return resource.__typename === 'User'
|
||||
},
|
||||
moderatorOfLatestReview(report) {
|
||||
return report.reviewed[0].moderator
|
||||
},
|
||||
params(resource) {
|
||||
const post = this.isComment(resource) ? resource.post : resource
|
||||
return {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user