188 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
import { mount, createLocalVue } from '@vue/test-utils';
 | 
						|
import createStore from '~/notes/stores';
 | 
						|
import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
 | 
						|
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
 | 
						|
import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue';
 | 
						|
import NoteForm from '~/notes/components/note_form.vue';
 | 
						|
import '~/behaviors/markdown/render_gfm';
 | 
						|
import {
 | 
						|
  noteableDataMock,
 | 
						|
  discussionMock,
 | 
						|
  notesDataMock,
 | 
						|
  loggedOutnoteableData,
 | 
						|
  userDataMock,
 | 
						|
} from '../mock_data';
 | 
						|
import mockDiffFile from 'jest/diffs/mock_data/diff_file';
 | 
						|
import { trimText } from 'helpers/text_helper';
 | 
						|
 | 
						|
const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';
 | 
						|
 | 
						|
const localVue = createLocalVue();
 | 
						|
 | 
						|
describe('noteable_discussion component', () => {
 | 
						|
  let store;
 | 
						|
  let wrapper;
 | 
						|
  let originalGon;
 | 
						|
 | 
						|
  preloadFixtures(discussionWithTwoUnresolvedNotes);
 | 
						|
 | 
						|
  beforeEach(() => {
 | 
						|
    window.mrTabs = {};
 | 
						|
    store = createStore();
 | 
						|
    store.dispatch('setNoteableData', noteableDataMock);
 | 
						|
    store.dispatch('setNotesData', notesDataMock);
 | 
						|
 | 
						|
    wrapper = mount(localVue.extend(noteableDiscussion), {
 | 
						|
      store,
 | 
						|
      propsData: { discussion: discussionMock },
 | 
						|
      localVue,
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  afterEach(() => {
 | 
						|
    wrapper.destroy();
 | 
						|
  });
 | 
						|
 | 
						|
  it('should not render thread header for non diff threads', () => {
 | 
						|
    expect(wrapper.find('.discussion-header').exists()).toBe(false);
 | 
						|
  });
 | 
						|
 | 
						|
  it('should render thread header', () => {
 | 
						|
    const discussion = { ...discussionMock };
 | 
						|
    discussion.diff_file = mockDiffFile;
 | 
						|
    discussion.diff_discussion = true;
 | 
						|
    discussion.expanded = false;
 | 
						|
 | 
						|
    wrapper.setProps({ discussion });
 | 
						|
 | 
						|
    return wrapper.vm.$nextTick().then(() => {
 | 
						|
      expect(wrapper.find('.discussion-header').exists()).toBe(true);
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('actions', () => {
 | 
						|
    it('should toggle reply form', () => {
 | 
						|
      const replyPlaceholder = wrapper.find(ReplyPlaceholder);
 | 
						|
 | 
						|
      return wrapper.vm
 | 
						|
        .$nextTick()
 | 
						|
        .then(() => {
 | 
						|
          expect(wrapper.vm.isReplying).toEqual(false);
 | 
						|
 | 
						|
          replyPlaceholder.vm.$emit('onClick');
 | 
						|
        })
 | 
						|
        .then(() => wrapper.vm.$nextTick())
 | 
						|
        .then(() => {
 | 
						|
          expect(wrapper.vm.isReplying).toEqual(true);
 | 
						|
 | 
						|
          const noteForm = wrapper.find(NoteForm);
 | 
						|
 | 
						|
          expect(noteForm.exists()).toBe(true);
 | 
						|
 | 
						|
          const noteFormProps = noteForm.props();
 | 
						|
 | 
						|
          expect(noteFormProps.discussion).toBe(discussionMock);
 | 
						|
          expect(noteFormProps.isEditing).toBe(false);
 | 
						|
          expect(noteFormProps.line).toBe(null);
 | 
						|
          expect(noteFormProps.saveButtonTitle).toBe('Comment');
 | 
						|
          expect(noteFormProps.autosaveKey).toBe(`Note/Issue/${discussionMock.id}/Reply`);
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    it('does not render jump to thread button', () => {
 | 
						|
      expect(wrapper.find('*[data-original-title="Jump to next unresolved thread"]').exists()).toBe(
 | 
						|
        false,
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('for resolved thread', () => {
 | 
						|
    beforeEach(() => {
 | 
						|
      const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
 | 
						|
      wrapper.setProps({ discussion });
 | 
						|
    });
 | 
						|
 | 
						|
    it('does not display a button to resolve with issue', () => {
 | 
						|
      const button = wrapper.find(ResolveWithIssueButton);
 | 
						|
 | 
						|
      expect(button.exists()).toBe(false);
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('for unresolved thread', () => {
 | 
						|
    beforeEach(() => {
 | 
						|
      const discussion = {
 | 
						|
        ...getJSONFixture(discussionWithTwoUnresolvedNotes)[0],
 | 
						|
        expanded: true,
 | 
						|
      };
 | 
						|
      discussion.notes = discussion.notes.map(note => ({
 | 
						|
        ...note,
 | 
						|
        resolved: false,
 | 
						|
        current_user: {
 | 
						|
          ...note.current_user,
 | 
						|
          can_resolve: true,
 | 
						|
        },
 | 
						|
      }));
 | 
						|
 | 
						|
      wrapper.setProps({ discussion });
 | 
						|
 | 
						|
      return wrapper.vm.$nextTick();
 | 
						|
    });
 | 
						|
 | 
						|
    it('displays a button to resolve with issue', () => {
 | 
						|
      const button = wrapper.find(ResolveWithIssueButton);
 | 
						|
 | 
						|
      expect(button.exists()).toBe(true);
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('signout widget', () => {
 | 
						|
    beforeEach(() => {
 | 
						|
      originalGon = { ...window.gon };
 | 
						|
      window.gon = window.gon || {};
 | 
						|
    });
 | 
						|
 | 
						|
    afterEach(() => {
 | 
						|
      wrapper.destroy();
 | 
						|
      window.gon = originalGon;
 | 
						|
    });
 | 
						|
 | 
						|
    describe('user is logged in', () => {
 | 
						|
      beforeEach(() => {
 | 
						|
        window.gon.current_user_id = userDataMock.id;
 | 
						|
        store.dispatch('setUserData', userDataMock);
 | 
						|
 | 
						|
        wrapper = mount(localVue.extend(noteableDiscussion), {
 | 
						|
          store,
 | 
						|
          propsData: { discussion: discussionMock },
 | 
						|
          localVue,
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      it('should not render signed out widget', () => {
 | 
						|
        expect(Boolean(wrapper.vm.isLoggedIn)).toBe(true);
 | 
						|
        expect(trimText(wrapper.text())).not.toContain('Please register or sign in to reply');
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    describe('user is not logged in', () => {
 | 
						|
      beforeEach(() => {
 | 
						|
        window.gon.current_user_id = null;
 | 
						|
        store.dispatch('setNoteableData', loggedOutnoteableData);
 | 
						|
        store.dispatch('setNotesData', notesDataMock);
 | 
						|
 | 
						|
        wrapper = mount(localVue.extend(noteableDiscussion), {
 | 
						|
          store,
 | 
						|
          propsData: { discussion: discussionMock },
 | 
						|
          localVue,
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      it('should render signed out widget', () => {
 | 
						|
        expect(Boolean(wrapper.vm.isLoggedIn)).toBe(false);
 | 
						|
        expect(trimText(wrapper.text())).toContain('Please register or sign in to reply');
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
});
 |