Added JS spec tests for CommentsStore
Updated other tests
This commit is contained in:
parent
6f94f62f72
commit
9878356dbc
8 changed files with 188 additions and 17 deletions
|
@ -1,7 +1,8 @@
|
|||
((w) => {
|
||||
w.CommentAndResolveBtn = Vue.extend({
|
||||
props: {
|
||||
discussionId: String
|
||||
discussionId: String,
|
||||
textareaVal: String
|
||||
},
|
||||
computed: {
|
||||
isDiscussionResolved: function () {
|
||||
|
@ -10,12 +11,33 @@
|
|||
return discussion.isResolved();
|
||||
},
|
||||
buttonText: function () {
|
||||
const textVal = this.textareaVal;
|
||||
|
||||
if (this.isDiscussionResolved) {
|
||||
return "Comment & unresolve discussion";
|
||||
if (textVal === '') {
|
||||
return "Unresolve discussion";
|
||||
} else {
|
||||
return "Comment & unresolve discussion";
|
||||
}
|
||||
} else {
|
||||
return "Comment & resolve discussion";
|
||||
if (textVal === '') {
|
||||
return "Resolve discussion";
|
||||
} else {
|
||||
return "Comment & resolve discussion";
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ready: function () {
|
||||
const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`);
|
||||
this.textareaVal = $textarea.val();
|
||||
|
||||
$textarea.on('input', () => {
|
||||
this.textareaVal = $textarea.val();
|
||||
});
|
||||
},
|
||||
destroyed: function () {
|
||||
$(`#new-discussion-note-form-${this.discussionId} .note-textarea`).off('input');
|
||||
}
|
||||
});
|
||||
})(window);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
this.form.find('.div-dropzone').remove();
|
||||
this.form.addClass('gfm-form');
|
||||
disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
|
||||
disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-resolve-button'));
|
||||
GitLab.GfmAutoComplete.setup();
|
||||
new DropzoneInput(this.form);
|
||||
autosize(this.textarea);
|
||||
|
|
|
@ -350,7 +350,7 @@
|
|||
form.find("#note_line_code").remove();
|
||||
form.find("#note_position").remove();
|
||||
form.find("#note_type").remove();
|
||||
form.find('.js-comment-resolve-button').closest('resolve-comment-btn').remove();
|
||||
form.find('.js-comment-resolve-button').closest('comment-and-resolve-btn').remove();
|
||||
return this.parentTimeline = form.parents('.timeline');
|
||||
};
|
||||
|
||||
|
@ -589,17 +589,17 @@
|
|||
form.find("#note_noteable_id").val(dataHolder.data("noteableId"));
|
||||
form.find('.js-note-discard').show().removeClass('js-note-discard').addClass('js-close-discussion-note-form').text(form.find('.js-close-discussion-note-form').data('cancel-text'));
|
||||
form.find('.js-note-target-close').remove();
|
||||
this.setupNoteForm(form);
|
||||
|
||||
if (canResolve === 'false') {
|
||||
form.find('resolve-comment-btn').remove();
|
||||
form.find('comment-and-resolve-btn').remove();
|
||||
} else if (DiffNotesApp) {
|
||||
var $commentBtn = form.find('resolve-comment-btn');
|
||||
var $commentBtn = form.find('comment-and-resolve-btn');
|
||||
$commentBtn
|
||||
.attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'");
|
||||
DiffNotesApp.$compile($commentBtn.get(0));
|
||||
}
|
||||
|
||||
this.setupNoteForm(form);
|
||||
form.find(".js-note-text").focus();
|
||||
form
|
||||
.find('.js-comment-resolve-button')
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
- discussion = local_assigns.fetch(:discussion, nil)
|
||||
%jump-to-discussion{ "inline-template" => true, ":discussion-id" => "'#{discussion.try(:id)}'" }
|
||||
.btn-group{ role: "group",
|
||||
"v-show" => "!allResolved" }
|
||||
%button.btn.btn-default.discussion-next-btn.has-tooltip{ "@click" => "jumpToNextUnresolvedDiscussion",
|
||||
title: "Jump to next unresolved discussion",
|
||||
"aria-label" => "Jump to next unresolved discussion",
|
||||
data: { container: "body" } }
|
||||
= custom_icon("next_discussion")
|
||||
- if current_user
|
||||
%jump-to-discussion{ "inline-template" => true, ":discussion-id" => "'#{discussion.try(:id)}'" }
|
||||
.btn-group{ role: "group",
|
||||
"v-show" => "!allResolved" }
|
||||
%button.btn.btn-default.discussion-next-btn.has-tooltip{ "@click" => "jumpToNextUnresolvedDiscussion",
|
||||
title: "Jump to next unresolved discussion",
|
||||
"aria-label" => "Jump to next unresolved discussion",
|
||||
data: { container: "body" } }
|
||||
= custom_icon("next_discussion")
|
||||
|
|
|
@ -86,6 +86,34 @@ feature 'Diff notes resolve', feature: true, js: true do
|
|||
expect(page).to have_selector('.discussion-body', visible: false)
|
||||
end
|
||||
|
||||
it 'allows user to resolve from reply form without a comment' do
|
||||
page.within '.diff-content' do
|
||||
click_button 'Reply...'
|
||||
|
||||
click_button 'Resolve discussion'
|
||||
end
|
||||
|
||||
page.within '.line-resolve-all-container' do
|
||||
expect(page).to have_content('1/1 discussion resolved')
|
||||
expect(page).to have_selector('.line-resolve-btn.is-active')
|
||||
end
|
||||
end
|
||||
|
||||
it 'allows user to unresolve from reply form without a comment' do
|
||||
page.within '.diff-content' do
|
||||
click_button 'Resolve discussion'
|
||||
|
||||
click_button 'Reply...'
|
||||
|
||||
click_button 'Resolve discussion'
|
||||
end
|
||||
|
||||
page.within '.line-resolve-all-container' do
|
||||
expect(page).to have_content('0/1 discussion resolved')
|
||||
expect(page).to have_selector('.line-resolve-btn.is-active')
|
||||
end
|
||||
end
|
||||
|
||||
it 'allows user to comment & resolve discussion' do
|
||||
page.within '.diff-content' do
|
||||
click_button 'Reply...'
|
||||
|
|
121
spec/javascripts/diff_comments_store_spec.js.es6
Normal file
121
spec/javascripts/diff_comments_store_spec.js.es6
Normal file
|
@ -0,0 +1,121 @@
|
|||
//= require vue
|
||||
//= require diff_notes/models/discussion
|
||||
//= require diff_notes/models/note
|
||||
//= require diff_notes/stores/comments
|
||||
(() => {
|
||||
function createDiscussion(noteId = 1, resolved = true) {
|
||||
CommentsStore.create('a', noteId, resolved, 'test');
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
CommentsStore.state = {};
|
||||
});
|
||||
|
||||
describe('New discussion', () => {
|
||||
it('creates new discussion', () => {
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
createDiscussion();
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(1);
|
||||
});
|
||||
|
||||
it('creates new note in discussion', () => {
|
||||
createDiscussion();
|
||||
createDiscussion(2);
|
||||
|
||||
const discussion = CommentsStore.state['a'];
|
||||
expect(Object.keys(discussion.notes).length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get note', () => {
|
||||
beforeEach(() => {
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
createDiscussion();
|
||||
});
|
||||
|
||||
it('gets note by ID', () => {
|
||||
const note = CommentsStore.get('a', 1);
|
||||
expect(note).toBeDefined();
|
||||
expect(note.id).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete discussion', () => {
|
||||
beforeEach(() => {
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
createDiscussion();
|
||||
});
|
||||
|
||||
it('deletes discussion by ID', () => {
|
||||
CommentsStore.delete('a', 1);
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
});
|
||||
|
||||
it('deletes discussion when no more notes', () => {
|
||||
createDiscussion();
|
||||
createDiscussion(2);
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(1);
|
||||
expect(Object.keys(CommentsStore.state['a'].notes).length).toBe(2);
|
||||
|
||||
CommentsStore.delete('a', 1);
|
||||
CommentsStore.delete('a', 2);
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update note', () => {
|
||||
beforeEach(() => {
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
createDiscussion();
|
||||
});
|
||||
|
||||
it('updates note to be unresolved', () => {
|
||||
CommentsStore.update('a', 1, false, 'test');
|
||||
|
||||
const note = CommentsStore.get('a', 1);
|
||||
expect(note.resolved).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Discussion resolved', () => {
|
||||
beforeEach(() => {
|
||||
expect(Object.keys(CommentsStore.state).length).toBe(0);
|
||||
createDiscussion();
|
||||
});
|
||||
|
||||
it('is resolved with single note', () => {
|
||||
const discussion = CommentsStore.state['a'];
|
||||
expect(discussion.isResolved()).toBe(true);
|
||||
});
|
||||
|
||||
it('is unresolved with 2 notes', () => {
|
||||
const discussion = CommentsStore.state['a'];
|
||||
createDiscussion(2, false);
|
||||
|
||||
expect(discussion.isResolved()).toBe(false);
|
||||
});
|
||||
|
||||
it('is resolved with 2 notes', () => {
|
||||
const discussion = CommentsStore.state['a'];
|
||||
createDiscussion(2);
|
||||
|
||||
expect(discussion.isResolved()).toBe(true);
|
||||
});
|
||||
|
||||
it('resolve all notes', () => {
|
||||
const discussion = CommentsStore.state['a'];
|
||||
createDiscussion(2, false);
|
||||
|
||||
discussion.resolveAllNotes();
|
||||
expect(discussion.isResolved()).toBe(true);
|
||||
});
|
||||
|
||||
it('unresolve all notes', () => {
|
||||
const discussion = CommentsStore.state['a'];
|
||||
createDiscussion(2);
|
||||
|
||||
discussion.unResolveAllNotes();
|
||||
expect(discussion.isResolved()).toBe(false);
|
||||
});
|
||||
});
|
||||
})();
|
|
@ -38,7 +38,7 @@ Teaspoon.configure do |config|
|
|||
|
||||
# Specify a file matcher as a regular expression and all matching files will be loaded when the suite is run. These
|
||||
# files need to be within an asset path. You can add asset paths using the `config.asset_paths`.
|
||||
suite.matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.coffee,coffee}"
|
||||
suite.matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.es6,es6}"
|
||||
|
||||
# Load additional JS files, but requiring them in your spec helper is the preferred way to do this.
|
||||
# suite.javascripts = []
|
||||
|
|
Loading…
Reference in a new issue