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(() => {
Felipe Artur's avatar
Felipe Artur committed
17
    store = createStore();
Simon Knox's avatar
Simon Knox committed
18
    store.dispatch('setNoteableData', noteableDataMock);
19
    store.dispatch('setNotesData', notesDataMock);
20

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

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

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

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

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

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

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

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

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

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

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

  describe('methods', () => {
    describe('jumpToNextDiscussion', () => {
      it('expands next unresolved discussion', () => {
        spyOn(vm, 'expandDiscussion').and.stub();
        const discussions = [
          discussionMock,
          {
            ...discussionMock,
            id: discussionMock.id + 1,
116
            notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }],
Felipe Artur's avatar
Felipe Artur committed
117 118 119 120
          },
          {
            ...discussionMock,
            id: discussionMock.id + 2,
121
            notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: false }],
Felipe Artur's avatar
Felipe Artur committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
          },
        ];
        const nextDiscussionId = discussionMock.id + 2;
        store.replaceState({
          ...store.state,
          discussions,
        });
        setFixtures(`
          <div data-discussion-id="${nextDiscussionId}"></div>
        `);

        vm.jumpToNextDiscussion();

        expect(vm.expandDiscussion).toHaveBeenCalledWith({ discussionId: nextDiscussionId });
      });
    });
  });
139
});