Merge branch 'dev' into feature/rails4

Signed-off-by: Alex Coles <alex@alexbcoles.com>
pull/2935/head
Alex Coles 9 years ago
commit 531b328ac3
  1. 6
      app/assets/javascripts/application.js.erb
  2. 2
      app/assets/stylesheets/content/_in_place_editing.lsg
  3. 62
      app/controllers/work_packages/auto_completes_controller.rb
  4. 2
      app/helpers/work_packages_helper.rb
  5. 3
      app/views/journals/_notes_form.html.erb
  6. 2
      app/views/messages/_form.html.erb
  7. 1
      app/views/news/_form.html.erb
  8. 3
      app/views/news/show.html.erb
  9. 1
      app/views/project_associations/_form.html.erb
  10. 7
      app/views/projects/form/attributes/_description.html.erb
  11. 8
      app/views/projects/form/attributes/_summary.html.erb
  12. 1
      app/views/reportings/edit.html.erb
  13. 1
      app/views/wiki/edit.html.erb
  14. 1
      app/views/wiki/new.html.erb
  15. 3
      app/views/work_packages/_edit.html.erb
  16. 3
      app/views/work_packages/_form.html.erb
  17. 3
      app/views/work_packages/bulk/edit.html.erb
  18. 3
      app/views/work_packages/moves/new.html.erb
  19. 33
      db/migrate/20150623151337_hide_mail_by_default.rb
  20. 1
      doc/apiv2-documentation.md
  21. 4
      frontend/app/helpers/auto-complete-helper.js
  22. 2
      frontend/app/helpers/index.js
  23. 7
      frontend/app/helpers/path-helper.js
  24. 3
      frontend/app/templates/components/activity_comment.html
  25. 3
      frontend/app/templates/components/inplace_editor/editable/textarea.html
  26. 3
      frontend/app/templates/work_packages/inplace_editor/custom/editable/wiki_textarea.html
  27. 3
      frontend/app/templates/work_packages/tabs/_user_activity.html
  28. 3
      frontend/app/ui_components/activity-comment-directive.js
  29. 3
      frontend/app/work_packages/directives/inplace_editor/custom/editable/inplace-editor-wiki-textarea-directive.js
  30. 2
      frontend/app/work_packages/tabs/add-work-package-relation-directive.js
  31. 3
      frontend/app/work_packages/tabs/user-activity-directive.js
  32. 3
      lib/tabular_form_builder.rb
  33. 2
      spec/controllers/api/v2/custom_fields_controller_spec.rb
  34. 60
      spec/controllers/work_packages/auto_completes_controller_spec.rb
  35. 2
      spec/factories/user_preference_factory.rb
  36. 12
      spec/features/work_packages/details/inplace_editor/shared_contexts.rb
  37. 5
      spec/features/work_packages/details/inplace_editor/subject_editor_spec.rb
  38. 8
      spec/lib/api/v3/users/user_representer_spec.rb
  39. 47
      spec/models/user_preference_spec.rb
  40. 6
      spec/requests/api/v3/authentication_spec.rb

@ -344,7 +344,7 @@ function observeParentIssueField(url) {
updateElement: function(value) {
document.getElementById('issue_parent_id').value = value.id;
},
parameters: 'scope=all'
parameters: 'scope=relatable'
});
}
@ -358,7 +358,7 @@ function observeWorkPackageParentField(url) {
updateElement: function(value) {
document.getElementById('work_package_parent_id').value = value.id;
},
parameters: 'scope=all'
parameters: 'scope=relatable'
});
}
@ -372,7 +372,7 @@ function observeRelatedIssueField(url) {
updateElement: function(value) {
document.getElementById('relation_to_id').value = value.id;
},
parameters: 'scope=all'
parameters: 'scope=relatable'
});
}

@ -122,7 +122,7 @@
</div>
<div class="jstEditor">
<textarea wiki-toolbar="" class="focus-input inplace-edit--textarea " preview-toggle="togglePreview()" name="value" title="Description: Edit" data-wp_autocomplete_url="/work_packages/auto_complete.json?project_id=undefined" aria-multiline="true" tabindex="0" aria-hidden="false" aria-disabled="false" aria-invalid="false" rows="5">
<textarea wiki-toolbar="" class="focus-input inplace-edit--textarea " preview-toggle="togglePreview()" name="value" title="Description: Edit" aria-multiline="true" tabindex="0" aria-hidden="false" aria-disabled="false" aria-invalid="false" rows="5">
</textarea>
</div>

