todo_spec.js 4.46 KB
Newer Older
Kushal Pandya's avatar
Kushal Pandya committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
import Vue from 'vue';

import SidebarTodos from '~/sidebar/components/todo_toggle/todo.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';

const createComponent = ({
  issuableId = 1,
  issuableType = 'epic',
  isTodo,
  isActionActive,
  collapsed,
}) => {
  const Component = Vue.extend(SidebarTodos);

  return mountComponent(Component, {
    issuableId,
    issuableType,
    isTodo,
    isActionActive,
    collapsed,
  });
};

describe('SidebarTodo', () => {
  let vm;

  beforeEach(() => {
    vm = createComponent({});
  });

  afterEach(() => {
    vm.$destroy();
  });

  describe('computed', () => {
    describe('buttonClasses', () => {
      it('returns todo button classes for when `collapsed` prop is `false`', () => {
        expect(vm.buttonClasses).toBe('btn btn-default btn-todo issuable-header-btn float-right');
      });

      it('returns todo button classes for when `collapsed` prop is `true`', done => {
        vm.collapsed = true;
        Vue.nextTick()
          .then(() => {
            expect(vm.buttonClasses).toBe('btn-blank btn-todo sidebar-collapsed-icon dont-change-state');
          })
          .then(done)
          .catch(done.fail);
      });
    });

    describe('buttonLabel', () => {
      it('returns todo button text for marking todo as done when `isTodo` prop is `true`', () => {
        expect(vm.buttonLabel).toBe('Mark todo as done');
      });

      it('returns todo button text for add todo when `isTodo` prop is `false`', done => {
        vm.isTodo = false;
        Vue.nextTick()
          .then(() => {
            expect(vm.buttonLabel).toBe('Add todo');
          })
          .then(done)
          .catch(done.fail);
      });
    });

    describe('collapsedButtonIconClasses', () => {
      it('returns collapsed button icon class when `isTodo` prop is `true`', () => {
        expect(vm.collapsedButtonIconClasses).toBe('todo-undone');
      });

      it('returns empty string when `isTodo` prop is `false`', done => {
        vm.isTodo = false;
        Vue.nextTick()
          .then(() => {
            expect(vm.collapsedButtonIconClasses).toBe('');
          })
          .then(done)
          .catch(done.fail);
      });
    });

    describe('collapsedButtonIcon', () => {
      it('returns button icon name when `isTodo` prop is `true`', () => {
        expect(vm.collapsedButtonIcon).toBe('todo-done');
      });

      it('returns button icon name when `isTodo` prop is `false`', done => {
        vm.isTodo = false;
        Vue.nextTick()
          .then(() => {
            expect(vm.collapsedButtonIcon).toBe('todo-add');
          })
          .then(done)
          .catch(done.fail);
      });
    });
  });

  describe('methods', () => {
    describe('handleButtonClick', () => {
      it('emits `toggleTodo` event on component', () => {
        spyOn(vm, '$emit');
        vm.handleButtonClick();
        expect(vm.$emit).toHaveBeenCalledWith('toggleTodo');
      });
    });
  });

  describe('template', () => {
    it('renders component container element', () => {
      const dataAttributes = {
        issuableId: '1',
        issuableType: 'epic',
        originalTitle: 'Mark todo as done',
        placement: 'left',
        container: 'body',
        boundary: 'viewport',
      };
      expect(vm.$el.nodeName).toBe('BUTTON');

      const elDataAttrs = vm.$el.dataset;
      Object.keys(elDataAttrs).forEach((attr) => {
        expect(elDataAttrs[attr]).toBe(dataAttributes[attr]);
      });
    });

    it('renders button label element when `collapsed` prop is `false`', () => {
      const buttonLabelEl = vm.$el.querySelector('span.issuable-todo-inner');
      expect(buttonLabelEl).not.toBeNull();
      expect(buttonLabelEl.innerText.trim()).toBe('Mark todo as done');
    });

    it('renders button icon when `collapsed` prop is `true`', done => {
      vm.collapsed = true;
      Vue.nextTick()
        .then(() => {
          const buttonIconEl = vm.$el.querySelector('svg');
          expect(buttonIconEl).not.toBeNull();
          expect(buttonIconEl.querySelector('use').getAttribute('xlink:href')).toContain('todo-done');
        })
        .then(done)
        .catch(done.fail);
    });

    it('renders loading icon when `isActionActive` prop is true', done => {
      vm.isActionActive = true;
      Vue.nextTick()
        .then(() => {
          const loadingEl = vm.$el.querySelector('span.loading-container');
          expect(loadingEl).not.toBeNull();
        })
        .then(done)
        .catch(done.fail);
    });
  });
});