Implement prefix of image urls with a filter

Fix #820

Ok, so after I would have to use the same method in three different
locations (`<ds-card>` expects an `image` attribute but cannot render
entire components) I decided to implement the prefix of image urls with
a filter rather than a component. The downside of this is that we have
to add the filter on a lot of component tests. The benefit is less
components and hopefully less complexity.
This commit is contained in:
Robert Schäfer 2019-06-13 16:56:41 +02:00
parent d0fd4de079
commit b8c5db48a6
12 changed files with 24 additions and 80 deletions

View File

@ -1,9 +1,11 @@
import { mount, createLocalVue } from '@vue/test-utils'
import Styleguide from '@human-connection/styleguide'
import Avatar from './Avatar.vue'
import Filters from '~/plugins/vue-filters'
const localVue = createLocalVue()
localVue.use(Styleguide)
localVue.use(Filters)
describe('Avatar.vue', () => {
let propsData = {}

View File

@ -1,5 +1,10 @@
<template>
<ds-avatar :image="avatarUrl" :name="userName" class="avatar" :size="size" />
<ds-avatar
:image="user && user.avatar | proxyApiUrl"
:name="userName"
class="avatar"
:size="size"
/>
</template>
<script>
@ -10,11 +15,6 @@ export default {
size: { type: String, default: 'small' },
},
computed: {
avatarUrl() {
const { avatar: imageSrc } = this.user || {}
if (!imageSrc) return imageSrc
return imageSrc.startsWith('/') ? imageSrc.replace('/', '/api/') : imageSrc
},
userName() {
const { name } = this.user || {}
// The name is used to display the initials in case

View File

@ -1,17 +1,13 @@
<template>
<div :class="[badges.length === 2 && 'hc-badges-dual']" class="hc-badges">
<div v-for="badge in badges" :key="badge.key" class="hc-badge-container">
<hc-image :title="badge.key" :image-props="{ src: badge.icon }" class="hc-badge" />
<img :title="badge.key" :src="badge.icon | proxyApiUrl" class="hc-badge" />
</div>
</div>
</template>
<script>
import HcImage from './Image'
export default {
components: {
HcImage,
},
props: {
badges: {
type: Array,

View File

@ -1,20 +0,0 @@
<template>
<img v-bind="imageProps" :src="imageSrc" />
</template>
<script>
export default {
props: {
imageProps: {
type: Object,
required: true,
},
},
computed: {
imageSrc() {
const src = this.imageProps.src
return src.startsWith('/') ? src.replace('/', '/api/') : src
},
},
}
</script>

View File

@ -1,39 +0,0 @@
import { shallowMount } from '@vue/test-utils'
import Image from '.'
describe('Image', () => {
let propsData = { imageProps: { class: 'hc-badge', src: '' } }
const Wrapper = () => {
return shallowMount(Image, { propsData })
}
it('renders', () => {
expect(Wrapper().is('img')).toBe(true)
})
it('passes properties down to `img`', () => {
expect(Wrapper().classes()).toEqual(['hc-badge'])
})
describe('given a relative `src`', () => {
beforeEach(() => {
propsData.imageProps.src = '/img/badges/fundraisingbox_de_airship.svg'
})
it('adds a prefix to load the image from the backend', () => {
expect(Wrapper().attributes('src')).toBe('/api/img/badges/fundraisingbox_de_airship.svg')
})
})
describe('given an absolute `src`', () => {
beforeEach(() => {
propsData.imageProps.src = 'http://lorempixel.com/640/480/animals'
})
it('keeps the URL as is', () => {
// e.g. our seeds have absolute image URLs
expect(Wrapper().attributes('src')).toBe('http://lorempixel.com/640/480/animals')
})
})
})

View File

@ -1,10 +1,12 @@
import { mount, createLocalVue } from '@vue/test-utils'
import ChangePassword from './Change.vue'
import Styleguide from '@human-connection/styleguide'
import Filters from '~/plugins/vue-filters'
const localVue = createLocalVue()
localVue.use(Styleguide)
localVue.use(Filters)
describe('ChangePassword.vue', () => {
let mocks

View File

@ -2,6 +2,7 @@ import { mount, createLocalVue, RouterLinkStub } from '@vue/test-utils'
import User from './index'
import Vuex from 'vuex'
import VTooltip from 'v-tooltip'
import Filters from '~/plugins/vue-filters'
import Styleguide from '@human-connection/styleguide'
@ -11,6 +12,7 @@ const filter = jest.fn(str => str)
localVue.use(Vuex)
localVue.use(VTooltip)
localVue.use(Styleguide)
localVue.use(Filters)
localVue.filter('truncate', filter)

View File

@ -3,11 +3,13 @@ import CommentList from '.'
import Empty from '~/components/Empty'
import Vuex from 'vuex'
import Styleguide from '@human-connection/styleguide'
import Filters from '~/plugins/vue-filters'
const localVue = createLocalVue()
localVue.use(Styleguide)
localVue.use(Vuex)
localVue.use(Filters)
localVue.filter('truncate', string => string)
config.stubs['v-popover'] = '<span><slot /></span>'

View File

@ -2,11 +2,13 @@ import { config, mount, shallowMount, createLocalVue } from '@vue/test-utils'
import ProfileSlug from './_slug.vue'
import Vuex from 'vuex'
import Styleguide from '@human-connection/styleguide'
import Filters from '~/plugins/vue-filters'
const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(Styleguide)
localVue.use(Filters)
localVue.filter('date', d => d)
config.stubs['no-ssr'] = '<span><slot /></span>'

View File

@ -2,11 +2,13 @@ import { mount, createLocalVue } from '@vue/test-utils'
import MySocialMedia from './my-social-media.vue'
import Vuex from 'vuex'
import Styleguide from '@human-connection/styleguide'
import Filters from '~/plugins/vue-filters'
const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(Styleguide)
localVue.use(Filters)
describe('my-social-media.vue', () => {
let wrapper

View File

@ -4,12 +4,7 @@
<ds-list>
<ds-list-item v-for="link in socialMediaLinks" :key="link.id">
<a :href="link.url" target="_blank">
<hc-image
:image-props="{ src: link.favicon }"
alt="Social Media link"
width="16"
height="16"
/>
<img :src="link.favicon | proxyApiUrl" alt="Social Media link" width="16" height="16" />
{{ link.url }}
</a>
&nbsp;&nbsp;
@ -44,12 +39,8 @@
<script>
import gql from 'graphql-tag'
import { mapGetters, mapMutations } from 'vuex'
import HcImage from '~/components/Image'
export default {
components: {
HcImage,
},
data() {
return {
value: '',

View File

@ -93,6 +93,10 @@ export default ({ app = {} }) => {
return excerpt
},
proxyApiUrl: url => {
if (!url) return url
return url.startsWith('/') ? url.replace('/', '/api/') : url
},
})
// add all methods as filters on each vue component