Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs and tests for #2973 #2990

Merged
merged 3 commits into from
Aug 12, 2022
Merged
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"lint": "eslint --ext .js,.vue src",
"lint:fix": "eslint --ext .js,.vue src --fix",
"test": "jest --verbose",
"test:coverage": "jest --verbose --coverage --no-cache",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used make test-coverage and noticed this command doesn't work because the script test:coverage wasn't present so i fixed this. It's not necessary but i think it's nice if the Makefile stages work :-)

"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css",
"stylelint:fix": "stylelint src/**/*.vue src/**/*.scss src/**/*.css --fix",
"styleguide": "vue-styleguidist server",
Expand Down
64 changes: 61 additions & 3 deletions src/components/MultiselectTags/MultiselectTags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
-->

<docs>
## Single tag selector
### Single tag selector

```vue
<template>
Expand All @@ -42,7 +42,7 @@ export default {
</script>
```

## Multiple tag selector
### Multiple tag selector
```vue
<template>
<div class="wrapper">
Expand All @@ -61,6 +61,64 @@ export default {
}
</script>
```

### Custom filter
Because of compatibility reasons only 5 tag entries are shown by default. If you want to show all available tags set the `filter` function-prop to `null`:
```vue
<template>
<div class="wrapper">
<MultiselectTags v-model="value" :filter="null" />
{{ value }}
</div>
</template>

<script>
export default {
data() {
return {
value: [1, 2]
}
}
}
</script>
```

It's also possible to apply any custom filter logic by setting the `filter` function-prop to any custom function receiving the tag element and the index:
```vue
<template>
<div class="wrapper">
<MultiselectTags v-model="value" :filter="customFilter" />
{{ value }}
</div>
</template>

<script>
export default {
data() {
return {
value: [3]
}
},
methods: {
/**
* Implement your custom filter logic to filter tags delivered
* by the server
*
* @param {object} the tag object
* @param {int} the index of the object inside the collection
*/
customFilter(element, index) {
/*
* Tag objects returned by the server will have the
* following properties (see also api.js):
* id, displayName, canAssign, userAssignable, userVisible
*/
return element.id >= 2 && element.displayName !== '' && element.canAssign && element.userAssignable && element.userVisible
}
}
}
</script>
```
</docs>

<template>
Expand Down Expand Up @@ -114,7 +172,7 @@ export default {
},
filter: {
type: Function,
default: (element, index) => index < 5,
default: (_element, index) => index < 5,
raimund-schluessler marked this conversation as resolved.
Show resolved Hide resolved
},
},
data() {
Expand Down
130 changes: 130 additions & 0 deletions tests/unit/components/MultiselectTags/MultiselectTags.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* @copyright Copyright (c) 2022 Robin Windey <ro.windey@gmail.com>
*
* @author Robin Windey <ro.windey@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { mount } from '@vue/test-utils'
import { searchTags } from '../../../../src/components/MultiselectTags/api.js'
import MultiselectTags from '../../../../src/components/MultiselectTags/MultiselectTags.vue'

jest.mock('../../../../src/components/MultiselectTags/api.js')

afterEach(() => {
jest.clearAllMocks()
})

describe('MultiselectTags.vue', () => {
'use strict'

it('Test that by default only 5 tags are shown', async () => {
const numberOfTags = 42
const mockedTags = []
for (let i = 0; i < numberOfTags; i++) {
mockedTags.push({
id: i,
displayName: 'tag ' + i,
canAssign: true,
userAssignable: true,
userVisible: true,
})
}

searchTags.mockResolvedValueOnce(mockedTags)

const wrapper = mount(MultiselectTags, {
propsData: {
label: 'name',
value: [],
},
})

// Wait for data to be loaded
await new Promise(process.nextTick)

const options = wrapper.findAll('li.multiselect__element .multiselect__option')

expect(searchTags).toHaveBeenCalledTimes(1)
expect(options.length).toBe(5)
})

it('Test that all available tags are shown if filter is null', async () => {
const numberOfTags = 42
const mockedTags = []
for (let i = 0; i < numberOfTags; i++) {
mockedTags.push({
id: i,
displayName: 'tag ' + i,
canAssign: true,
userAssignable: true,
userVisible: true,
})
}

searchTags.mockResolvedValueOnce(mockedTags)

const wrapper = mount(MultiselectTags, {
propsData: {
label: 'name',
value: [],
filter: null,
},
})

// Wait for data to be loaded
await new Promise(process.nextTick)

const options = wrapper.findAll('li.multiselect__element .multiselect__option')

expect(searchTags).toHaveBeenCalledTimes(1)
expect(options.length).toBe(numberOfTags)
})

it('Test that filter is applied correctly', async () => {
const numberOfTags = 42
const mockedTags = []
for (let i = 0; i < numberOfTags; i++) {
mockedTags.push({
id: i,
displayName: 'tag ' + i,
canAssign: true,
userAssignable: true,
userVisible: true,
})
}

searchTags.mockResolvedValueOnce(mockedTags)

const wrapper = mount(MultiselectTags, {
propsData: {
label: 'name',
value: [],
filter: (element, index) => index >= 40 && element.id >= 40,
},
})

// Wait for data to be loaded
await new Promise(process.nextTick)

const options = wrapper.findAll('li.multiselect__element .multiselect__option')

expect(searchTags).toHaveBeenCalledTimes(1)
expect(options.length).toBe(2)
})
})