update tests

This commit is contained in:
einhornimmond 2024-06-24 15:18:57 +02:00
parent f4d0d8cf7c
commit 70f8b6d18b
10 changed files with 433 additions and 160 deletions

View File

@ -1,9 +1,19 @@
import { createMockClient } from 'mock-apollo-client'
import { mount } from '@vue/test-utils'
import VueApollo from 'vue-apollo'
import Vuex from 'vuex'
import CommunityVisualizeItem from './CommunityVisualizeItem.vue'
import { updateHomeCommunity } from '../../graphql/updateHomeCommunity'
import { toastSuccessSpy } from '../../../test/testSetup'
const mockClient = createMockClient()
const apolloProvider = new VueApollo({
defaultClient: mockClient,
})
const localVue = global.localVue
localVue.use(Vuex)
localVue.use(VueApollo)
const today = new Date()
const createdDate = new Date()
createdDate.setDate(createdDate.getDate() - 3)
@ -19,7 +29,7 @@ const store = new Vuex.Store({
let propsData = {
item: {
id: 1,
uuid: 1,
foreign: false,
url: 'http://localhost/api/',
publicKey: '4007170edd8d33fb009cd99ee4e87f214e7cd21b668d45540a064deb42e243c2',
@ -76,8 +86,18 @@ const mocks = {
describe('CommunityVisualizeItem', () => {
let wrapper
const updateHomeCommunityMock = jest.fn()
mockClient.setRequestHandler(
updateHomeCommunity,
updateHomeCommunityMock.mockResolvedValue({
data: {
updateHomeCommunity: { id: 1 },
},
}),
)
const Wrapper = () => {
return mount(CommunityVisualizeItem, { localVue, mocks, propsData, store })
return mount(CommunityVisualizeItem, { localVue, mocks, propsData, store, apolloProvider })
}
describe('mount', () => {
@ -152,7 +172,7 @@ describe('CommunityVisualizeItem', () => {
beforeEach(() => {
propsData = {
item: {
id: 7590,
uuid: 7590,
foreign: false,
publicKey: 'eaf6a426b24fd54f8fbae11c17700fc595080ca25159579c63d38dbc64284ba7',
url: 'http://localhost/api/2_0',
@ -195,7 +215,7 @@ describe('CommunityVisualizeItem', () => {
beforeEach(() => {
propsData = {
item: {
id: 7590,
uuid: 7590,
foreign: false,
publicKey: 'eaf6a426b24fd54f8fbae11c17700fc595080ca25159579c63d38dbc64284ba7',
url: 'http://localhost/api/',
@ -219,7 +239,7 @@ describe('CommunityVisualizeItem', () => {
beforeEach(() => {
propsData = {
item: {
id: 7590,
uuid: 7590,
foreign: false,
publicKey: 'eaf6a426b24fd54f8fbae11c17700fc595080ca25159579c63d38dbc64284ba7',
url: 'http://localhost/api/2_0',
@ -237,6 +257,103 @@ describe('CommunityVisualizeItem', () => {
expect(wrapper.vm.createdAt).toBe('')
})
})
describe('test handleUpdateHomeCommunity', () => {
describe('gms api key', () => {
beforeEach(async () => {
wrapper = Wrapper()
wrapper.vm.originalGmsApiKey = 'original'
wrapper.vm.gmsApiKey = 'changed key'
await wrapper.vm.handleUpdateHomeCommunity()
// Wait for the next tick to allow async operations to complete
await wrapper.vm.$nextTick()
})
it('expect changed gms api key', () => {
expect(updateHomeCommunityMock).toBeCalledWith({
uuid: propsData.item.uuid,
gmsApiKey: 'changed key',
location: undefined,
})
expect(wrapper.vm.originalGmsApiKey).toBe('changed key')
expect(toastSuccessSpy).toBeCalledWith('federation.toast_gmsApiKeyUpdated')
})
})
describe('location', () => {
beforeEach(async () => {
wrapper = Wrapper()
wrapper.vm.originalLocation = { coordinates: [1.212, 15.121], type: 'Point' }
wrapper.vm.location = { coordinates: [17.212, 1.121], type: 'Point' }
await wrapper.vm.handleUpdateHomeCommunity()
// Wait for the next tick to allow async operations to complete
await wrapper.vm.$nextTick()
})
it('expect changed location', () => {
expect(updateHomeCommunityMock).toBeCalledWith({
uuid: propsData.item.uuid,
location: { coordinates: [17.212, 1.121], type: 'Point' },
gmsApiKey: undefined,
})
expect(wrapper.vm.originalLocation).toStrictEqual({
coordinates: [17.212, 1.121],
type: 'Point',
})
expect(toastSuccessSpy).toBeCalledWith('federation.toast_gmsLocationUpdated')
})
})
describe('gms api key and location', () => {
beforeEach(async () => {
wrapper = Wrapper()
wrapper.vm.originalGmsApiKey = 'original'
wrapper.vm.gmsApiKey = 'changed key'
wrapper.vm.originalLocation = { coordinates: [1.212, 15.121], type: 'Point' }
wrapper.vm.location = { coordinates: [17.212, 1.121], type: 'Point' }
await wrapper.vm.handleUpdateHomeCommunity()
// Wait for the next tick to allow async operations to complete
await wrapper.vm.$nextTick()
})
it('expect changed gms api key and changed location', () => {
expect(updateHomeCommunityMock).toBeCalledWith({
uuid: propsData.item.uuid,
gmsApiKey: 'changed key',
location: undefined,
})
expect(wrapper.vm.originalGmsApiKey).toBe('changed key')
expect(wrapper.vm.originalLocation).toStrictEqual({
coordinates: [17.212, 1.121],
type: 'Point',
})
expect(toastSuccessSpy).toBeCalledWith('federation.toast_gmsApiKeyAndLocationUpdated')
})
})
})
describe('test resetHomeCommunityEditable', () => {
beforeEach(async () => {
wrapper = Wrapper()
})
it('test', () => {
wrapper.vm.originalGmsApiKey = 'original'
wrapper.vm.gmsApiKey = 'changed key'
wrapper.vm.originalLocation = { coordinates: [1.212, 15.121], type: 'Point' }
wrapper.vm.location = { coordinates: [17.212, 1.121], type: 'Point' }
wrapper.vm.resetHomeCommunityEditable()
expect(wrapper.vm.location).toStrictEqual({
coordinates: [1.212, 15.121],
type: 'Point',
})
expect(wrapper.vm.gmsApiKey).toBe('original')
})
})
})
})
})

View File

@ -45,7 +45,11 @@
</b-form-group>
</template>
<template #edit>
<g-m-s-api-key v-model="gmsApiKey" />
<editable-groupable-label
v-model="gmsApiKey"
:label="$t('federation.gmsApiKey')"
idName="home-community-api-key"
/>
<coordinates v-model="location" />
</template>
</editable-group>
@ -81,7 +85,7 @@ import EditableGroup from '@/components/input/EditableGroup'
import FederationVisualizeItem from './FederationVisualizeItem.vue'
import { updateHomeCommunity } from '../../graphql/updateHomeCommunity'
import Coordinates from '../input/Coordinates.vue'
import GMSApiKey from './GMSApiKey.vue'
import EditableGroupableLabel from '../input/EditableGroupableLabel.vue'
const locales = { en, de, es, fr, nl }
@ -91,7 +95,7 @@ export default {
Coordinates,
EditableGroup,
FederationVisualizeItem,
GMSApiKey,
EditableGroupableLabel,
},
props: {
item: { type: Object },

View File

@ -0,0 +1,119 @@
import { mount } from '@vue/test-utils'
import Coordinates from './Coordinates.vue'
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const localVue = global.localVue
const i18n = new VueI18n({
locale: 'en',
messages: {
en: {
'geo-coordinates.format': '{latitude}, {longitude}',
},
},
})
describe('Coordinates', () => {
let wrapper
const value = {
type: 'Point',
coordinates: [12.34, 56.78],
}
const createWrapper = (propsData) => {
return mount(Coordinates, {
localVue,
i18n,
propsData,
})
}
beforeEach(() => {
wrapper = createWrapper({ value })
})
it('renders the component with initial values', () => {
expect(wrapper.find('#home-community-latitude').element.value).toBe('56.78')
expect(wrapper.find('#home-community-longitude').element.value).toBe('12.34')
expect(wrapper.find('#home-community-latitude-longitude-smart').element.value).toBe(
'56.78, 12.34',
)
})
it('updates latitude and longitude when input changes', async () => {
const latitudeInput = wrapper.find('#home-community-latitude')
const longitudeInput = wrapper.find('#home-community-longitude')
await latitudeInput.setValue('34.56')
await longitudeInput.setValue('78.90')
expect(wrapper.vm.latitude).toBe('34.56')
expect(wrapper.vm.longitude).toBe('78.90')
})
it('emits input event with updated values', async () => {
const latitudeInput = wrapper.find('#home-community-latitude')
const longitudeInput = wrapper.find('#home-community-longitude')
await latitudeInput.setValue('34.56')
expect(wrapper.emitted().input).toBeTruthy()
expect(wrapper.emitted().input[0][0]).toEqual({
type: 'Point',
coordinates: [12.34, 34.56],
})
await longitudeInput.setValue('78.90')
expect(wrapper.emitted().input).toBeTruthy()
expect(wrapper.emitted().input[1][0]).toEqual({
type: 'Point',
coordinates: [78.9, 34.56],
})
})
it('updates latitudeLongitude when latitude or longitude changes', async () => {
const latitudeInput = wrapper.find('#home-community-latitude')
const longitudeInput = wrapper.find('#home-community-longitude')
await latitudeInput.setValue('34.56')
await longitudeInput.setValue('78.90')
expect(wrapper.vm.latitudeLongitude).toBe('34.56, 78.90')
})
it('splits coordinates correctly when entering in latitudeLongitude input', async () => {
const latitudeLongitudeInput = wrapper.find('#home-community-latitude-longitude-smart')
await latitudeLongitudeInput.setValue('34.56, 78.90')
await latitudeLongitudeInput.trigger('input')
expect(wrapper.vm.latitude).toBe(34.56)
expect(wrapper.vm.longitude).toBe(78.9)
})
it('sets inputValue to null if coordinates are invalid', async () => {
const latitudeInput = wrapper.find('#home-community-latitude')
const longitudeInput = wrapper.find('#home-community-longitude')
await latitudeInput.setValue('invalid')
await longitudeInput.setValue('78.90')
expect(wrapper.vm.inputValue).toBeNull()
})
it('validates coordinates correctly', async () => {
const latitudeInput = wrapper.find('#home-community-latitude')
const longitudeInput = wrapper.find('#home-community-longitude')
await latitudeInput.setValue('invalid')
await longitudeInput.setValue('78.90')
expect(wrapper.vm.isValid).toBe(false)
await latitudeInput.setValue('34.56')
await longitudeInput.setValue('78.90')
expect(wrapper.vm.isValid).toBe(true)
})
})

View File

@ -39,6 +39,7 @@
<script>
export default {
name: 'Coordinates',
props: {
value: Object,
default: null,

View File

@ -0,0 +1,92 @@
import { mount } from '@vue/test-utils'
import EditableGroup from './EditableGroup.vue'
const localVue = global.localVue
const viewValue = 'test label value'
const editValue = 'test edit value'
const mocks = {
$t: jest.fn((t) => t),
}
describe('EditableGroup', () => {
let wrapper
const createWrapper = (propsData) => {
return mount(EditableGroup, {
localVue,
propsData,
mocks,
slots: {
view: `<div>${viewValue}</div>`,
edit: `<div class='test-edit'>${editValue}</div>`,
},
})
}
it('renders the view slot when not editing', () => {
wrapper = createWrapper({ allowEdit: true })
expect(wrapper.find('div').text()).toBe(viewValue)
})
it('renders the edit slot when editing', async () => {
wrapper = createWrapper({ allowEdit: true })
await wrapper.find('button').trigger('click')
expect(wrapper.find('.test-edit').text()).toBe(editValue)
})
it('emits save event when clicking save button', async () => {
wrapper = createWrapper({ allowEdit: true })
await wrapper.find('button').trigger('click') // Click to enable editing
await wrapper.vm.$emit('input', 'New Value') // Simulate input change
await wrapper.setData({ isValueChanged: true }) // Set valueChanged to true
await wrapper.find('button').trigger('click') // Click to save
expect(wrapper.emitted().save).toBeTruthy()
})
it('disables save button when value is not changed', async () => {
wrapper = createWrapper({ allowEdit: true })
await wrapper.find('button').trigger('click') // Click to enable editing
expect(wrapper.find('button').attributes('disabled')).toBe('disabled')
})
it('enables save button when value is changed', async () => {
wrapper = createWrapper({ allowEdit: true })
await wrapper.find('button').trigger('click') // Click to enable editing
await wrapper.vm.$emit('input', 'New Value') // Simulate input change
await wrapper.setData({ isValueChanged: true }) // Set valueChanged to true
expect(wrapper.find('button').attributes('disabled')).toBeFalsy()
})
it('updates variant to success when editing', async () => {
wrapper = createWrapper({ allowEdit: true })
await wrapper.find('button').trigger('click') // Click to enable editing
expect(wrapper.vm.variant).toBe('success')
})
it('updates variant to prime when not editing', async () => {
wrapper = createWrapper({ allowEdit: true })
expect(wrapper.vm.variant).toBe('prime')
})
it('emits reset event when clicking close button', async () => {
wrapper = createWrapper({ allowEdit: true })
await wrapper.find('button').trigger('click') // Click to enable editing
await wrapper.find('button.close-button').trigger('click') // Click close button
expect(wrapper.emitted().reset).toBeTruthy()
})
})

View File

@ -8,10 +8,10 @@
</b-button>
</b-form-group>
<b-form-group v-else-if="allowEdit && isEditing">
<b-button @click="save" :variant="variant" :disabled="!isValueChanged">
<b-button @click="save" :variant="variant" :disabled="!isValueChanged" class="save-button">
{{ $t('save') }}
</b-button>
<b-button @click="close" variant="secondary">
<b-button @click="close" variant="secondary" class="close-button">
{{ $t('close') }}
</b-button>
</b-form-group>

View File

@ -0,0 +1,79 @@
import { mount } from '@vue/test-utils'
import EditableGroupableLabel from './EditableGroupableLabel.vue'
const localVue = global.localVue
const value = 'test label value'
const label = 'Test Label'
const idName = 'test-id-name'
describe('EditableGroupableLabel', () => {
let wrapper
const createWrapper = (propsData) => {
return mount(EditableGroupableLabel, {
localVue,
propsData,
})
}
beforeEach(() => {
wrapper = createWrapper({ value, label, idName })
})
it('renders the label correctly', () => {
expect(wrapper.find('label').text()).toBe(label)
})
it('renders the input with the correct id and value', () => {
const input = wrapper.find('input')
expect(input.attributes('id')).toBe(idName)
expect(input.element.value).toBe(value)
})
it('emits input event with the correct value when input changes', async () => {
const newValue = 'new label value'
const input = wrapper.find('input')
input.element.value = newValue
await input.trigger('input')
expect(wrapper.emitted().input).toBeTruthy()
expect(wrapper.emitted().input[0][0]).toBe(newValue)
})
it('calls valueChanged method on parent when value changes', async () => {
const valueChangedMock = jest.fn()
wrapper.vm.$parent = { valueChanged: valueChangedMock }
const newValue = 'new label value'
const input = wrapper.find('input')
input.element.value = newValue
await input.trigger('input')
expect(valueChangedMock).toHaveBeenCalled()
})
it('calls invalidValues method on parent when value is reverted to original', async () => {
const invalidValuesMock = jest.fn()
wrapper.vm.$parent = { invalidValues: invalidValuesMock }
const input = wrapper.find('input')
input.element.value = 'new label value'
await input.trigger('input')
input.element.value = value
await input.trigger('input')
expect(invalidValuesMock).toHaveBeenCalled()
})
it('does not call valueChanged method on parent when value is reverted to original', async () => {
const valueChangedMock = jest.fn()
wrapper.vm.$parent = { valueChanged: valueChangedMock }
const input = wrapper.find('input')
input.element.value = value
await input.trigger('input')
expect(valueChangedMock).not.toHaveBeenCalled()
})
})

View File

@ -1,18 +1,26 @@
<template>
<b-form-group :label="$t('federation.gmsApiKey')" label-for="home-community-api-key">
<b-form-input id="home-community-api-key" v-model="inputValue" @input="updateValue" />
<b-form-group :label="label" :label-for="idName">
<b-form-input :id="idName" v-model="inputValue" @input="updateValue" />
</b-form-group>
</template>
<script>
export default {
name: 'GMSApiKey',
name: 'EditableGroupableLabel',
props: {
value: {
type: String,
required: false,
default: null,
},
label: {
type: String,
required: true,
},
idName: {
type: String,
required: true,
},
},
data() {
return {

View File

@ -1,83 +0,0 @@
// Test written by ChatGPT 3.5
import { mount } from '@vue/test-utils'
import EditableLabel from './EditableLabel.vue'
const localVue = global.localVue
const value = 'test label value'
describe('EditableLabel', () => {
let wrapper
const createWrapper = (propsData) => {
return mount(EditableLabel, {
localVue,
propsData,
})
}
it('renders the label when not editing', () => {
wrapper = createWrapper({ value, allowEdit: true })
expect(wrapper.find('label').text()).toBe(value)
})
it('renders the input when editing', async () => {
wrapper = createWrapper({ value, allowEdit: true })
await wrapper.find('button').trigger('click')
expect(wrapper.find('input').exists()).toBe(true)
})
it('emits save event when clicking save button', async () => {
wrapper = createWrapper({ value, allowEdit: true })
await wrapper.find('button').trigger('click')
await wrapper.setData({ inputValue: 'New Value' })
await wrapper.find('button').trigger('click')
expect(wrapper.emitted().save).toBeTruthy()
expect(wrapper.emitted().save[0][0]).toBe('New Value')
})
it('disables save button when value is not changed', async () => {
wrapper = createWrapper({ value, allowEdit: true })
await wrapper.find('button').trigger('click')
expect(wrapper.find('button').attributes('disabled')).toBe('disabled')
})
it('enables save button when value is changed', async () => {
wrapper = createWrapper({ value, allowEdit: true })
await wrapper.find('button').trigger('click')
await wrapper.setData({ inputValue: 'New Value' })
expect(wrapper.find('button').attributes('disabled')).toBeFalsy()
})
it('updates originalValue when saving changes', async () => {
wrapper = createWrapper({ value, allowEdit: true })
await wrapper.find('button').trigger('click')
await wrapper.setData({ inputValue: 'New Value' })
await wrapper.find('button').trigger('click')
expect(wrapper.vm.originalValue).toBe('New Value')
})
it('changes variant to success when editing', async () => {
wrapper = createWrapper({ value, allowEdit: true })
await wrapper.find('button').trigger('click')
expect(wrapper.vm.variant).toBe('success')
})
it('changes variant to prime when not editing', async () => {
wrapper = createWrapper({ value, allowEdit: true })
expect(wrapper.vm.variant).toBe('prime')
})
})

View File

@ -1,64 +0,0 @@
<template>
<div>
<b-form-group>
<label v-if="!editing">{{ value }}</label>
<b-form-input v-else v-model="inputValue" :placeholder="placeholder" />
</b-form-group>
<b-button
v-if="allowEdit"
@click="toggleEdit"
:disabled="!isValueChanged && editing"
:variant="variant"
>
<b-icon v-if="!editing" icon="pencil-fill" tooltip="$t('edit')"></b-icon>
<b-icon v-else icon="check" tooltip="$t('save')"></b-icon>
</b-button>
</div>
</template>
<script>
export default {
// Code written from chatGPT 3.5
name: 'EditableLabel',
props: {
value: {
type: String,
required: false,
default: '',
},
allowEdit: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
required: false,
default: '',
},
},
data() {
return {
editing: false,
inputValue: this.value,
originalValue: this.value,
}
},
computed: {
variant() {
return this.editing ? 'success' : 'prime'
},
isValueChanged() {
return this.inputValue !== this.originalValue
},
},
methods: {
toggleEdit() {
if (this.editing) {
this.$emit('save', this.inputValue)
this.originalValue = this.inputValue
}
this.editing = !this.editing
},
},
}
</script>