diff --git a/spec/features/work_packages/inline_edit/edit_work_packages_spec.rb b/spec/features/work_packages/inline_edit/edit_work_packages_spec.rb new file mode 100644 index 0000000000..8fdedbf5bc --- /dev/null +++ b/spec/features/work_packages/inline_edit/edit_work_packages_spec.rb @@ -0,0 +1,116 @@ +require 'spec_helper' + +describe 'Inline editing work packages', js: true do + let(:dev_role) do + FactoryGirl.create :role, + permissions: [:view_work_packages, + :add_work_packages] + end + let(:dev) do + FactoryGirl.create :user, + firstname: 'Dev', + lastname: 'Guy', + member_in_project: project, + member_through_role: dev_role + end + let(:manager_role) do + FactoryGirl.create :role, + permissions: [:view_work_packages, + :edit_work_packages] + end + let(:manager) do + FactoryGirl.create :user, + firstname: 'Manager', + lastname: 'Guy', + member_in_project: project, + member_through_role: manager_role + end + let(:type) { FactoryGirl.create :type } + let(:type2) { FactoryGirl.create :type } + let(:project) { FactoryGirl.create(:project, types: [type, type2]) } + let(:work_package) { FactoryGirl.create(:work_package, author: dev, project: project, type: type, subject: 'Foobar') } + + let(:wp_table) { Pages::WorkPackagesTable.new(project) } + let(:fields) { InlineEditField.new(wp_table, work_package) } + + + let(:priority2) { FactoryGirl.create :priority } + let(:status2) { FactoryGirl.create :status } + let(:workflow) do + FactoryGirl.create :workflow, + type_id: type2.id, + old_status: work_package.status, + new_status: status2, + role: manager_role + end + let(:version) { FactoryGirl.create :version, project: project } + let(:category) { FactoryGirl.create :category, project: project } + + before do + login_as(manager) + + manager + dev + priority2 + workflow + + wp_table.visit! + wp_table.expect_work_package_listed(work_package) + end + + it 'allows updating and seeing the results' do + subject_field = wp_table.edit_field(work_package, :subject) + subject_field.expect_text('Foobar') + + subject_field.activate! + + subject_field.set_value('New subject!') + + expect(UpdateWorkPackageService).to receive(:new).and_call_original + subject_field.save! + subject_field.expect_text('New subject!') + + work_package.reload + expect(work_package.subject).to eq('New subject!') + end + + it 'allows to edit multiple fields' do + subject_field = wp_table.edit_field(work_package, :subject) + priority_field = wp_table.edit_field(work_package, :priority) + + subject_field.activate! + priority_field.activate! + + + subject_field.set_value('Other subject') + priority_field.set_value(priority2.name) + + expect(UpdateWorkPackageService).to receive(:new).and_call_original + priority_field.save! + + subject_field.expect_text('Other subject!') + priority_field.expect_text(priority2.name) + + work_package.reload + expect(work_package.subject).to eq('Other subject!') + expect(work_package.priority.id).to eq(priority2.id) + end + + it 'provides error handling' do + subject_field = wp_table.edit_field(work_package, :subject) + subject_field.expect_text('Foobar') + + subject_field.activate! + + subject_field.set_value('') + + expect(UpdateWorkPackageService).to receive(:new).and_call_original + subject_field.save! + wait_until_requests_completed! + subject_field.expect_error + subject_field.expect_text('-') + + work_package.reload + expect(work_package.subject).to eq('Foobar') + end +end diff --git a/spec/support/pages/work_packages_table.rb b/spec/support/pages/work_packages_table.rb index 45a26f133a..480f63d87a 100644 --- a/spec/support/pages/work_packages_table.rb +++ b/spec/support/pages/work_packages_table.rb @@ -27,6 +27,7 @@ #++ require 'support/pages/page' +require 'support/work_packages/inline_edit_field' module Pages class WorkPackagesTable < Page @@ -59,6 +60,14 @@ module Pages FullWorkPackage.new(work_package) end + def row(work_package) + table_container.find("#work-package-#{work_package.id}") + end + + def edit_field(work_package, attribute) + InlineEditField.new(work_package, attribute) + end + private def path @@ -68,9 +77,5 @@ module Pages def table_container find('#content .work-package-table--container') end - - def row(work_package) - table_container.find("#work-package-#{work_package.id}") - end end end diff --git a/spec/support/work_packages/inline_edit_field.rb b/spec/support/work_packages/inline_edit_field.rb new file mode 100644 index 0000000000..458ff3bbc4 --- /dev/null +++ b/spec/support/work_packages/inline_edit_field.rb @@ -0,0 +1,85 @@ +class InlineEditField + include Capybara::DSL + include RSpec::Matchers + + attr_reader :work_package, :attribute, :element, :selector + + def initialize(work_package, attribute, field_type: nil) + @work_package = work_package + @attribute = attribute + @field_type = field_type + + @selector = "#work-package-#{work_package.id} .#{attribute}" + @element = page.find(selector) + end + + def expect_text(text) + expect(page).to have_selector(selector, text: text) + end + + ## + # Activate the field and check it opened correctly + def activate! + edit_field.click + expect_active! + end + + ## + # Set or select the given value. + # For fields of type select, will check for an option with that value. + def set_value(content) + if field_type == 'select' + input_field.find(:option, content) + else + input_field.set(content) + end + end + + def expect_error + expect(page).to have_selector("#{field_selector}.-error") + end + + def expect_active! + expect(edit_field).to have_selector(field_type) + end + + def expect_inactive! + expect(edit_field).not_to have_selector(field_type) + end + + def save! + input_field.native.send_keys(:return) + reset_field + end + + def edit_field + @edit_field ||= @element.find('.wp-edit-field') + end + + def input_field + @input_field ||= edit_field.find(field_type) + end + + private + + def field_selector + "#{selector} .wp-edit-field" + end + + ## + # Reset the input field e.g., after saving + def reset_field + @input_field = nil + end + + def field_type + @field_type ||= begin + case attribute + when :assignee, :priority, :status + :select + else + :input + end.to_s + end + end +end