Skip to content

Commit

Permalink
Merge pull request #2990 from nextcloud/feature/add-docs-tests#2973
Browse files Browse the repository at this point in the history
Add docs and tests for #2973
  • Loading branch information
raimund-schluessler authored Aug 12, 2022
2 parents b908e39 + e31cdcf commit b4cbd40
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 3 deletions.
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",
"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,
},
},
emits: ['input'],
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)
})
})

0 comments on commit b4cbd40

Please sign in to comment.