@ -30,43 +30,65 @@
require 'rack/utils'
class WorkPackages::AutoCompletesController < ApplicationController
before_filter :find_project
def index
@work_packages = []
q = params[:q].to_s
scope = determine_scope
if scope.nil?
render_404
return
end
if q.present?
query = (params[:scope] == 'all' && Setting.cross_project_work_package_relations?) ? WorkPackage : @project.work_packages
query_term = params[:q].to_s
@work_packages = []
# query for exact ID matches first, to make an exact match the first result of autocompletion
if query_term =~ /\A\d+\z/
@work_packages |= scope.visible.find_all_by_id(query_term.to_i)
end
@work_packages |= query.visible.find_all_by_id(q.to_i) if q =~ /\A\d+\z/
sql_query = ["LOWER(#{WorkPackage.table_name}.subject) LIKE :q OR
CAST(#{WorkPackage.table_name}.id AS CHAR(13)) LIKE :q",
{ q: "%#{query_term.downcase}%" }]
@work_packages |= query.visible.find(:all,
limit: 10,
order: "#{WorkPackage.table_name}.id ASC",
conditions: ["LOWER(#{WorkPackage.table_name}.subject) LIKE :q OR CAST(#{WorkPackage.table_name}.id AS CHAR(13)) LIKE :q", { q: "%#{q.downcase}%" }])
end
@work_packages |= scope.visible
.where(sql_query)
.order("#{WorkPackage.table_name}.id ASC") # :id does not work because...
.limit(10)
respond_to do |format|
format.html { render layout: false }
format.any(:xml, :json) { render request.format.to_sym => wp_hash_with_string }
format.any(:xml, :json) { render request.format.to_sym => wp_hashes_with_string }
end
end
private
def wp_hash_with_string
@work_packages.map do |wp|
Hash[wp.attributes.map do |key, value|
[key, Rack::Utils.escape_html(value)]
end << ['to_s', Rack::Utils.escape_html(wp.to_s)]]
def wp_hashes_with_string
@work_packages.map do |work_package|
wp_hash = Hash.new
work_package.attributes.each { |key, value| wp_hash[key] = Rack::Utils.escape_html(value) }
wp_hash['to_s'] = Rack::Utils.escape_html(work_package.to_s)
wp_hash
end
end
def find_project
project_id = (params[:work_package] && params[:work_package][:project_id]) || params[:project_id]
@project = Project.find(project_id)
return nil unless project_id
Project.find(project_id)
rescue ActiveRecord::RecordNotFound
render_404
nil
end
def determine_scope
project = find_project
if params[:scope] == 'relatable'
return nil unless project
Setting.cross_project_work_package_relations? ? WorkPackage.scoped : project.work_packages
elsif params[:scope] == 'all' || project.nil?
WorkPackage.scoped
else
project.work_packages
end
end
end

@ -246,7 +246,7 @@ module WorkPackagesHelper
title << content_tag(:span, l(:description_sub_work_package), class: 'hidden-for-sighted')
end
issue_text = link_to(work_package.to_s.html_safe, work_package_path(work_package))
issue_text = link_to(work_package.to_s, work_package_path(work_package))
end
content_tag :tr, class: css_classes.join(' ') do

@ -35,8 +35,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% rows = @journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min %>
<%= text_area_tag :notes, @journal.notes,
:class => 'wiki-edit',
:rows => rows,
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json) %>
:rows => rows %>
<%= javascript_tag("enable_textarea_auto_completion(jQuery('#notes'));") %>
<%= call_hook(:view_journals_notes_form_after_notes, { :journal => @journal}) %>

