Ocelot-Social/webapp/components/NotificationsTable/NotificationsTable.spec.js
Max 33274e5b9a
feat(webapp): user teaser popover (#8450)
* calculate distance between current user and queried user

* fix query for unset location

* use database to calculate distance

* rename distance to distance to me, 100% calculation done in DB

* distanceToMe tests

* lint fixes

* remove comments

* Show user teaser popover with badges, Desktop

* Refactor UserTeaser and add mobile popover support

* Avoid click propagation (WIP)

* Prevent event propagation

* Adjust alignment and font sizes

* More spacing for statistics

* Add distance, simplify user link

* Refactor location info into own component

* Add tests for UserTeaserPopup

* Refactor and test LocationInfo

* Query distanceToMe, rename distance to distanceToMe

* Update test

* Improve tests for UserTeaser, WIP

* Fix tests

* DistanceToMe on User instead of Location

* Revert "DistanceToMe on User instead of Location"

This reverts commit 96c9db00a44cd120e47bfe9534d3e066a194744c.

* Fix notifications

* Refactor UserTeaser and fix location info

* Fix group member crash

* Show 0 distance

* Fit in popover on small screens

* Allow access to profile on desktop

* Revert backend changes

* Load user teaser popover data only when needed

* Fix type mismatch

* Refactor for clarity and accessibility

* Litte refactorings and improvements

* Fix popover test

* Adapt and fix tests

* Fix tests and bugs

* Add placeholder

* cypress: adapt user teaser locator to changes

* Remove delays and scrolling

* Disable popovers in notification list and fix layout

* Remove flickering

* Make overlay catch all pointer events on touch devices

* Re-add attribute for E2E test

* Fix test, return to mouseover

* fix snapshot

---------

Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>
Co-authored-by: mahula <lenzmath@posteo.de>
2025-05-05 23:54:13 +00:00

169 lines
5.1 KiB
JavaScript

import { mount, RouterLinkStub } from '@vue/test-utils'
import Vuex from 'vuex'
import NotificationsTable from './NotificationsTable'
import { notifications } from '~/components/utils/Notifications'
const localVue = global.localVue
localVue.filter('truncate', (string) => string)
describe('NotificationsTable.vue', () => {
let wrapper, mocks, propsData, stubs
const postNotification = notifications[0]
const commentNotification = notifications[1]
beforeEach(() => {
mocks = {
$t: jest.fn((string) => string),
}
stubs = {
NuxtLink: RouterLinkStub,
'client-only': true,
}
propsData = {}
})
describe('mount', () => {
const Wrapper = () => {
const store = new Vuex.Store({
getters: {
'auth/isModerator': () => false,
'auth/user': () => {
return {}
},
},
})
return mount(NotificationsTable, {
propsData,
mocks,
localVue,
store,
stubs,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
describe('no notifications', () => {
it('renders HcEmpty component', () => {
expect(wrapper.find('.hc-empty').exists()).toBe(true)
})
})
describe('given notifications', () => {
beforeEach(() => {
propsData.notifications = notifications
wrapper = Wrapper()
})
it('renders a grid table', () => {
expect(wrapper.find('.notification-grid').exists()).toBe(true)
})
describe('renders 4 columns', () => {
it('for icon', () => {
expect(wrapper.vm.fields.icon).toBeTruthy()
})
it('for user', () => {
expect(wrapper.vm.fields.user).toBeTruthy()
})
it('for post', () => {
expect(wrapper.vm.fields.post).toBeTruthy()
})
it('for content', () => {
expect(wrapper.vm.fields.content).toBeTruthy()
})
})
describe('Post', () => {
let firstRowNotification
beforeEach(() => {
firstRowNotification = wrapper.findAll('.notification-grid-row').at(0)
})
it('renders the author', () => {
const userinfo = firstRowNotification.find('.user-teaser .info')
expect(userinfo.text()).toContain(postNotification.from.author.name)
})
it('renders the reason for the notification', () => {
const dsTexts = firstRowNotification.findAll('.ds-text')
const reason = dsTexts.filter(
(element) => element.text() === 'notifications.reason.mentioned_in_post',
)
expect(reason.exists()).toBe(true)
})
it('renders a link to the Post', () => {
const postLink = firstRowNotification.find('a.notification-mention-post')
expect(postLink.text()).toEqual(postNotification.from.title)
})
it("renders the Post's content", () => {
const boldTags = firstRowNotification.findAll('b')
const content = boldTags.filter(
(element) => element.text() === postNotification.from.contentExcerpt,
)
expect(content.exists()).toBe(true)
})
})
describe('Comment', () => {
let secondRowNotification
beforeEach(() => {
secondRowNotification = wrapper.findAll('.notification-grid-row').at(1)
})
it('renders the author', () => {
const userinfo = secondRowNotification.find('.user-teaser .info')
expect(userinfo.text()).toContain(commentNotification.from.author.name)
})
it('renders the reason for the notification', () => {
const dsTexts = secondRowNotification.findAll('.ds-text')
const reason = dsTexts.filter(
(element) => element.text() === 'notifications.reason.mentioned_in_comment',
)
expect(reason.exists()).toBe(true)
})
it('renders a link to the Post', () => {
const postLink = secondRowNotification.find('a.notification-mention-post')
expect(postLink.text()).toEqual(commentNotification.from.post.title)
})
it("renders the Post's content", () => {
const boldTags = secondRowNotification.findAll('b')
const content = boldTags.filter(
(element) => element.text() === commentNotification.from.contentExcerpt,
)
expect(content.exists()).toBe(true)
})
})
describe('unread status', () => {
it('does not have class `notification-status`', () => {
expect(wrapper.find('.notification-status').exists()).toBe(false)
})
it('clicking on a Post link emits `markNotificationAsRead`', () => {
wrapper.find('a.notification-mention-post').trigger('click')
expect(wrapper.emitted().markNotificationAsRead[0][0]).toEqual(postNotification.from.id)
})
it('adds class `notification-status` when read is true', () => {
postNotification.read = true
wrapper = Wrapper()
expect(wrapper.find('.notification-status').exists()).toBe(true)
})
})
})
})
})