Commit 9878356d authored by Phil Hughes's avatar Phil Hughes

Added JS spec tests for CommentsStore

Updated other tests
parent 6f94f62f
((w) => { ((w) => {
w.CommentAndResolveBtn = Vue.extend({ w.CommentAndResolveBtn = Vue.extend({
props: { props: {
discussionId: String discussionId: String,
textareaVal: String
}, },
computed: { computed: {
isDiscussionResolved: function () { isDiscussionResolved: function () {
...@@ -10,12 +11,33 @@ ...@@ -10,12 +11,33 @@
return discussion.isResolved(); return discussion.isResolved();
}, },
buttonText: function () { buttonText: function () {
const textVal = this.textareaVal;
if (this.isDiscussionResolved) { if (this.isDiscussionResolved) {
if (textVal === '') {
return "Unresolve discussion";
} else {
return "Comment & unresolve discussion"; return "Comment & unresolve discussion";
}
} else {
if (textVal === '') {
return "Resolve discussion";
} else { } else {
return "Comment & resolve discussion"; 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); })(window);
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
this.form.find('.div-dropzone').remove(); this.form.find('.div-dropzone').remove();
this.form.addClass('gfm-form'); 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-button'));
disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-resolve-button'));
GitLab.GfmAutoComplete.setup(); GitLab.GfmAutoComplete.setup();
new DropzoneInput(this.form); new DropzoneInput(this.form);
autosize(this.textarea); autosize(this.textarea);
......
...@@ -350,7 +350,7 @@ ...@@ -350,7 +350,7 @@
form.find("#note_line_code").remove(); form.find("#note_line_code").remove();
form.find("#note_position").remove(); form.find("#note_position").remove();
form.find("#note_type").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'); return this.parentTimeline = form.parents('.timeline');
}; };
...@@ -589,17 +589,17 @@ ...@@ -589,17 +589,17 @@
form.find("#note_noteable_id").val(dataHolder.data("noteableId")); 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-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(); form.find('.js-note-target-close').remove();
this.setupNoteForm(form);
if (canResolve === 'false') { if (canResolve === 'false') {
form.find('resolve-comment-btn').remove(); form.find('comment-and-resolve-btn').remove();
} else if (DiffNotesApp) { } else if (DiffNotesApp) {
var $commentBtn = form.find('resolve-comment-btn'); var $commentBtn = form.find('comment-and-resolve-btn');
$commentBtn $commentBtn
.attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'"); .attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'");
DiffNotesApp.$compile($commentBtn.get(0)); DiffNotesApp.$compile($commentBtn.get(0));
} }
this.setupNoteForm(form);
form.find(".js-note-text").focus(); form.find(".js-note-text").focus();
form form
.find('.js-comment-resolve-button') .find('.js-comment-resolve-button')
......
- discussion = local_assigns.fetch(:discussion, nil) - discussion = local_assigns.fetch(:discussion, nil)
%jump-to-discussion{ "inline-template" => true, ":discussion-id" => "'#{discussion.try(:id)}'" } - if current_user
%jump-to-discussion{ "inline-template" => true, ":discussion-id" => "'#{discussion.try(:id)}'" }
.btn-group{ role: "group", .btn-group{ role: "group",
"v-show" => "!allResolved" } "v-show" => "!allResolved" }
%button.btn.btn-default.discussion-next-btn.has-tooltip{ "@click" => "jumpToNextUnresolvedDiscussion", %button.btn.btn-default.discussion-next-btn.has-tooltip{ "@click" => "jumpToNextUnresolvedDiscussion",
......
...@@ -86,6 +86,34 @@ feature 'Diff notes resolve', feature: true, js: true do ...@@ -86,6 +86,34 @@ feature 'Diff notes resolve', feature: true, js: true do
expect(page).to have_selector('.discussion-body', visible: false) expect(page).to have_selector('.discussion-body', visible: false)
end 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 it 'allows user to comment & resolve discussion' do
page.within '.diff-content' do page.within '.diff-content' do
click_button 'Reply...' click_button 'Reply...'
......
//= 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| ...@@ -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 # 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`. # 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. # Load additional JS files, but requiring them in your spec helper is the preferred way to do this.
# suite.javascripts = [] # suite.javascripts = []
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment