feat(webapp): dynamic static pages (#8920)

Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>
This commit is contained in:
Moriz Wahl 2025-09-25 11:16:07 +02:00 committed by GitHub
parent 9a4f7326c1
commit a15351aa42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 104 additions and 463 deletions

View File

@ -25,11 +25,21 @@
</template>
<script>
import { PageParams } from '~/components/utils/PageParams.js'
export default {
name: 'InternalPage',
props: {
pageParams: { type: Object, required: true },
},
created() {
const pageParamsObj = new PageParams({
...this.pageParams,
})
if (!pageParamsObj.isInternalPage) {
pageParamsObj.redirectToPage(this)
}
},
}
</script>

View File

@ -1,22 +1,26 @@
import InternalPage from '~/components/_new/features/InternalPage/InternalPage.vue'
import links from '~/constants/links.js'
export function internalPageMixins(pageParams) {
export function internalPageMixins() {
return {
layout: 'basic',
components: {
InternalPage,
},
data() {
return { pageParams }
},
head() {
return {
title: this.$t(this.pageParams.internalPage.headTitleIdent),
}
},
created() {
if (!this.pageParams.isInternalPage) {
this.pageParams.redirectToPage(this)
async asyncData({ params, error }) {
const [link] = Object.keys(links).filter((key) => links[key].name === params.static)
if (!link)
return error({
statusCode: 404,
key: 'error-pages.404-default',
})
return {
pageParams: links[link],
}
},
}

View File

@ -0,0 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`_static mount renders 1`] = `
<div>
<div>
<div
class="ds-space"
style="margin-top: 16px; margin-bottom: 16px;"
>
<h2
class="ds-heading ds-heading-h2"
>
</h2>
</div>
<div
class="ds-container ds-container-x-large"
>
<article
class="base-card"
>
<div />
<!---->
</article>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,38 @@
import { mount } from '@vue/test-utils'
import Static from './_static.vue'
const localVue = global.localVue
describe('_static', () => {
let wrapper
describe('mount', () => {
const Wrapper = (page) => {
return mount(Static, {
mocks: {
$t: jest.fn(),
},
data() {
return {
pageParams: {
internalPage: {
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
},
},
}
},
localVue,
})
}
beforeEach(async () => {
wrapper = await Wrapper('faq')
})
it('renders', () => {
expect(wrapper.element).toMatchSnapshot()
})
})
})

13
webapp/pages/_static.vue Normal file
View File

@ -0,0 +1,13 @@
<template>
<div>
<internal-page :pageParams="pageParams" />
</div>
</template>
<script>
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins()],
}
</script>

View File

@ -1,43 +0,0 @@
import { mount } from '@vue/test-utils'
import CodeOfConduct from './code-of-conduct.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('code-of-conduct.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(CodeOfConduct, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.code-of-conduct')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.CODE_OF_CONDUCT)],
}
</script>

View File

@ -1,43 +0,0 @@
import { mount } from '@vue/test-utils'
import DataPrivacy from './data-privacy.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('data-privacy.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(DataPrivacy, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.data-privacy')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.DATA_PRIVACY)],
}
</script>

View File

@ -1,47 +0,0 @@
import { mount } from '@vue/test-utils'
import Donate from './donate.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
const openMock = jest.fn()
delete window.open
window.open = openMock
describe('donate.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Donate, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.donate')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.DONATE)],
}
</script>

View File

@ -1,43 +0,0 @@
import { mount } from '@vue/test-utils'
import Faq from './faq.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('faq.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Faq, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.faq')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.FAQ)],
}
</script>

View File

@ -1,47 +0,0 @@
import { mount } from '@vue/test-utils'
import Imprint from './imprint.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
const openMock = jest.fn()
delete window.open
window.open = openMock
describe('imprint.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Imprint, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.imprint')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.IMPRINT)],
}
</script>

View File

@ -1,47 +0,0 @@
import { mount } from '@vue/test-utils'
import Organization from './organization.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
const openMock = jest.fn()
delete window.open
window.open = openMock
describe('organization.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Organization, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.made')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.ORGANIZATION)],
}
</script>

View File

@ -1,47 +0,0 @@
import { mount } from '@vue/test-utils'
import Support from './support.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
const openMock = jest.fn()
delete window.open
window.open = openMock
describe('support.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Support, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.support')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.SUPPORT)],
}
</script>

View File

@ -1,43 +0,0 @@
import { mount } from '@vue/test-utils'
import TermsAndConditions from './terms-and-conditions.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('terms-and-conditions.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(TermsAndConditions, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.element.tagName).toBe('DIV')
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.termsAndConditions')
})
})
})

View File

@ -1,12 +0,0 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.TERMS_AND_CONDITIONS)],
}
</script>