#-- copyright # OpenProject is a project management system. # Copyright (C) 2012-2015 the OpenProject Foundation (OPF) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License version 3. # # OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: # Copyright (C) 2006-2013 Jean-Philippe Lang # Copyright (C) 2010-2013 the ChiliProject Team # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # See doc/COPYRIGHT.rdoc for more details. #++ require 'spec_helper' describe WorkPackagesHelper, type: :helper do let(:stub_work_package) { FactoryGirl.build_stubbed(:work_package) } let(:stub_project) { FactoryGirl.build_stubbed(:project) } let(:stub_type) { FactoryGirl.build_stubbed(:type) } let(:label_placeholder) { ''.html_safe } let(:form) do double('form', select: '', label: label_placeholder).as_null_object end let(:stub_user) { FactoryGirl.build_stubbed(:user) } def inside_form(&_block) ret = '' form_for(stub_work_package, as: 'work_package', url: work_package_path(stub_work_package)) do |f| ret = yield f end ret end describe '#work_package_breadcrumb' do it 'should provide a link to index as the first element and all ancestors as links' do index_link = double('work_package_index_link') ancestors_links = double('ancestors_links') allow(helper).to receive(:ancestors_links).and_return([ancestors_links]) allow(helper).to receive(:work_package_index_link).and_return(index_link) @expectation = [index_link, ancestors_links] expect(helper).to receive(:breadcrumb_paths).with(*@expectation) helper.work_package_breadcrumb end end describe '#ancestors_links' do it 'should return a list of links for every ancestor' do ancestors = [double('ancestor1', id: 1), double('ancestor2', id: 2)] allow(controller).to receive(:ancestors).and_return(ancestors) ancestors.each_with_index do |ancestor, index| expect(helper.ancestors_links[index]).to have_selector("a[href='#{work_package_path(ancestor.id)}']", text: "##{ancestor.id}") end end end describe '#link_to_work_package' do let(:open_status) { FactoryGirl.build_stubbed(:status, is_closed: false) } let(:closed_status) { FactoryGirl.build_stubbed(:status, is_closed: true) } before do stub_work_package.status = open_status end describe 'without parameters' do it 'should return a link to the work package with the id as the text' do link_text = Regexp.new("^##{stub_work_package.id}$") expect(helper.link_to_work_package(stub_work_package)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end it 'should return a link to the work package with type and id as the text if type is set' do stub_work_package.type = stub_type link_text = Regexp.new("^#{stub_type.name} ##{stub_work_package.id}$") expect(helper.link_to_work_package(stub_work_package)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end it 'should additionally return the subject' do text = Regexp.new("#{stub_work_package.subject}$") expect(helper.link_to_work_package(stub_work_package)).to have_text(text) end it 'should prepend an invisible closed information if the work package is closed' do stub_work_package.status = closed_status expect(helper.link_to_work_package(stub_work_package)).to have_selector('a span.hidden-for-sighted', text: 'closed') end end describe 'with the all_link option provided' do it 'should return a link to the work package with the type, id, and subject as the text' do stub_work_package.type = stub_type link_text = Regexp.new("^#{stub_type} ##{stub_work_package.id}: #{stub_work_package.subject}$") expect(helper.link_to_work_package(stub_work_package, all_link: true)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end end describe 'when truncating' do it 'should truncate the subject if the subject is longer than the specified amount' do stub_work_package.subject = '12345678' text = Regexp.new('1234...$') expect(helper.link_to_work_package(stub_work_package, truncate: 7)).to have_text(text) end it 'should not truncate the subject if the subject is shorter than the specified amount' do stub_work_package.subject = '1234567' text = Regexp.new('1234567$') expect(helper.link_to_work_package(stub_work_package, truncate: 7)).to have_text(text) end end describe 'when omitting the subject' do it 'should omit the subject' do expect(helper.link_to_work_package(stub_work_package, subject: false)).not_to have_text(stub_work_package.subject) end end describe 'when omitting the type' do it 'should omit the type' do stub_work_package.type = stub_type link_text = Regexp.new("^##{stub_work_package.id}$") expect(helper.link_to_work_package(stub_work_package, type: false)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end end describe 'with a project' do let(:text) { Regexp.new("^#{stub_project.name} -") } before do stub_work_package.project = stub_project end it 'should prepend the project if parameter set to true' do expect(helper.link_to_work_package(stub_work_package, project: true)).to have_text(text) end it 'should not have the project name if the parameter is missing/false' do expect(helper.link_to_work_package(stub_work_package)).not_to have_text(text) end end describe 'when only wanting the id' do it 'should return a link with the id as text only even if the work package has a type' do stub_work_package.type = stub_type link_text = Regexp.new("^##{stub_work_package.id}$") expect(helper.link_to_work_package(stub_work_package, id_only: true)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end it 'should not have the subject as text' do expect(helper.link_to_work_package(stub_work_package, id_only: true)).not_to have_text(stub_work_package.subject) end end describe 'when only wanting the subject' do it 'should return a link with the subject as text' do link_text = Regexp.new("^#{stub_work_package.subject}$") expect(helper.link_to_work_package(stub_work_package, subject_only: true)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end end describe 'with the status displayed' do it 'should return a link with the status name contained in the text' do stub_work_package.type = stub_type link_text = Regexp.new("^#{stub_type.name} ##{stub_work_package.id} #{stub_work_package.status}$") expect(helper.link_to_work_package(stub_work_package, status: true)).to have_selector("a[href='#{work_package_path(stub_work_package)}']", text: link_text) end end end describe '#work_package_index_link' do it 'should return a link to issue_index (work_packages index later)' do expect(helper.work_package_index_link).to have_selector("a[href='#{work_packages_path}']", text: I18n.t(:label_work_package_plural)) end end describe '#work_package_show_spent_time_attribute' do it 'should show a spent time link pointing to the time entries of the work package' do allow(stub_work_package).to receive(:spent_hours).and_return(5.0) field = helper.work_package_show_spent_time_attribute(stub_work_package).field expected_href = work_package_time_entries_path(stub_work_package) expect(field).to have_css(".-spent-time a[@href='#{ expected_href }']", text: '5.0') end it "should show a '-' if spent time is 0" do allow(stub_work_package).to receive(:spent_hours).and_return(0.0) field = helper.work_package_show_spent_time_attribute(stub_work_package).field expect(field).to have_css('.-spent-time', text: '-') end end # Testing private method here. # Only doing so because this method is an exception. # All other show... methods are public. # TODO: check wether the method can be made public. describe '#work_package_show_custom_fields' do let(:stub_custom_field) do stub_custom_field = FactoryGirl.build_stubbed(:custom_field, name: 'My Custom Field') end let(:stub_custom_value) do FactoryGirl.build_stubbed(:work_package_custom_value, customized: stub_work_package, custom_field: stub_custom_field, value: true) end it 'should show the field name unchanged' do allow(stub_work_package).to receive(:custom_field_values).and_return([stub_custom_value]) attributes = helper.send(:work_package_show_custom_fields, stub_work_package) expect(attributes.length).to eql(1) expected_css_class = ".attributes-key-value--key.-custom_field.-cf_#{stub_custom_field.id}" expect(attributes[0].field).to have_css(expected_css_class, text: stub_custom_field.name) end end describe '#work_package_form_category_attribute' do let(:stub_project) { FactoryGirl.build_stubbed(:project) } let(:stub_category) { FactoryGirl.build_stubbed(:category) } before do # set sensible defaults allow(helper).to receive(:authorize_for).and_return(false) allow(stub_project).to receive(:categories).and_return([stub_category]) end it 'should return nothing if the project has no categories assigned' do allow(stub_project).to receive(:categories).and_return([]) expect(helper.work_package_form_category_attribute(form, stub_work_package, project: stub_project)).to be_nil end it 'should have a :category symbol as the attribute' do expect(helper.work_package_form_category_attribute(form, stub_work_package, project: stub_project).attribute).to eq(:category) end it "should render a select with the project's work package categories" do select = 'category html' expect(form).to receive(:select).with(:category_id, [[stub_category.name, stub_category.id]], include_blank: true, no_label: true).and_return(select) expect(helper.work_package_form_category_attribute(form, stub_work_package, project: stub_project).field) .to be_html_eql("