@ -45,7 +45,7 @@ See doc/COPYRIGHT.rdoc for more details.
</div>
<% end %>
<div class="form--field -required">
<%= f.text_area :content, required: true, label: l(:description_message_content), class: 'wiki-edit', data: {:'ng-non-bindable' => '' }, 'data-wp_autocomplete_url' => work_packages_auto_complete_path(project_id: @project, format: :json) %>
<%= f.text_area :content, required: true, label: l(:description_message_content), class: 'wiki-edit', data: {:'ng-non-bindable' => '' } %>
<%= wikitoolbar_for(replying ? 'reply_content' : 'message_content') %>
</div>
<%= render :partial => 'attachments/form' %>

@ -35,7 +35,6 @@ See doc/COPYRIGHT.rdoc for more details.
</div>
<div class="form--field">
<%= f.text_area :description, :required => true, :cols => 60, :rows => 15, :class => 'wiki-edit',
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json),
:'ng-non-bindable' => '' %>
</div>
<%= wikitoolbar_for 'news_description' %>

@ -95,8 +95,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= form_for([@news, Comment.new], :html => { :id => "add_comment_form", :style => "display:none;" }) do %>
<div class="box">
<%= label_tag 'comment_comments', Journal.human_attribute_name(:notes), :class => 'hidden-for-sighted' %>
<%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit',
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json) %>
<%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
<%= wikitoolbar_for 'comment_comments' %>
</div>
<p><%= submit_tag l(:button_add), class: 'button -highlight' %></p>

@ -28,7 +28,6 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<div class="form--field -required">
<%= f.text_area(:description, :class => 'timelines-project-association-description wiki-edit', :rows => 10,
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json),
:'ng-non-bindable' => '') %>
</div>
<%= wikitoolbar_for 'project_association_description' %>

@ -27,17 +27,10 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<%
project = form.object
autocomplete_path = work_packages_auto_complete_path(project_id: project,
format: :json)
%>
<div class="form--field">
<%= form.text_area :description,
rows: 5,
class: 'wiki-edit',
:'data-wp_autocomplete_url' => autocomplete_path,
:'ng-non-bindable' => '' %>
</div>
<%= wikitoolbar_for 'project_description' %>

@ -27,17 +27,9 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<%
project = form.object
autocomplete_path = work_packages_auto_complete_path(project_id: project,
format: :json)
%>
<div class="form--field">
<%= form.text_area :summary,
rows: 2,
class: 'wiki-edit',
:'data-wp_autocomplete_url' => autocomplete_path,
:'ng-non-bindable' => '' %>
</div>

@ -58,7 +58,6 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="form--field">
<%= f.text_area(:reported_project_status_comment, :class => 'wiki-edit', :rows => 10,
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json),
:'ng-non-bindable' => '', label: Reporting.human_attribute_name(:reported_project_status_comment)) %>
</div>
<%= wikitoolbar_for 'reporting_reported_project_status_comment' %>

@ -33,7 +33,6 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="form--field -required -vertical">
<%= f.text_area :text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit),
:value => format_text(@content, :text, :attachments => @content.page.attachments, :edit => true),
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json),
:'ng-non-bindable' => '' %>
</div>
<div class="form--field">

@ -49,7 +49,6 @@ See doc/COPYRIGHT.rdoc for more details.
</div>
<div class="form--field -required -vertical">
<%= f.text_area :text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit),
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json),
:'ng-non-bindable' => '' %>
</div>

@ -57,8 +57,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= f.text_area :journal_notes, :cols => 60,
:rows => 10,
:class => 'wiki-edit',
:label => Journal.human_attribute_name(:notes),
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => project, :format => :json) %>
:label => Journal.human_attribute_name(:notes) %>
<%= wikitoolbar_for 'work_package_journal_notes' %>
</div>

@ -57,8 +57,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= f.text_field :subject, required: true %>
</div>
<div class="form--field -vertical">
<%= f.text_area :description, accesskey: accesskey(:edit), class: 'wiki-edit', rows: 10, :'ng-non-bindable' => '',
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(project_id: work_package.project, format: :json) %>
<%= f.text_area :description, accesskey: accesskey(:edit), class: 'wiki-edit', rows: 10, :'ng-non-bindable' => '' %>
</div>
<div id="attributes" class="attributes">

@ -140,8 +140,7 @@ See doc/COPYRIGHT.rdoc for more details.
<fieldset class="form--fieldset">
<legend class="form--fieldset-legend"><%= Journal.human_attribute_name(:notes) %></legend>
<%= label_tag 'notes', Journal.human_attribute_name(:notes), :class => 'hidden-for-sighted' %>
<%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit',
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json) %>
<%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
<%= wikitoolbar_for 'notes' %>
<p><%= send_notification_option %></p>
</fieldset>

