From 51c3393974c0702f56f22122006606d3e03b668d Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 4 May 2015 23:06:57 -0400 Subject: [PATCH] Task List feature and JS specs --- spec/features/task_lists_spec.rb | 151 ++++++++++++++++++ spec/javascripts/issue_spec.js.coffee | 36 +++++ spec/javascripts/merge_request_spec.js.coffee | 36 +++++ spec/javascripts/notes_spec.js.coffee | 30 ++++ 4 files changed, 253 insertions(+) create mode 100644 spec/features/task_lists_spec.rb create mode 100644 spec/javascripts/issue_spec.js.coffee create mode 100644 spec/javascripts/merge_request_spec.js.coffee create mode 100644 spec/javascripts/notes_spec.js.coffee diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb new file mode 100644 index 00000000000..651792601ed --- /dev/null +++ b/spec/features/task_lists_spec.rb @@ -0,0 +1,151 @@ +require 'spec_helper' + +feature 'Task Lists' do + include Warden::Test::Helpers + + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:user2) { create(:user) } + + let(:markdown) do + <<-MARKDOWN.strip_heredoc + This is a task list: + + - [ ] Incomplete entry 1 + - [x] Complete entry 1 + - [ ] Incomplete entry 2 + - [x] Complete entry 2 + - [ ] Incomplete entry 3 + - [ ] Incomplete entry 4 + MARKDOWN + end + + before do + Warden.test_mode! + + project.team << [user, :master] + project.team << [user2, :guest] + + login_as(user) + end + + def visit_issue(project, issue) + visit namespace_project_issue_path(project.namespace, project, issue) + end + + describe 'for Issues' do + let!(:issue) { create(:issue, description: markdown, author: user, project: project) } + + it 'renders' do + visit_issue(project, issue) + + expect(page).to have_selector('ul.task-list', count: 1) + expect(page).to have_selector('li.task-list-item', count: 6) + expect(page).to have_selector('ul input[checked]', count: 2) + end + + it 'contains the required selectors' do + visit_issue(project, issue) + + container = '.issue-details .description.js-task-list-container' + + expect(page).to have_selector(container) + expect(page).to have_selector("#{container} .wiki .task-list .task-list-item .task-list-item-checkbox") + expect(page).to have_selector("#{container} .js-task-list-field") + expect(page).to have_selector('form.js-issue-update') + expect(page).to have_selector('a.btn-close') + end + + it 'is only editable by author' do + visit_issue(project, issue) + expect(page).to have_selector('.js-task-list-container') + + logout(:user) + + login_as(user2) + visit current_path + expect(page).not_to have_selector('.js-task-list-container') + end + + it 'provides a summary on Issues#index' do + visit namespace_project_issues_path(project.namespace, project) + expect(page).to have_content("6 tasks (2 done, 4 unfinished)") + end + end + + describe 'for Notes' do + let!(:issue) { create(:issue, author: user, project: project) } + let!(:note) { create(:note, note: markdown, noteable: issue, author: user) } + + it 'renders for note body' do + visit_issue(project, issue) + + expect(page).to have_selector('.note ul.task-list', count: 1) + expect(page).to have_selector('.note li.task-list-item', count: 6) + expect(page).to have_selector('.note ul input[checked]', count: 2) + end + + it 'contains the required selectors' do + visit_issue(project, issue) + + expect(page).to have_selector('.note .js-task-list-container') + expect(page).to have_selector('.note .js-task-list-container .task-list .task-list-item .task-list-item-checkbox') + expect(page).to have_selector('.note .js-task-list-container .js-task-list-field') + end + + it 'is only editable by author' do + visit_issue(project, issue) + expect(page).to have_selector('.js-task-list-container') + + logout(:user) + + login_as(user2) + visit current_path + expect(page).not_to have_selector('.js-task-list-container') + end + end + + describe 'for Merge Requests' do + def visit_merge_request(project, merge) + visit namespace_project_merge_request_path(project.namespace, project, merge) + end + + let!(:merge) { create(:merge_request, :simple, description: markdown, author: user, source_project: project) } + + it 'renders for description' do + visit_merge_request(project, merge) + + expect(page).to have_selector('ul.task-list', count: 1) + expect(page).to have_selector('li.task-list-item', count: 6) + expect(page).to have_selector('ul input[checked]', count: 2) + end + + it 'contains the required selectors' do + visit_merge_request(project, merge) + + container = '.merge-request-details .description.js-task-list-container' + + expect(page).to have_selector(container) + expect(page).to have_selector("#{container} .wiki .task-list .task-list-item .task-list-item-checkbox") + expect(page).to have_selector("#{container} .js-task-list-field") + expect(page).to have_selector('form.js-merge-request-update') + expect(page).to have_selector('a.btn-close') + end + + it 'is only editable by author' do + visit_merge_request(project, merge) + expect(page).to have_selector('.js-task-list-container') + + logout(:user) + + login_as(user2) + visit current_path + expect(page).not_to have_selector('.js-task-list-container') + end + + it 'provides a summary on MergeRequests#index' do + visit namespace_project_merge_requests_path(project.namespace, project) + expect(page).to have_content("6 tasks (2 done, 4 unfinished)") + end + end +end diff --git a/spec/javascripts/issue_spec.js.coffee b/spec/javascripts/issue_spec.js.coffee new file mode 100644 index 00000000000..13b25862f57 --- /dev/null +++ b/spec/javascripts/issue_spec.js.coffee @@ -0,0 +1,36 @@ +#= require jquery +#= require jasmine-fixture +#= require issue + +describe 'Issue', -> + describe 'task lists', -> + selectors = { + container: '.issue-details .description.js-task-list-container' + item: '.wiki ul.task-list li.task-list-item input.task-list-item-checkbox[type=checkbox] {Task List Item}' + textarea: '.wiki textarea.js-task-list-field{- [ ] Task List Item}' + form: 'form.js-issue-update[action="/foo"]' + close: 'a.btn-close' + } + + beforeEach -> + $container = affix(selectors.container) + + # # These two elements are siblings inside the container + $container.find('.js-task-list-container').append(affix(selectors.item)) + $container.find('.js-task-list-container').append(affix(selectors.textarea)) + + # Task lists don't get initialized unless this button exists. Not ideal. + $container.append(affix(selectors.close)) + + # This form is used to get the `update` URL. Not ideal. + $container.append(affix(selectors.form)) + + @issue = new Issue() + + it 'submits an ajax request on tasklist:changed', -> + spyOn($, 'ajax').and.callFake (req) -> + expect(req.type).toBe('PATCH') + expect(req.url).toBe('/foo') + expect(req.data.issue.description).not.toBe(null) + + $('.js-task-list-field').trigger('tasklist:changed') diff --git a/spec/javascripts/merge_request_spec.js.coffee b/spec/javascripts/merge_request_spec.js.coffee new file mode 100644 index 00000000000..3ebc4a4eed5 --- /dev/null +++ b/spec/javascripts/merge_request_spec.js.coffee @@ -0,0 +1,36 @@ +#= require jquery +#= require jasmine-fixture +#= require merge_request + +describe 'MergeRequest', -> + describe 'task lists', -> + selectors = { + container: '.merge-request-details .description.js-task-list-container' + item: '.wiki ul.task-list li.task-list-item input.task-list-item-checkbox[type=checkbox] {Task List Item}' + textarea: '.wiki textarea.js-task-list-field{- [ ] Task List Item}' + form: 'form.js-merge-request-update[action="/foo"]' + close: 'a.btn-close' + } + + beforeEach -> + $container = affix(selectors.container) + + # # These two elements are siblings inside the container + $container.find('.js-task-list-container').append(affix(selectors.item)) + $container.find('.js-task-list-container').append(affix(selectors.textarea)) + + # Task lists don't get initialized unless this button exists. Not ideal. + $container.append(affix(selectors.close)) + + # This form is used to get the `update` URL. Not ideal. + $container.append(affix(selectors.form)) + + @merge = new MergeRequest({}) + + it 'submits an ajax request on tasklist:changed', -> + spyOn($, 'ajax').and.callFake (req) -> + expect(req.type).toBe('PATCH') + expect(req.url).toBe('/foo') + expect(req.data.merge_request.description).not.toBe(null) + + $('.js-task-list-field').trigger('tasklist:changed') diff --git a/spec/javascripts/notes_spec.js.coffee b/spec/javascripts/notes_spec.js.coffee new file mode 100644 index 00000000000..de2e8e7f6c8 --- /dev/null +++ b/spec/javascripts/notes_spec.js.coffee @@ -0,0 +1,30 @@ +#= require jquery +#= require jasmine-fixture +#= require notes + +window.gon = {} +window.disableButtonIfEmptyField = -> null + +describe 'Notes', -> + describe 'task lists', -> + selectors = { + container: 'li.note .js-task-list-container' + item: '.note-text ul.task-list li.task-list-item input.task-list-item-checkbox[type=checkbox] {Task List Item}' + textarea: '.note-edit-form form textarea.js-task-list-field{- [ ] Task List Item}' + } + + beforeEach -> + $container = affix(selectors.container) + + # These two elements are siblings inside the container + $container.find('.js-task-list-container').append(affix(selectors.item)) + $container.find('.js-task-list-container').append(affix(selectors.textarea)) + + @notes = new Notes() + + it 'submits the form on tasklist:changed', -> + submitted = false + $('form').on 'submit', (e) -> submitted = true; e.preventDefault() + + $('.js-task-list-field').trigger('tasklist:changed') + expect(submitted).toBe(true)