Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/boekhouding-frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const homeUrl = computed(() => isAuthenticated.value ? '/projecten' : '/')
<router-link to="/toegankelijkheid" class="app-footer__link">Toegankelijkheid</router-link>
<span class="app-footer__separator">|</span>
<router-link to="/over" class="app-footer__link">Over Invulhulpen</router-link>
<span class="app-footer__separator">|</span>
<router-link to="/contact" class="app-footer__link">Contact</router-link>
</nav>
</footer>
</div>
Expand Down
6 changes: 6 additions & 0 deletions apps/boekhouding-frontend/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ const routes: RouteRecordRaw[] = [
component: () => import('./views/AboutAssessments.vue'),
meta: { public: true },
},
{
path: '/contact',
name: 'contact',
component: () => import('./views/ContactPage.vue'),
meta: { public: true },
},
]

export const router = createRouter({
Expand Down
41 changes: 41 additions & 0 deletions apps/boekhouding-frontend/src/views/ContactPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script setup lang="ts">
import { computed } from 'vue'
import AppHeader from '../components/AppHeader.vue'

const hasHistory = computed(() => !!window.history.state?.back)
</script>

<template>
<div class="rvo-max-width-layout rvo-max-width-layout--md rvo-max-width-layout-inline-padding--md">
<AppHeader
:backLabel="hasHistory ? 'Terug' : 'Ga naar home'"
:backRoute="hasHistory ? undefined : '/'"
:showBack="hasHistory"
/>

<h1 class="utrecht-heading-1">Contact</h1>

<p>
Invulhulpen is een applicatie van het Ministerie van Binnenlandse Zaken en
Koninkrijksrelaties (BZK), als hulpmiddel bij het uitvoeren van een pre-scan, DPIA of IAMA.
De applicatie is in ontwikkeling; vragen en feedback zijn welkom.
</p>

<h2 class="utrecht-heading-2">Vragen over de applicatie</h2>
<p>Voor vragen, feedback of meldingen over de applicatie zelf:</p>
<ul>
<li>E-mail: <a href="mailto:RIG@rijksoverheid.nl">RIG@rijksoverheid.nl</a></li>
<li>
GitHub:
<a href="https://github.com/MinBZK/par-dpia-form/issues" target="_blank" rel="noopener noreferrer">Issues melden</a>
</li>
</ul>

<h2 class="utrecht-heading-2">Inhoudelijke vragen over pre-scan, DPIA of IAMA</h2>
<p>
Voor inhoudelijke vragen over een pre-scan, DPIA of IAMA kun je terecht bij de
privacyadviseur van je eigen organisatie. Zie ook
<a href="https://rijksportaal.overheid-i.nl/organisaties/bzk/artikelen/dg-digitalisering-en-overheidsorganisatie-dgdoo/cio-rijk/informatiebeveiliging-en-privacy/privacy-adviseurs-rijk-par.html" target="_blank" rel="noopener noreferrer">Privacy Adviseurs Rijk (PAR)</a>.
</p>
</div>
</template>
4 changes: 3 additions & 1 deletion apps/boekhouding-frontend/test/cov/App.cov.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,18 @@ describe('App.vue', () => {
expect(wrapper.find('.session-expired-stub').exists()).toBe(true)

const footerLinks = wrapper.findAll('.app-footer__link')
expect(footerLinks).toHaveLength(3)
expect(footerLinks).toHaveLength(4)
expect(footerLinks.map((l) => l.text())).toEqual([
'Privacyverklaring',
'Toegankelijkheid',
'Over Invulhulpen',
'Contact',
])
expect(footerLinks.map((l) => l.attributes('href'))).toEqual([
'/privacy',
'/toegankelijkheid',
'/over',
'/contact',
])
})

Expand Down
4 changes: 4 additions & 0 deletions apps/boekhouding-frontend/test/cov/router.cov.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ vi.mock('../../src/views/VersionHistory.vue', () => stub('VersionHistory'))
vi.mock('../../src/views/PrivacyStatement.vue', () => stub('PrivacyStatement'))
vi.mock('../../src/views/AccessibilityStatement.vue', () => stub('AccessibilityStatement'))
vi.mock('../../src/views/AboutAssessments.vue', () => stub('AboutAssessments'))
vi.mock('../../src/views/ContactPage.vue', () => stub('ContactPage'))

let router: typeof import('../../src/router').router

Expand Down Expand Up @@ -61,13 +62,15 @@ describe('router route table', () => {
expect(paths.get('privacy')).toBe('/privacy')
expect(paths.get('accessibility')).toBe('/toegankelijkheid')
expect(paths.get('about')).toBe('/over')
expect(paths.get('contact')).toBe('/contact')
})

it('marks the public routes with meta.public and leaves the rest unset', () => {
expect(byName('home').meta?.public).toBe(true)
expect(byName('privacy').meta?.public).toBe(true)
expect(byName('accessibility').meta?.public).toBe(true)
expect(byName('about').meta?.public).toBe(true)
expect(byName('contact').meta?.public).toBe(true)

expect(byName('projects').meta?.public).toBeUndefined()
expect(byName('project').meta?.public).toBeUndefined()
Expand All @@ -85,6 +88,7 @@ describe('router route table', () => {
privacy: 'PrivacyStatement',
accessibility: 'AccessibilityStatement',
about: 'AboutAssessments',
contact: 'ContactPage',
}

for (const [name, componentName] of Object.entries(expected)) {
Expand Down
83 changes: 83 additions & 0 deletions apps/boekhouding-frontend/test/cov/views-ContactPage.cov.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, afterEach } from 'vitest'
import { mount } from '@vue/test-utils'

import ContactPage from '../../src/views/ContactPage.vue'

const AppHeaderStub = {
name: 'AppHeader',
props: ['backLabel', 'backRoute', 'showBack'],
template:
'<header class="app-header-stub" ' +
':data-back-label="backLabel" ' +
":data-back-route=\"backRoute === undefined ? '__undefined__' : backRoute\" " +
':data-show-back="String(showBack)"></header>',
}

function mountContact() {
return mount(ContactPage, {
global: { stubs: { AppHeader: AppHeaderStub } },
})
}

afterEach(() => {
window.history.replaceState(null, '', window.location.href)
})

describe('ContactPage', () => {
describe('hasHistory computed (window.history.state?.back)', () => {
it('is falsy when history.state is null (optional chaining short-circuits)', () => {
window.history.replaceState(null, '', window.location.href)

const header = mountContact().find('.app-header-stub')

expect(header.attributes('data-back-label')).toBe('Ga naar home')
expect(header.attributes('data-back-route')).toBe('/')
expect(header.attributes('data-show-back')).toBe('false')
})

it('is falsy when history.state exists but has no back entry', () => {
window.history.replaceState({ other: 'value' }, '', window.location.href)

const header = mountContact().find('.app-header-stub')

expect(header.attributes('data-back-label')).toBe('Ga naar home')
expect(header.attributes('data-back-route')).toBe('/')
expect(header.attributes('data-show-back')).toBe('false')
})

it('is truthy when history.state.back is set', () => {
window.history.replaceState({ back: '/' }, '', window.location.href)

const header = mountContact().find('.app-header-stub')

expect(header.attributes('data-back-label')).toBe('Terug')
expect(header.attributes('data-back-route')).toBe('__undefined__')
expect(header.attributes('data-show-back')).toBe('true')
})
})

describe('static content', () => {
it('renders the page heading and the two contact sections', () => {
const wrapper = mountContact()

expect(wrapper.find('h1.utrecht-heading-1').text()).toBe('Contact')
const text = wrapper.text()
expect(text).toContain('Vragen over de applicatie')
expect(text).toContain('Inhoudelijke vragen over pre-scan, DPIA of IAMA')
})

it('links to the RIG mailbox, GitHub issues and Privacy Adviseurs Rijk', () => {
const wrapper = mountContact()
const hrefs = wrapper.findAll('a').map((a) => a.attributes('href'))

expect(hrefs).toContain('mailto:RIG@rijksoverheid.nl')
expect(hrefs).toContain('https://github.com/MinBZK/par-dpia-form/issues')
expect(hrefs).toContain(
'https://rijksportaal.overheid-i.nl/organisaties/bzk/artikelen/dg-digitalisering-en-overheidsorganisatie-dgdoo/cio-rijk/informatiebeveiliging-en-privacy/privacy-adviseurs-rijk-par.html',
)
})
})
})
Loading