@ -113,8 +113,7 @@ See doc/COPYRIGHT.rdoc for more details.
<fieldset class="form--fieldset">
<legend class="form--fieldset-legend"><%= Journal.human_attribute_name(:notes) %></legend>
<%= label_tag 'notes', Journal.human_attribute_name(:notes), :class => 'hidden-for-sighted' %>
<%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit',
:'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @target_project, :format => :json) %>
<%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
<%= wikitoolbar_for 'notes' %>
</fieldset>
<%= call_hook(:view_work_packages_move_bottom, :work_packages => @work_packages, :target_project => @target_project, :copy => !!@copy) %>

@ -0,0 +1,33 @@
#-- 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.
#++
class HideMailByDefault < ActiveRecord::Migration
def change
change_column_default :user_preferences, :hide_mail, true
end
end

@ -1468,6 +1468,7 @@ _GET_ @/api/v2/projects/:project_id/workflows(.:format)@
This end-point returns the following HTTP status codes:
| *HTTP Status Code* | *Meaning* | *Response* |
| ------------------ | --------- | ---------------------------------------------------- |
| 200 | Success | Authentication Data |
| 401 | Unauthorized - cannot find user for given credentials | empty |
| 403 | Forbidden - API does not allow authentication (Settings) | empty |

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
module.exports = function($http) {
module.exports = function($http, PathHelper) {
var getAtWhoParameters = function(url) {
return {
at: '#',
@ -57,7 +57,7 @@ module.exports = function($http) {
return {
enableTextareaAutoCompletion: function(textareas) {
angular.forEach(textareas, function(textarea) {
var url = angular.element(textarea).data('wp_autocomplete_url');
var url = PathHelper.workPackageJsonAutoCompletePath();
if (url !== undefined && url.length > 0) {
angular.element(textarea).atwho(getAtWhoParameters(url));

@ -28,7 +28,7 @@
angular.module('openproject.helpers')
.constant('CUSTOM_FIELD_PREFIX', 'cf_')
.service('AutoCompleteHelper', ['$http', require('./auto-complete-helper')])
.service('AutoCompleteHelper', ['$http', 'PathHelper', require('./auto-complete-helper')])
.service('CustomFieldHelper', ['CUSTOM_FIELD_PREFIX', 'I18n', require(
'./custom-field-helper')])
.service('PathHelper', require('./path-helper'))

@ -126,9 +126,6 @@ module.exports = function() {
workPackagesBulkDeletePath: function() {
return PathHelper.workPackagesPath() + '/bulk';
},
workPackageAutoCompletePath: function(projectId, workPackageId) {
return '/work_packages/auto_complete?escape=false&id=' + workPackageId + '&project_id=' + projectId;
},
workPackageJsonAutoCompletePath: function() {
return '/work_packages/auto_complete.json';
},
@ -284,10 +281,6 @@ module.exports = function() {
staticWorkPackagesAutocompletePath: function(projectId) {
return PathHelper.staticBase + '/work_packages/auto_complete.json?project_id=' + projectId;
},
staticWorkPackageAutoCompletePath: function(projectId, workPackageId) {
return PathHelper.staticBase
+ PathHelper.workPackageAutoCompletePath(projectId, workPackageId);
},
staticProjectWikiPath: function(projectId) {
return PathHelper.staticProjectPath(projectId) + '/wiki';
},

@ -9,8 +9,7 @@
ng-model="$parent.activity.comment"
required
placeholder="{{ $parent.title }}"
ng-disabled="$parent.processingComment"
data-wp_autocomplete_url="{{ autocompletePath }}">
ng-disabled="$parent.processingComment">
</textarea>
<button class="button"
ng-click="$parent.createComment()"

@ -4,6 +4,5 @@
ng-disabled="fieldController.state.isBusy"
ng-required="editPaneController.isRequired"
ng-model="fieldController.writeValue.raw"
title="{{ fieldController.editTitle }}"
data-wp_autocomplete_url="{{ autocompletePath }}">
title="{{ fieldController.editTitle }}">
</textarea>

@ -8,8 +8,7 @@
ng-disabled="fieldController.state.isBusy"
ng-required="editPaneController.isRequired"
ng-model="fieldController.writeValue.raw"
title="{{ fieldController.editTitle }}"
data-wp_autocomplete_url="{{customEditorController.autocompletePath }}">
title="{{ fieldController.editTitle }}">
</textarea>
<div class="inplace-edit--preview" ng-if="customEditorController.isPreview && !fieldController.state.isBusy">
<span ng-bind-html="customEditorController.previewHtml"></span>

@ -33,8 +33,7 @@
ng-model="activity.props.comment.raw"
ng-bind-html="activity.props.comment.html"
rows="4"
required
data-wp_autocomplete_url="{{ autocompletePath }}">
required>
</textarea>
</div>
<div>

@ -38,8 +38,7 @@ module.exports = function($timeout,
require: '^?exclusiveEdit',
scope: {
workPackage: '=',
activities: '=',
autocompletePath: '@'
activities: '='
},
templateUrl: '/templates/components/activity_comment.html',
link: function(scope, element, attrs, exclusiveEditController) {

@ -37,8 +37,7 @@ module.exports = function(TextileService, EditableFieldsState, $sce, AutoComplet
controller: function($scope) {
this.isPreview = false;
this.previewHtml = '';
this.autocompletePath = '/work_packages/auto_complete.json?project_id=' +
EditableFieldsState.workPackage.embedded.project.props.id;
this.autocompletePath = '/work_packages/auto_complete.json';
this.togglePreview = function() {
this.isPreview = !this.isPreview;

@ -39,7 +39,7 @@ module.exports = function($http, PathHelper) {
}
var params = {
q: term,
scope: 'all',
scope: 'relatable',
escape: false,
id: scope.handler.workPackage.props.id,
'project_id': scope.handler.workPackage.embedded.project.props.id

@ -45,8 +45,7 @@ module.exports = function($uiViewScroll,
workPackage: '=',
activity: '=',
activityNo: '=',
inputElementId: '=',
autocompletePath: '@'
inputElementId: '='
},
link: function(scope, element, attrs, exclusiveEditController) {
exclusiveEditController.addEditable(scope);

@ -32,6 +32,7 @@ require 'action_view/helpers/form_helper'
class TabularFormBuilder < ActionView::Helpers::FormBuilder
include Redmine::I18n
include ActionView::Helpers::AssetTagHelper
include ERB::Util
(field_helpers - %i(radio_button hidden_field fields_for label) + %i(date_select)).each do |selector|
define_method selector do |field, options = {}, *args|
@ -204,7 +205,7 @@ class TabularFormBuilder < ActionView::Helpers::FormBuilder
label_options[:lang] = options[:lang]
label_options.reject! { |_k, v| v.nil? }
@template.label(@object_name, field, text.html_safe, label_options)
@template.label(@object_name, field, h(text), label_options)
end
def element_id(translation_form)

@ -73,7 +73,7 @@ describe Api::V2::CustomFieldsController, type: :controller do
end
describe 'unauthorized access' do
before { get :index, project_id: project.id, format: :xml }
before { allow(Setting).to receive(:login_required).and_return false }
it_behaves_like 'a user w/o a project'
end

@ -181,7 +181,7 @@ describe WorkPackages::AutoCompletesController, type: :controller do
end
end
describe '#cross_project_work_package_relations' do
describe 'in different projects' do
let(:project_2) {
FactoryGirl.create(:project,
parent: project)
@ -203,38 +203,74 @@ describe WorkPackages::AutoCompletesController, type: :controller do
work_package_4
end
context 'with scope all and cross project relations' do
let(:expected_values) { work_package_4 }
context 'with cross project relations' do
let(:project_id) { project.id }
before do
allow(Setting).to receive(:cross_project_work_package_relations?).and_return(true)
get :index,
project_id: project.id,
project_id: project_id,
q: work_package_4.id,
scope: 'all'
scope: scope
end
context 'with scope "relatable"' do
let(:scope) { 'relatable' }
let(:expected_values) { work_package_4 }
it_behaves_like 'successful response'
it_behaves_like 'contains expected values'
context 'without project_id' do
let(:project_id) { nil }
it 'returns HTTP Not Found' do
expect(response.status).to eql(404)
end
end
end
it_behaves_like 'successful response'
context 'with scope "all"' do
let(:scope) { 'all' }
let(:expected_values) { work_package_4 }
it_behaves_like 'successful response'
it_behaves_like 'contains expected values'
it_behaves_like 'contains expected values'
end
end
context 'with scope all but w/o cross project relations' do
context 'without cross project relations' do
before do
allow(Setting).to receive(:cross_project_work_package_relations?).and_return(false)
get :index,
project_id: project.id,
q: work_package_4.id,
scope: 'all'
scope: scope
end
it_behaves_like 'successful response'
context 'with scope "relatable"' do
let(:scope) { 'relatable' }
let(:expected_values) { work_package_4 }
it_behaves_like 'successful response'
subject { assigns(:work_packages) }
subject { assigns(:work_packages) }
it { is_expected.to eq([]) }
end
it { is_expected.to eq([]) }
context 'with scope "all"' do
let(:scope) { 'all' }
let(:expected_values) { work_package_4 }
it_behaves_like 'successful response'
it_behaves_like 'contains expected values'
end
end
end
end

@ -29,7 +29,7 @@
FactoryGirl.define do
factory :user_preference do
user
hide_mail 0
hide_mail true
others = {}
end
end

@ -47,3 +47,15 @@ shared_context 'ensure wp table loaded' do
'Work package table page was not loaded in time'
end
end
shared_context 'ensure wp details pane update done' do
after do
raise "Expect to have a let called 'update_user' defining which user \
is doing the update".squish unless update_user
# safeguard to ensure all backend queries
# have been answered before starting a new spec
expect(page).to have_selector('.work-package-details-activities-activity-contents .user',
text: update_user.name)
end
end

@ -50,6 +50,11 @@ describe 'subject inplace editor', js: true do
field.input_element.set 'Aloha'
end
# safeguard
include_context 'ensure wp details pane update done' do
let(:update_user) { user }
end
it 'displays the new value after save' do
field.submit_by_click
expect(field.read_state_text).to eq 'Aloha'

@ -45,12 +45,8 @@ describe ::API::V3::Users::UserRepresenter do
it { is_expected.to have_json_path('name') }
describe 'email' do
it 'shows the users E-Mail address' do
is_expected.to be_json_eql(user.mail.to_json).at_path('email')
end
context 'user shows his E-Mail address' do
let(:preference) { FactoryGirl.build(:user_preference, hide_mail: 0) }
let(:preference) { FactoryGirl.build(:user_preference, hide_mail: false) }
let(:user) { FactoryGirl.build_stubbed(:user, status: 1, preference: preference) }
it 'shows the users E-Mail address' do
@ -59,7 +55,7 @@ describe ::API::V3::Users::UserRepresenter do
end
context 'user hides his E-Mail address' do
let(:preference) { FactoryGirl.build(:user_preference, hide_mail: 1) }
let(:preference) { FactoryGirl.build(:user_preference, hide_mail: true) }
let(:user) { FactoryGirl.build_stubbed(:user, status: 1, preference: preference) }
it 'hides the users E-Mail address' do

@ -0,0 +1,47 @@
#-- 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 UserPreference do
subject { described_class.new }
describe 'default settings' do
it 'hides the email address' do
expect(subject.hide_mail).to eql(true)
end
it 'has an empty others hash' do
expect(subject.others).to eql({})
end
it 'disables accessibility mode' do
expect(subject.impaired).to eql(false)
end
end
end

@ -107,7 +107,8 @@ describe API::V3, type: :request do
context 'with login required' do
before do
Setting.login_required = 1
allow(Setting).to receive(:login_required).and_return(true)
allow(Setting).to receive(:login_required?).and_return(true)
end
context 'with global basic auth configured' do
@ -144,7 +145,8 @@ describe API::V3, type: :request do
context 'without login required' do
before do
Setting.login_required = 0
allow(Setting).to receive(:login_required).and_return(false)
allow(Setting).to receive(:login_required?).and_return(false)
end
context 'with global and user basic auth enabled' do

Loading…
Cancel
Save