noteable_discussion_spec.js 4.16 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';
Filipa Lacerda's avatar
Filipa Lacerda committed
6

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

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

14
  preloadFixtures(discussionWithTwoUnresolvedNotes);
15

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

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

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

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

36
  it('should render discussion header', () => {
37
    expect(vm.$el.querySelector('.discussion-header')).not.toBeNull();
38
    expect(vm.$el.querySelector('.notes').children.length).toEqual(discussionMock.notes.length);
39
  });
40

41 42
  describe('actions', () => {
    it('should render reply button', () => {
43 44 45
      expect(vm.$el.querySelector('.js-vue-discussion-reply').textContent.trim()).toEqual(
        'Reply...',
      );
46 47
    });

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

51 52
      Vue.nextTick(() => {
        expect(vm.isReplying).toEqual(true);
53 54 55 56 57 58

        // There is a watcher for `isReplying` which will init autosave in the next tick
        Vue.nextTick(() => {
          expect(vm.$refs.noteForm).not.toBeNull();
          done();
        });
59 60
      });
    });
61 62 63 64 65 66

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

  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 => {
94 95 96
        const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
        discussion.notes[0].resolved = false;
        vm.$store.dispatch('setInitialNotes', [discussion, discussion]);
Felipe Artur's avatar
Felipe Artur committed
97 98 99 100 101 102 103 104 105 106 107 108 109

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

  describe('methods', () => {
    describe('jumpToNextDiscussion', () => {
110 111 112 113 114 115 116 117 118 119 120 121
      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
122

123 124 125
            setFixtures(`
              <div class="discussion" data-discussion-id="${nextDiscussionId}"></div>
            `);
126

127 128 129 130 131 132
            vm.jumpToNextDiscussion();

            expect(vm.expandDiscussion).toHaveBeenCalledWith({ discussionId: nextDiscussionId });
          })
          .then(done)
          .catch(done.fail);
Felipe Artur's avatar
Felipe Artur committed
133 134 135
      });
    });
  });
136
});