Added JS spec tests for CommentsStore

Updated other tests
This commit is contained in:
Phil Hughes 2016-07-29 15:03:58 +01:00
parent 6f94f62f72
commit 9878356dbc
8 changed files with 188 additions and 17 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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')

View file

@ -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")

View file

@ -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...'

View 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);
});
});
})();

View file

@ -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 = []