summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js')
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js212
1 files changed, 140 insertions, 72 deletions
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
index 3b50927dcc6..f50eafdbc52 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
@@ -1,13 +1,13 @@
import {
- GlFilteredSearchToken,
GlFilteredSearchTokenSegment,
GlFilteredSearchSuggestion,
GlDropdownDivider,
+ GlAvatar,
} from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
-import { deprecatedCreateFlash as createFlash } from '~/flash';
+import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import {
@@ -15,6 +15,7 @@ import {
DEFAULT_NONE_ANY,
} from '~/vue_shared/components/filtered_search_bar/constants';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
+import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { mockAuthorToken, mockAuthors } from '../mock_data';
@@ -29,12 +30,22 @@ const defaultStubs = {
},
};
+const mockPreloadedAuthors = [
+ {
+ id: 13,
+ name: 'Administrator',
+ username: 'root',
+ avatar_url: 'avatar/url',
+ },
+];
+
function createComponent(options = {}) {
const {
config = mockAuthorToken,
value = { data: '' },
active = false,
stubs = defaultStubs,
+ data = {},
} = options;
return mount(AuthorToken, {
propsData: {
@@ -47,132 +58,172 @@ function createComponent(options = {}) {
alignSuggestions: function fakeAlignSuggestions() {},
suggestionsListClass: 'custom-class',
},
+ data() {
+ return { ...data };
+ },
stubs,
});
}
describe('AuthorToken', () => {
+ const originalGon = window.gon;
+ const currentUserLength = 1;
let mock;
let wrapper;
+ const getBaseToken = () => wrapper.findComponent(BaseToken);
+
beforeEach(() => {
mock = new MockAdapter(axios);
- wrapper = createComponent();
});
afterEach(() => {
+ window.gon = originalGon;
mock.restore();
wrapper.destroy();
});
- describe('computed', () => {
- describe('currentValue', () => {
- it('returns lowercase string for `value.data`', () => {
- wrapper = createComponent({ value: { data: 'FOO' } });
-
- expect(wrapper.vm.currentValue).toBe('foo');
+ describe('methods', () => {
+ describe('fetchAuthorBySearchTerm', () => {
+ beforeEach(() => {
+ wrapper = createComponent();
});
- });
- describe('activeAuthor', () => {
- it('returns object for currently present `value.data`', async () => {
- wrapper = createComponent({ value: { data: mockAuthors[0].username } });
-
- wrapper.setData({
- authors: mockAuthors,
- });
+ it('calls `config.fetchAuthors` with provided searchTerm param', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors');
- await wrapper.vm.$nextTick();
+ getBaseToken().vm.$emit('fetch-token-values', mockAuthors[0].username);
- expect(wrapper.vm.activeAuthor).toEqual(mockAuthors[0]);
+ expect(wrapper.vm.config.fetchAuthors).toHaveBeenCalledWith(
+ mockAuthorToken.fetchPath,
+ mockAuthors[0].username,
+ );
});
- });
- });
-
- describe('fetchAuthorBySearchTerm', () => {
- it('calls `config.fetchAuthors` with provided searchTerm param', () => {
- jest.spyOn(wrapper.vm.config, 'fetchAuthors');
-
- wrapper.vm.fetchAuthorBySearchTerm(mockAuthors[0].username);
- expect(wrapper.vm.config.fetchAuthors).toHaveBeenCalledWith(
- mockAuthorToken.fetchPath,
- mockAuthors[0].username,
- );
- });
-
- it('sets response to `authors` when request is succesful', () => {
- jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockResolvedValue(mockAuthors);
+ it('sets response to `authors` when request is succesful', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockResolvedValue(mockAuthors);
- wrapper.vm.fetchAuthorBySearchTerm('root');
+ getBaseToken().vm.$emit('fetch-token-values', 'root');
- return waitForPromises().then(() => {
- expect(wrapper.vm.authors).toEqual(mockAuthors);
+ return waitForPromises().then(() => {
+ expect(getBaseToken().props('tokenValues')).toEqual(mockAuthors);
+ });
});
- });
- it('calls `createFlash` with flash error message when request fails', () => {
- jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({});
+ it('calls `createFlash` with flash error message when request fails', () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({});
- wrapper.vm.fetchAuthorBySearchTerm('root');
+ getBaseToken().vm.$emit('fetch-token-values', 'root');
- return waitForPromises().then(() => {
- expect(createFlash).toHaveBeenCalledWith('There was a problem fetching users.');
+ return waitForPromises().then(() => {
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'There was a problem fetching users.',
+ });
+ });
});
- });
- it('sets `loading` to false when request completes', () => {
- jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({});
+ it('sets `loading` to false when request completes', async () => {
+ jest.spyOn(wrapper.vm.config, 'fetchAuthors').mockRejectedValue({});
- wrapper.vm.fetchAuthorBySearchTerm('root');
+ getBaseToken().vm.$emit('fetch-token-values', 'root');
- return waitForPromises().then(() => {
- expect(wrapper.vm.loading).toBe(false);
+ await waitForPromises();
+
+ expect(getBaseToken().props('tokensListLoading')).toBe(false);
});
});
});
describe('template', () => {
- beforeEach(() => {
- wrapper.setData({
- authors: mockAuthors,
+ const activateTokenValuesList = async () => {
+ const tokenSegments = wrapper.findAllComponents(GlFilteredSearchTokenSegment);
+ const suggestionsSegment = tokenSegments.at(2);
+ suggestionsSegment.vm.$emit('activate');
+ await wrapper.vm.$nextTick();
+ };
+
+ it('renders base-token component', () => {
+ wrapper = createComponent({
+ value: { data: mockAuthors[0].username },
+ data: { authors: mockAuthors },
});
- return wrapper.vm.$nextTick();
- });
+ const baseTokenEl = getBaseToken();
- it('renders gl-filtered-search-token component', () => {
- expect(wrapper.find(GlFilteredSearchToken).exists()).toBe(true);
+ expect(baseTokenEl.exists()).toBe(true);
+ expect(baseTokenEl.props()).toMatchObject({
+ tokenValues: mockAuthors,
+ fnActiveTokenValue: wrapper.vm.getActiveAuthor,
+ });
});
it('renders token item when value is selected', () => {
- wrapper.setProps({
+ wrapper = createComponent({
value: { data: mockAuthors[0].username },
+ data: { authors: mockAuthors },
+ stubs: { Portal: true },
});
return wrapper.vm.$nextTick(() => {
const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
expect(tokenSegments).toHaveLength(3); // Author, =, "Administrator"
- expect(tokenSegments.at(2).text()).toBe(mockAuthors[0].name); // "Administrator"
+
+ const tokenValue = tokenSegments.at(2);
+
+ expect(tokenValue.findComponent(GlAvatar).props('src')).toBe(mockAuthors[0].avatar_url);
+ expect(tokenValue.text()).toBe(mockAuthors[0].name); // "Administrator"
});
});
+ it('renders token value with correct avatarUrl from author object', async () => {
+ const getAvatarEl = () =>
+ wrapper.findAll(GlFilteredSearchTokenSegment).at(2).findComponent(GlAvatar);
+
+ wrapper = createComponent({
+ value: { data: mockAuthors[0].username },
+ data: {
+ authors: [
+ {
+ ...mockAuthors[0],
+ },
+ ],
+ },
+ stubs: { Portal: true },
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(getAvatarEl().props('src')).toBe(mockAuthors[0].avatar_url);
+
+ wrapper.setData({
+ authors: [
+ {
+ ...mockAuthors[0],
+ avatarUrl: mockAuthors[0].avatar_url,
+ avatar_url: undefined,
+ },
+ ],
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(getAvatarEl().props('src')).toBe(mockAuthors[0].avatar_url);
+ });
+
it('renders provided defaultAuthors as suggestions', async () => {
const defaultAuthors = DEFAULT_NONE_ANY;
wrapper = createComponent({
active: true,
- config: { ...mockAuthorToken, defaultAuthors },
+ config: { ...mockAuthorToken, defaultAuthors, preloadedAuthors: mockPreloadedAuthors },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
- const suggestionsSegment = tokenSegments.at(2);
- suggestionsSegment.vm.$emit('activate');
- await wrapper.vm.$nextTick();
+
+ await activateTokenValuesList();
const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
- expect(suggestions).toHaveLength(defaultAuthors.length);
+ expect(suggestions).toHaveLength(defaultAuthors.length + currentUserLength);
defaultAuthors.forEach((label, index) => {
expect(suggestions.at(index).text()).toBe(label.text);
});
@@ -189,25 +240,42 @@ describe('AuthorToken', () => {
suggestionsSegment.vm.$emit('activate');
await wrapper.vm.$nextTick();
- expect(wrapper.find(GlFilteredSearchSuggestion).exists()).toBe(false);
expect(wrapper.find(GlDropdownDivider).exists()).toBe(false);
});
it('renders `DEFAULT_LABEL_ANY` as default suggestions', async () => {
wrapper = createComponent({
active: true,
- config: { ...mockAuthorToken },
+ config: { ...mockAuthorToken, preloadedAuthors: mockPreloadedAuthors },
stubs: { Portal: true },
});
- const tokenSegments = wrapper.findAll(GlFilteredSearchTokenSegment);
- const suggestionsSegment = tokenSegments.at(2);
- suggestionsSegment.vm.$emit('activate');
- await wrapper.vm.$nextTick();
+
+ await activateTokenValuesList();
const suggestions = wrapper.findAll(GlFilteredSearchSuggestion);
- expect(suggestions).toHaveLength(1);
+ expect(suggestions).toHaveLength(1 + currentUserLength);
expect(suggestions.at(0).text()).toBe(DEFAULT_LABEL_ANY.text);
});
+
+ describe('when loading', () => {
+ beforeEach(() => {
+ wrapper = createComponent({
+ active: true,
+ config: {
+ ...mockAuthorToken,
+ preloadedAuthors: mockPreloadedAuthors,
+ defaultAuthors: [],
+ },
+ stubs: { Portal: true },
+ });
+ });
+
+ it('shows current user', () => {
+ const firstSuggestion = wrapper.findComponent(GlFilteredSearchSuggestion).text();
+ expect(firstSuggestion).toContain('Administrator');
+ expect(firstSuggestion).toContain('@root');
+ });
+ });
});
});