text: import Vue from 'vue';
  import MockAdapter from 'axios-mock-adapter';
  import { TEST_HOST } from 'helpers/test_constants';
  import mountComponent from 'helpers/vue_mount_component_helper';
  import axios from '~/lib/utils/axios_utils';
  
  import updateUsername from '~/profile/account/components/update_username.vue';
  
  describe('UpdateUsername component', () => {
    const rootUrl = TEST_HOST;
    const actionUrl = `${TEST_HOST}/update/username`;
    const username = 'hasnoname';
    const newUsername = 'new_username';
    let Component;
    let vm;
    let axiosMock;
  
    beforeEach(() => {
      axiosMock = new MockAdapter(axios);
      Component = Vue.extend(updateUsername);
      vm = mountComponent(Component, {
        actionUrl,
        rootUrl,
        initialUsername: username,
      });
    });
  
    afterEach(() => {
      vm.$destroy();
      axiosMock.restore();
    });
  
    const findElements = () => {
      const modalSelector = `#${vm.$options.modalId}`;
  
      return {
        input: vm.$el.querySelector(`#${vm.$options.inputId}`),
        openModalBtn: vm.$el.querySelector(`[data-target="${modalSelector}"]`),
        modal: vm.$el.querySelector(modalSelector),
        modalBody: vm.$el.querySelector(`${modalSelector} .modal-body`),
        modalHeader: vm.$el.querySelector(`${modalSelector} .modal-title`),
        confirmModalBtn: vm.$el.querySelector(`${modalSelector} .btn-warning`),
      };
    };
  
    it('has a disabled button if the username was not changed', done => {
      const { input, openModalBtn } = findElements();
      input.dispatchEvent(new Event('input'));
  
      Vue.nextTick()
        .then(() => {
          expect(vm.username).toBe(username);
          expect(vm.newUsername).toBe(username);
          expect(openModalBtn).toBeDisabled();
        })
        .then(done)
        .catch(done.fail);
    });
  
    it('has an enabled button which if the username was changed', done => {
      const { input, openModalBtn } = findElements();
      input.value = newUsername;
      input.dispatchEvent(new Event('input'));
  
      Vue.nextTick()
        .then(() => {
          expect(vm.username).toBe(username);
          expect(vm.newUsername).toBe(newUsername);
          expect(openModalBtn).not.toBeDisabled();
        })
        .then(done)
        .catch(done.fail);
    });
  
    it('confirmation modal contains proper header and body', done => {
      const { modalBody, modalHeader } = findElements();
  
      vm.newUsername = newUsername;
  
      Vue.nextTick()
        .then(() => {
          expect(modalHeader.textContent).toContain('Change username?');
          expect(modalBody.textContent).toContain(
            `You are going to change the username ${username} to ${newUsername}`,
          );
        })
        .then(done)
        .catch(done.fail);
    });
  
    it('confirmation modal should escape usernames properly', done => {
      const { modalBody } = findElements();
  
      vm.username = '<i>Italic</i>';
      vm.newUsername = vm.username;
  
      Vue.nextTick()
        .then(() => {
          expect(modalBody.innerHTML).toContain('&lt;i&gt;Italic&lt;/i&gt;');
          expect(modalBody.innerHTML).not.toContain(vm.username);
        })
        .then(done)
        .catch(done.fail);
    });
  
    it('executes API call on confirmation button click', done => {
      const { confirmModalBtn } = findElements();
  
      axiosMock.onPut(actionUrl).replyOnce(() => [200, { message: 'Username changed' }]);
      jest.spyOn(axios, 'put');
  
      vm.newUsername = newUsername;
  
      Vue.nextTick()
        .then(() => {
          confirmModalBtn.click();
  
          expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } });
        })
        .then(done)
        .catch(done.fail);
    });
  
    it('sets the username after a successful update', done => {
      const { input, openModalBtn } = findElements();
  
      axiosMock.onPut(actionUrl).replyOnce(() => {
        expect(input).toBeDisabled();
        expect(openModalBtn).toBeDisabled();
  
        return [200, { message: 'Username changed' }];
      });
  
      vm.newUsername = newUsername;
  
      vm.onConfirm()
        .then(() => {
          expect(vm.username).toBe(newUsername);
          expect(vm.newUsername).toBe(newUsername);
          expect(input).not.toBeDisabled();
          expect(input.value).toBe(newUsername);
          expect(openModalBtn).toBeDisabled();
        })
        .then(done)
        .catch(done.fail);
    });
  
    it('does not set the username after a erroneous update', done => {
      const { input, openModalBtn } = findElements();
  
      axiosMock.onPut(actionUrl).replyOnce(() => {
        expect(input).toBeDisabled();
        expect(openModalBtn).toBeDisabled();
  
        return [400, { message: 'Invalid username' }];
      });
  
      const invalidUsername = 'anything.git';
      vm.newUsername = invalidUsername;
  
      vm.onConfirm()
        .then(() => done.fail('Expected onConfirm to throw!'))
        .catch(() => {
          expect(vm.username).toBe(username);
          expect(vm.newUsername).toBe(invalidUsername);
          expect(input).not.toBeDisabled();
          expect(input.value).toBe(invalidUsername);
          expect(openModalBtn).not.toBeDisabled();
        })
        .then(done)
        .catch(done.fail);
    });
  });
  