106 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| import { GlSearchBoxByType, GlAvatarLabeled, GlDropdownItem } from '@gitlab/ui';
 | |
| import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
 | |
| import waitForPromises from 'helpers/wait_for_promises';
 | |
| import * as projectsApi from '~/api/projects_api';
 | |
| import ProjectSelect from '~/invite_members/components/project_select.vue';
 | |
| import { allProjects, project1 } from '../mock_data/api_response_data';
 | |
| 
 | |
| describe('ProjectSelect', () => {
 | |
|   let wrapper;
 | |
| 
 | |
|   const createComponent = () => {
 | |
|     wrapper = shallowMountExtended(ProjectSelect, {});
 | |
|   };
 | |
| 
 | |
|   beforeEach(() => {
 | |
|     jest.spyOn(projectsApi, 'getProjects').mockResolvedValue(allProjects);
 | |
| 
 | |
|     createComponent();
 | |
|   });
 | |
| 
 | |
|   afterEach(() => {
 | |
|     wrapper.destroy();
 | |
|   });
 | |
| 
 | |
|   const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
 | |
|   const findDropdownItem = (index) => wrapper.findAllComponents(GlDropdownItem).at(index);
 | |
|   const findAvatarLabeled = (index) => findDropdownItem(index).findComponent(GlAvatarLabeled);
 | |
|   const findEmptyResultMessage = () => wrapper.findByTestId('empty-result-message');
 | |
|   const findErrorMessage = () => wrapper.findByTestId('error-message');
 | |
| 
 | |
|   it('renders GlSearchBoxByType with default attributes', () => {
 | |
|     expect(findSearchBoxByType().exists()).toBe(true);
 | |
|     expect(findSearchBoxByType().vm.$attrs).toMatchObject({
 | |
|       placeholder: 'Search projects',
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('when user types in the search input', () => {
 | |
|     let resolveApiRequest;
 | |
|     let rejectApiRequest;
 | |
| 
 | |
|     beforeEach(() => {
 | |
|       jest.spyOn(projectsApi, 'getProjects').mockImplementation(
 | |
|         () =>
 | |
|           new Promise((resolve, reject) => {
 | |
|             resolveApiRequest = resolve;
 | |
|             rejectApiRequest = reject;
 | |
|           }),
 | |
|       );
 | |
| 
 | |
|       findSearchBoxByType().vm.$emit('input', project1.name);
 | |
|     });
 | |
| 
 | |
|     it('calls the API', () => {
 | |
|       resolveApiRequest({ data: allProjects });
 | |
| 
 | |
|       expect(projectsApi.getProjects).toHaveBeenCalledWith(project1.name, {
 | |
|         active: true,
 | |
|         exclude_internal: true,
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     it('displays loading icon while waiting for API call to resolve and then sets loading false', async () => {
 | |
|       expect(findSearchBoxByType().props('isLoading')).toBe(true);
 | |
| 
 | |
|       resolveApiRequest({ data: allProjects });
 | |
|       await waitForPromises();
 | |
| 
 | |
|       expect(findSearchBoxByType().props('isLoading')).toBe(false);
 | |
|       expect(findEmptyResultMessage().exists()).toBe(false);
 | |
|       expect(findErrorMessage().exists()).toBe(false);
 | |
|     });
 | |
| 
 | |
|     it('displays a dropdown item and avatar for each project fetched', async () => {
 | |
|       resolveApiRequest({ data: allProjects });
 | |
|       await waitForPromises();
 | |
| 
 | |
|       allProjects.forEach((project, index) => {
 | |
|         expect(findDropdownItem(index).attributes('name')).toBe(project.name_with_namespace);
 | |
|         expect(findAvatarLabeled(index).attributes()).toMatchObject({
 | |
|           src: project.avatar_url,
 | |
|           'entity-id': String(project.id),
 | |
|           'entity-name': project.name_with_namespace,
 | |
|         });
 | |
|         expect(findAvatarLabeled(index).props('label')).toBe(project.name_with_namespace);
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     it('displays the empty message when the API results are empty', async () => {
 | |
|       resolveApiRequest({ data: [] });
 | |
|       await waitForPromises();
 | |
| 
 | |
|       expect(findEmptyResultMessage().text()).toBe('No matching results');
 | |
|     });
 | |
| 
 | |
|     it('displays the error message when the fetch fails', async () => {
 | |
|       rejectApiRequest();
 | |
|       await waitForPromises();
 | |
| 
 | |
|       expect(findErrorMessage().text()).toBe(
 | |
|         'There was an error fetching the projects. Please try again.',
 | |
|       );
 | |
|     });
 | |
|   });
 | |
| });
 |