noteable_discussion_spec.js 5.03 KB
Newer Older
1
import Vue from 'vue';
Felipe Artur's avatar
Felipe Artur committed
2 3 4
import createStore from '~/notes/stores';
import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
import '~/behaviors/markdown/render_gfm';
Simon Knox's avatar
Simon Knox committed
5
import { noteableDataMock, discussionMock, notesDataMock } from '../mock_data';
6
import mockDiffFile from '../../diffs/mock_data/diff_file';
Filipa Lacerda's avatar
Filipa Lacerda committed
7

8 9
const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';

Felipe Artur's avatar
Felipe Artur committed
10
describe('noteable_discussion component', () => {
11
  const Component = Vue.extend(noteableDiscussion);
Felipe Artur's avatar
Felipe Artur committed
12
  let store;
13
  let vm;
14

15
  preloadFixtures(discussionWithTwoUnresolvedNotes);
16

17
  beforeEach(() => {
18
    window.mrTabs = {};
Felipe Artur's avatar
Felipe Artur committed
19
    store = createStore();
Simon Knox's avatar
Simon Knox committed
20
    store.dispatch('setNoteableData', noteableDataMock);
21
    store.dispatch('setNotesData', notesDataMock);
22

23 24
    vm = new Component({
      store,
25
      propsData: { discussion: discussionMock },
26
    }).$mount();
27 28
  });

29 30 31
  afterEach(() => {
    vm.$destroy();
  });
32

33
  it('should render user avatar', () => {
34
    expect(vm.$el.querySelector('.user-avatar-link')).not.toBeNull();
35
  });
36

37 38 39 40
  it('should not render discussion header for non diff discussions', () => {
    expect(vm.$el.querySelector('.discussion-header')).toBeNull();
  });

41
  it('should render discussion header', () => {
42 43 44 45 46 47 48 49 50
    const discussion = { ...discussionMock };
    discussion.diff_file = mockDiffFile;
    discussion.diff_discussion = true;
    const diffDiscussionVm = new Component({
      store,
      propsData: { discussion },
    }).$mount();

    expect(diffDiscussionVm.$el.querySelector('.discussion-header')).not.toBeNull();
51
  });
52

53 54
  describe('actions', () => {
    it('should render reply button', () => {
55 56 57
      expect(vm.$el.querySelector('.js-vue-discussion-reply').textContent.trim()).toEqual(
        'Reply...',
      );
58 59
    });

60
    it('should toggle reply form', done => {
61
      vm.$el.querySelector('.js-vue-discussion-reply').click();
62

63 64
      Vue.nextTick(() => {
        expect(vm.isReplying).toEqual(true);
65 66 67 68 69 70

        // There is a watcher for `isReplying` which will init autosave in the next tick
        Vue.nextTick(() => {
          expect(vm.$refs.noteForm).not.toBeNull();
          done();
        });
71 72
      });
    });
73 74 75 76 77 78

    it('does not render jump to discussion button', () => {
      expect(
        vm.$el.querySelector('*[data-original-title="Jump to next unresolved discussion"]'),
      ).toBeNull();
    });
79
  });
Felipe Artur's avatar
Felipe Artur committed
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

  describe('computed', () => {
    describe('hasMultipleUnresolvedDiscussions', () => {
      it('is false if there are no unresolved discussions', done => {
        spyOnProperty(vm, 'unresolvedDiscussions').and.returnValue([]);

        Vue.nextTick()
          .then(() => {
            expect(vm.hasMultipleUnresolvedDiscussions).toBe(false);
          })
          .then(done)
          .catch(done.fail);
      });

      it('is false if there is one unresolved discussion', done => {
        spyOnProperty(vm, 'unresolvedDiscussions').and.returnValue([discussionMock]);

        Vue.nextTick()
          .then(() => {
            expect(vm.hasMultipleUnresolvedDiscussions).toBe(false);
          })
          .then(done)
          .catch(done.fail);
      });

      it('is true if there are two unresolved discussions', done => {
106 107 108
        const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
        discussion.notes[0].resolved = false;
        vm.$store.dispatch('setInitialNotes', [discussion, discussion]);
Felipe Artur's avatar
Felipe Artur committed
109 110 111 112 113 114 115 116 117 118 119 120 121

        Vue.nextTick()
          .then(() => {
            expect(vm.hasMultipleUnresolvedDiscussions).toBe(true);
          })
          .then(done)
          .catch(done.fail);
      });
    });
  });

  describe('methods', () => {
    describe('jumpToNextDiscussion', () => {
122 123 124 125 126 127 128 129 130 131 132 133
      it('expands next unresolved discussion', done => {
        const discussion2 = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
        discussion2.resolved = false;
        discussion2.id = 'next'; // prepare this for being identified as next one (to be jumped to)
        vm.$store.dispatch('setInitialNotes', [discussionMock, discussion2]);
        window.mrTabs.currentAction = 'show';

        Vue.nextTick()
          .then(() => {
            spyOn(vm, 'expandDiscussion').and.stub();

            const nextDiscussionId = discussion2.id;
Felipe Artur's avatar
Felipe Artur committed
134

135 136 137
            setFixtures(`
              <div class="discussion" data-discussion-id="${nextDiscussionId}"></div>
            `);
138

139 140 141 142 143 144
            vm.jumpToNextDiscussion();

            expect(vm.expandDiscussion).toHaveBeenCalledWith({ discussionId: nextDiscussionId });
          })
          .then(done)
          .catch(done.fail);
Felipe Artur's avatar
Felipe Artur committed
145 146 147
      });
    });
  });
148 149 150 151 152

  describe('componentData', () => {
    it('should return first note object for placeholder note', () => {
      const data = {
        isPlaceholderNote: true,
Mike Greiling's avatar
Mike Greiling committed
153
        notes: [{ body: 'hello world!' }],
154 155 156
      };

      const note = vm.componentData(data);
157

158 159 160 161 162
      expect(note).toEqual(data.notes[0]);
    });

    it('should return given note for nonplaceholder notes', () => {
      const data = {
Mike Greiling's avatar
Mike Greiling committed
163
        notes: [{ id: 12 }],
164 165 166
      };

      const note = vm.componentData(data);
167

168 169 170
      expect(note).toEqual(data);
    });
  });
171
});