Files
BeamMP-Website/tests/footer.test.js
T

87 lines
3.3 KiB
JavaScript

/**
* The footer is on every page: the social links, the Patreon link, and the
* legal links. A wrong address or a missing "opens in a new tab" safety
* attribute here is shipped to every visitor.
*/
import { mount, flushPromises } from '@vue/test-utils'
import { installI18n } from './helpers'
import router from '@/routes'
import AppFooter from '@/components/AppFooter.vue'
async function mountFooter() {
const i18n = installI18n('en')
await router.push('/en')
await router.isReady()
const wrapper = mount(AppFooter, { global: { plugins: [i18n, router] } })
await flushPromises()
return wrapper
}
const SOCIAL = {
GitHub: 'https://github.com/BeamMP',
Discord: 'https://discord.gg/beammp',
YouTube: 'https://www.youtube.com/@beammpofficial',
X: 'https://x.com/beammpofficial',
Reddit: 'https://www.reddit.com/r/BeamMP',
Bluesky: 'https://bsky.app/profile/beammp.com',
Twitch: 'https://www.twitch.tv/beammpofficial',
Instagram: 'https://www.instagram.com/beammpofficial',
TikTok: 'https://www.tiktok.com/@beammpofficial',
Facebook: 'https://www.facebook.com/BeamMPTeam',
}
test('shows each social link, in order, with the right address', async () => {
const wrapper = await mountFooter()
const links = wrapper.findAll('a[aria-label]')
expect(links.map((a) => a.attributes('aria-label'))).toEqual(Object.keys(SOCIAL))
for (const a of links) {
expect(a.attributes('href'), a.attributes('aria-label')).toBe(
SOCIAL[a.attributes('aria-label')]
)
}
})
test('Twitch and Bluesky are both there, side by side', async () => {
const wrapper = await mountFooter()
const labels = wrapper.findAll('a[aria-label]').map((a) => a.attributes('aria-label'))
expect(labels.indexOf('Twitch')).toBe(labels.indexOf('Bluesky') + 1)
})
test('every link that leaves the site opens in a new tab without handing over the opener', async () => {
const wrapper = await mountFooter()
const external = wrapper
.findAll('a')
.filter((a) => /^https?:\/\//.test(a.attributes('href') || ''))
expect(external.length).toBeGreaterThanOrEqual(Object.keys(SOCIAL).length + 3)
for (const a of external) {
expect(a.attributes('target'), a.attributes('href')).toBe('_blank')
expect(a.attributes('rel'), a.attributes('href')).toContain('noopener')
}
})
test('every social icon is a labelled link with a drawn icon', async () => {
const wrapper = await mountFooter()
for (const a of wrapper.findAll('a[aria-label]')) {
expect(a.find('svg').exists(), a.attributes('aria-label')).toBe(true)
}
})
test('has the Patreon link and the legal links, and this year in the copyright', async () => {
const wrapper = await mountFooter()
const hrefs = wrapper.findAll('a').map((a) => a.attributes('href'))
expect(hrefs).toContain('https://www.patreon.com/BeamMP')
expect(hrefs).toContain('https://beammp.com/privacy')
expect(hrefs).toContain('https://beammp.com/terms')
expect(hrefs).toContain('/en/about')
expect(wrapper.text()).toContain(`2019 - ${new Date().getFullYear()}`)
})
test('the About link follows the language', async () => {
const i18n = installI18n('en')
await router.push('/de')
const wrapper = mount(AppFooter, { global: { plugins: [i18n, router] } })
await flushPromises()
expect(wrapper.findAll('a').map((a) => a.attributes('href'))).toContain('/de/about')
})