diff --git a/app/controllers/time_entries/reports_controller.rb b/app/controllers/time_entries/reports_controller.rb
index cda839b2ab..98f9f36470 100644
--- a/app/controllers/time_entries/reports_controller.rb
+++ b/app/controllers/time_entries/reports_controller.rb
@@ -135,27 +135,39 @@ class TimeEntries::ReportsController < ApplicationController
# Add list and boolean custom fields as available criterias
custom_fields = (@project.nil? ? WorkPackageCustomField.for_all : @project.all_work_package_custom_fields)
- custom_fields.select { |cf| %w(list bool).include? cf.field_format }.each do |cf|
- @available_criterias["cf_#{cf.id}"] = { sql: "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'WorkPackage' AND c.customized_id = #{WorkPackage.table_name}.id)",
- format: cf.field_format,
- label: cf.name }
- end if @project
+
+ if @project
+ custom_fields.select { |cf| %w(list bool).include? cf.field_format }.each do |cf|
+ @available_criterias["cf_#{cf.id}"] = { sql: "(SELECT c.value FROM #{CustomValue.table_name} c
+ WHERE c.custom_field_id = #{cf.id}
+ AND c.customized_type = 'WorkPackage'
+ AND c.customized_id = #{WorkPackage.table_name}.id)",
+ format: cf,
+ label: cf.name }
+ end
+ end
# Add list and boolean time entry custom fields
TimeEntryCustomField.all.select { |cf| %w(list bool).include? cf.field_format }.each do |cf|
- @available_criterias["cf_#{cf.id}"] = { sql: "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
- format: cf.field_format,
+ @available_criterias["cf_#{cf.id}"] = { sql: "(SELECT c.value FROM #{CustomValue.table_name} c
+ WHERE c.custom_field_id = #{cf.id}
+ AND c.customized_type = 'TimeEntry'
+ AND c.customized_id = #{TimeEntry.table_name}.id)",
+ format: cf,
label: cf.name }
end
# Add list and boolean time entry activity custom fields
TimeEntryActivityCustomField.all.select { |cf| %w(list bool).include? cf.field_format }.each do |cf|
- @available_criterias["cf_#{cf.id}"] = { sql: "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id)",
- format: cf.field_format,
+ @available_criterias["cf_#{cf.id}"] = { sql: "(SELECT c.value FROM #{CustomValue.table_name} c
+ WHERE c.custom_field_id = #{cf.id}
+ AND c.customized_type = 'Enumeration'
+ AND c.customized_id = #{TimeEntry.table_name}.activity_id)",
+ format: cf,
label: cf.name }
end
- call_hook(:controller_timelog_available_criterias, available_criterias: @available_criterias, project: @project)
+ call_hook(:controller_timelog_available_criterias, available_criterias: @available_criterias, project: @project)
@available_criterias
end
diff --git a/app/helpers/custom_fields_helper.rb b/app/helpers/custom_fields_helper.rb
index 3b553edd0e..811b486a9d 100644
--- a/app/helpers/custom_fields_helper.rb
+++ b/app/helpers/custom_fields_helper.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -47,7 +48,7 @@ module CustomFieldsHelper
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
field_id = "#{name}_custom_field_values_#{custom_field.id}"
- field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
+ field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format)
tag = case field_format.try(:edit_as)
when 'date'
@@ -114,7 +115,7 @@ module CustomFieldsHelper
def custom_field_tag_for_bulk_edit(name, custom_field, project=nil)
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
field_id = "#{name}_custom_field_values_#{custom_field.id}"
- field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
+ field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format)
case field_format.try(:edit_as)
when 'date'
styled_text_field_tag(field_name, '', id: field_id, size: 10) +
@@ -135,27 +136,32 @@ module CustomFieldsHelper
# Return a string used to display a custom value
def show_value(custom_value)
return '' unless custom_value
- format_value(custom_value.value, custom_value.custom_field.field_format)
+ custom_value.formatted_value
end
# Return a string used to display a custom value
- def format_value(value, field_format)
- Redmine::CustomFieldFormat.format_value(value, field_format) # Proxy
+ def format_value(value, custom_field)
+ custom_value = CustomValue.new(custom_field: custom_field,
+ value: value)
+
+ custom_value.formatted_value
end
# Return an array of custom field formats which can be used in select_tag
def custom_field_formats_for_select(custom_field)
- Redmine::CustomFieldFormat.as_select(custom_field.class.customized_class.name)
+ OpenProject::CustomFieldFormat
+ .all_for_field(custom_field)
+ .sort_by(&:order)
+ .map do |custom_field_format|
+ [label_for_custom_field_format(custom_field_format.name), custom_field_format.name]
+ end
end
- # Renders the custom_values in api views
- def render_api_custom_values(custom_values, api)
- api.array :custom_fields do
- custom_values.each do |custom_value|
- api.custom_field id: custom_value.custom_field_id, name: custom_value.custom_field.name do
- api.value custom_value.value
- end
- end
- end unless custom_values.empty?
+ def label_for_custom_field_format(format_string)
+ format = OpenProject::CustomFieldFormat.find_by_name(format_string)
+
+ if format
+ format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label)
+ end
end
end
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index 245864c962..31b5d0832d 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -49,7 +49,7 @@ class CustomField < ActiveRecord::Base
errors.add(:name, :taken) if name.in?(taken_names)
end
- validates_inclusion_of :field_format, in: Redmine::CustomFieldFormat.available_formats
+ validates_inclusion_of :field_format, in: OpenProject::CustomFieldFormat.available_formats
validate :validate_default_value
@@ -96,6 +96,10 @@ class CustomField < ActiveRecord::Base
end
end
+ def required?
+ is_required?
+ end
+
def possible_values_options(obj = nil)
case field_format
when 'user', 'version'
diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb
index 058d500358..22a4233d75 100644
--- a/app/models/custom_value.rb
+++ b/app/models/custom_value.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -28,18 +29,6 @@
#++
class CustomValue < ActiveRecord::Base
- FORMAT_STRATEGIES = {
- 'string' => CustomValue::StringStrategy,
- 'text' => CustomValue::StringStrategy,
- 'int' => CustomValue::IntStrategy,
- 'float' => CustomValue::FloatStrategy,
- 'date' => CustomValue::DateStrategy,
- 'bool' => CustomValue::BoolStrategy,
- 'user' => CustomValue::UserStrategy,
- 'version' => CustomValue::VersionStrategy,
- 'list' => CustomValue::ListStrategy
- }.freeze
-
belongs_to :custom_field
belongs_to :customized, polymorphic: true
@@ -48,23 +37,16 @@ class CustomValue < ActiveRecord::Base
validate :validate_type_of_value
validate :validate_length_of_value
- # returns the value of this custom value, but converts it according to the field_format
- # of the custom field beforehand
- def typed_value
- strategy.typed_value
- end
-
- def editable?
- custom_field.editable?
- end
-
- def visible?
- custom_field.visible?
- end
+ delegate :typed_value,
+ :formatted_value,
+ to: :strategy
- def required?
- custom_field.is_required?
- end
+ delegate :editable?,
+ :visible?,
+ :required?,
+ :max_length,
+ :min_length,
+ to: :custom_field
def to_s
value.to_s
@@ -79,7 +61,7 @@ class CustomValue < ActiveRecord::Base
protected
def validate_presence_of_required_value
- errors.add(:value, :blank) if custom_field.is_required? && !strategy.value_present?
+ errors.add(:value, :blank) if custom_field.required? && !strategy.value_present?
end
def validate_format_of_value
@@ -98,15 +80,23 @@ class CustomValue < ActiveRecord::Base
end
def validate_length_of_value
- if value.present? && custom_field.min_length.present? && custom_field.max_length.present?
- errors.add(:value, :too_short, count: custom_field.min_length) if custom_field.min_length > 0 and value.length < custom_field.min_length
- errors.add(:value, :too_long, count: custom_field.max_length) if custom_field.max_length > 0 and value.length > custom_field.max_length
+ if value.present? && (min_length.present? || max_length.present?)
+ validate_min_length_of_value
+ validate_max_length_of_value
end
end
private
+ def validate_min_length_of_value
+ errors.add(:value, :too_short, count: min_length) if min_length > 0 && value.length < min_length
+ end
+
+ def validate_max_length_of_value
+ errors.add(:value, :too_long, count: max_length) if max_length > 0 && value.length > max_length
+ end
+
def strategy
- @strategy ||= FORMAT_STRATEGIES[custom_field.field_format].new(self)
+ @strategy ||= OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format).formatter.new(self)
end
end
diff --git a/app/models/custom_value/ar_object_strategy.rb b/app/models/custom_value/ar_object_strategy.rb
index 3e022b4e70..79aae8a19d 100644
--- a/app/models/custom_value/ar_object_strategy.rb
+++ b/app/models/custom_value/ar_object_strategy.rb
@@ -39,6 +39,10 @@ class CustomValue::ARObjectStrategy < CustomValue::FormatStrategy
end
end
+ def formatted_value
+ typed_value.to_s
+ end
+
def parse_value(val)
if val.is_a?(ar_class)
self.memoized_typed_value = val
diff --git a/app/models/custom_value/bool_strategy.rb b/app/models/custom_value/bool_strategy.rb
index 3fd1e75088..b9cc16b986 100644
--- a/app/models/custom_value/bool_strategy.rb
+++ b/app/models/custom_value/bool_strategy.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -41,6 +42,11 @@ class CustomValue::BoolStrategy < CustomValue::FormatStrategy
ActiveRecord::Type::Boolean.new.cast(value)
end
+ def formatted_value
+ is_true = ActiveRecord::Type::Boolean.new.cast(value)
+ I18n.t(is_true ? :general_text_Yes : :general_text_No)
+ end
+
def parse_value(val)
parsed_val = if !present?(val)
nil
@@ -53,8 +59,7 @@ class CustomValue::BoolStrategy < CustomValue::FormatStrategy
super(parsed_val)
end
- def validate_type_of_value
- end
+ def validate_type_of_value; end
private
diff --git a/app/models/custom_value/date_strategy.rb b/app/models/custom_value/date_strategy.rb
index 96e040f239..1852b80c7e 100644
--- a/app/models/custom_value/date_strategy.rb
+++ b/app/models/custom_value/date_strategy.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -34,6 +35,12 @@ class CustomValue::DateStrategy < CustomValue::FormatStrategy
end
end
+ def formatted_value
+ format_date(value.to_date)
+ rescue
+ value.to_s
+ end
+
def validate_type_of_value
return nil if value.is_a? Date
diff --git a/app/models/custom_value/float_strategy.rb b/app/models/custom_value/float_strategy.rb
index 79665cc983..6bd8167d6a 100644
--- a/app/models/custom_value/float_strategy.rb
+++ b/app/models/custom_value/float_strategy.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -28,12 +29,18 @@
#++
class CustomValue::FloatStrategy < CustomValue::FormatStrategy
+ include ActionView::Helpers::NumberHelper
+
def typed_value
unless value.blank?
value.to_f
end
end
+ def formatted_value
+ number_with_delimiter(value.to_s)
+ end
+
def validate_type_of_value
Kernel.Float(value)
nil
diff --git a/app/models/custom_value/format_strategy.rb b/app/models/custom_value/format_strategy.rb
index 895a2b3136..e3a7a12033 100644
--- a/app/models/custom_value/format_strategy.rb
+++ b/app/models/custom_value/format_strategy.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -45,6 +46,12 @@ class CustomValue::FormatStrategy
raise 'SubclassResponsibility'
end
+ # Returns the value of the CustomValue formatted to a string
+ # representation.
+ def formatted_value
+ value.to_s
+ end
+
# Parses the value to
# 1) have a unified representation for different inputs
# 2) memoize typed values (if the subclass descides to do so
diff --git a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb
index b63f026f87..4d6deeaf3e 100644
--- a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb
+++ b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb
@@ -171,11 +171,11 @@ class WorkPackage::PdfExport::WorkPackageListToPdf
end
def make_custom_field_value(work_package, column)
- value = work_package
- .custom_values
- .detect { |v| v.custom_field_id == column.custom_field.id }
+ values = work_package
+ .custom_values
+ .select { |v| v.custom_field_id == column.custom_field.id }
- pdf.make_cell show_value(value),
+ pdf.make_cell values.map(&:formatted_value).join(', '),
padding: cell_padding
end
end
diff --git a/app/views/custom_fields/_tab.html.erb b/app/views/custom_fields/_tab.html.erb
index 36582e2a7c..9b0f4e7872 100644
--- a/app/views/custom_fields/_tab.html.erb
+++ b/app/views/custom_fields/_tab.html.erb
@@ -107,7 +107,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%>
<%= link_to h(custom_field.name), edit_custom_field_path(custom_field), lang: custom_field.name_locale %> |
- <%= Redmine::CustomFieldFormat.label_for(custom_field.field_format) %> |
+ <%= label_for_custom_field_format(custom_field.field_format) %> |
<%= checked_image custom_field.is_required? %> |
<% if tab[:name] == 'WorkPackageCustomField' %>
<%= checked_image custom_field.is_for_all? %> |
diff --git a/app/views/time_entries/reports/_report_criteria.html.erb b/app/views/time_entries/reports/_report_criteria.html.erb
index e049c3e4f6..a945f466e9 100644
--- a/app/views/time_entries/reports/_report_criteria.html.erb
+++ b/app/views/time_entries/reports/_report_criteria.html.erb
@@ -28,6 +28,7 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<% @hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value| %>
+
<% hours_for_value = select_hours(hours, criterias[level], value) -%>
<% next if hours_for_value.empty? -%>
diff --git a/config/initializers/custom_field_format.rb b/config/initializers/custom_field_format.rb
index d574401319..213a6899b9 100644
--- a/config/initializers/custom_field_format.rb
+++ b/config/initializers/custom_field_format.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -27,38 +28,45 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
-Redmine::CustomFieldFormat.map do |fields|
- fields.register Redmine::CustomFieldFormat.new('string',
- label: :label_string,
- order: 1)
- fields.register Redmine::CustomFieldFormat.new('text',
- label: :label_text,
- order: 2)
- fields.register Redmine::CustomFieldFormat.new('int',
- label: :label_integer,
- order: 3)
- fields.register Redmine::CustomFieldFormat.new('float',
- label: :label_float,
- order: 4)
- fields.register Redmine::CustomFieldFormat.new('list',
- label: :label_list,
- order: 5)
- fields.register Redmine::CustomFieldFormat.new('date',
- label: :label_date,
- order: 6)
- fields.register Redmine::CustomFieldFormat.new('bool',
- label: :label_boolean,
- order: 7)
- fields.register Redmine::CustomFieldFormat.new('user',
- label: Proc.new { User.model_name.human },
- only: %w(WorkPackage TimeEntry
- Version Project),
- edit_as: 'list',
- order: 8)
- fields.register Redmine::CustomFieldFormat.new('version',
- label: Proc.new { Version.model_name.human },
- only: %w(WorkPackage TimeEntry
- Version Project),
- edit_as: 'list',
- order: 9)
+OpenProject::CustomFieldFormat.map do |fields|
+ fields.register OpenProject::CustomFieldFormat.new('string',
+ label: :label_string,
+ order: 1)
+ fields.register OpenProject::CustomFieldFormat.new('text',
+ label: :label_text,
+ order: 2)
+ fields.register OpenProject::CustomFieldFormat.new('int',
+ label: :label_integer,
+ order: 3,
+ formatter: CustomValue::IntStrategy)
+ fields.register OpenProject::CustomFieldFormat.new('float',
+ label: :label_float,
+ order: 4,
+ formatter: CustomValue::FloatStrategy)
+ fields.register OpenProject::CustomFieldFormat.new('list',
+ label: :label_list,
+ order: 5,
+ formatter: CustomValue::ListStrategy)
+ fields.register OpenProject::CustomFieldFormat.new('date',
+ label: :label_date,
+ order: 6,
+ formatter: CustomValue::DateStrategy)
+ fields.register OpenProject::CustomFieldFormat.new('bool',
+ label: :label_boolean,
+ order: 7,
+ formatter: CustomValue::BoolStrategy)
+ fields.register OpenProject::CustomFieldFormat.new('user',
+ label: Proc.new { User.model_name.human },
+ only: %w(WorkPackage TimeEntry
+ Version Project),
+ edit_as: 'list',
+ order: 8,
+ formatter: CustomValue::UserStrategy)
+ fields.register OpenProject::CustomFieldFormat.new('version',
+ label: Proc.new { Version.model_name.human },
+ only: %w(WorkPackage TimeEntry
+ Version Project),
+ edit_as: 'list',
+ order: 9,
+ formatter: CustomValue::VersionStrategy)
end
diff --git a/lib/custom_field_form_builder.rb b/lib/custom_field_form_builder.rb
index 301e8349fc..5e9e718e73 100644
--- a/lib/custom_field_form_builder.rb
+++ b/lib/custom_field_form_builder.rb
@@ -54,7 +54,7 @@ class CustomFieldFormBuilder < TabularFormBuilder
name: custom_field_field_name,
id: custom_field_field_id)
- field_format = Redmine::CustomFieldFormat.find_by_name(object.custom_field.field_format)
+ field_format = OpenProject::CustomFieldFormat.find_by_name(object.custom_field.field_format)
case field_format.try(:edit_as)
when 'date'
diff --git a/lib/open_project.rb b/lib/open_project.rb
index 1a4d596434..4e9701535e 100644
--- a/lib/open_project.rb
+++ b/lib/open_project.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -30,7 +31,7 @@
require 'redmine/menu_manager'
require 'redmine/activity'
require 'redmine/search'
-require 'redmine/custom_field_format'
+require 'open_project/custom_field_format'
require 'redmine/mime_type'
require 'redmine/core_ext'
require 'open_project/design'
diff --git a/lib/redmine/custom_field_format.rb b/lib/open_project/custom_field_format.rb
similarity index 54%
rename from lib/redmine/custom_field_format.rb
rename to lib/open_project/custom_field_format.rb
index 367decb4dd..50810b76a2 100644
--- a/lib/redmine/custom_field_format.rb
+++ b/lib/open_project/custom_field_format.rb
@@ -1,4 +1,5 @@
#-- encoding: UTF-8
+
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
@@ -27,50 +28,22 @@
# See doc/COPYRIGHT.rdoc for more details.
#++
-module Redmine
+module OpenProject
class CustomFieldFormat
include Redmine::I18n
- include ActionView::Helpers::NumberHelper
cattr_accessor :available
@@available = {}
- attr_accessor :name, :order, :label, :edit_as, :class_names
+ attr_accessor :name, :order, :label, :edit_as, :class_names, :formatter
- def initialize(name, label:, order:, edit_as: name, only: nil)
+ def initialize(name, label:, order:, edit_as: name, only: nil, formatter: CustomValue::StringStrategy)
self.name = name
self.label = label
self.order = order
self.edit_as = edit_as
self.class_names = only
- end
-
- def format(value)
- send "format_as_#{name}", value
- end
-
- def format_as_date(value)
- format_date(value.to_date); rescue; value end
-
- def format_as_bool(value)
- is_true = ActiveRecord::Type::Boolean.new.cast(value)
- l(is_true ? :general_text_Yes : :general_text_No)
- end
-
- ['string', 'text', 'int', 'list'].each do |name|
- define_method("format_as_#{name}") {|value|
- return value.to_s
- }
- end
-
- def format_as_float(value)
- number_with_delimiter(value.to_s)
- end
-
- ['user', 'version'].each do |name|
- define_method("format_as_#{name}") {|value|
- return value.blank? ? '' : name.classify.constantize.find_by(id: value.to_i).to_s
- }
+ self.formatter = formatter
end
class << self
@@ -91,30 +64,12 @@ module Redmine
@@available[name.to_s]
end
- def label_for(name)
- format = @@available[name.to_s]
- format.label.is_a?(Proc) ? format.label.call : l(format.label) if format
- end
-
- # Return an array of custom field formats which can be used in select_tag
- def as_select(class_name = nil)
- fields = @@available.values
- fields = fields.select { |field| field.class_names.nil? || field.class_names.include?(class_name) }
- fields.sort {|a, b|
- a.order <=> b.order
- }.map {|custom_field_format|
- [label_for(custom_field_format.name), custom_field_format.name]
- }
- end
-
- def format_value(value, field_format)
- return '' unless value && !value.empty?
+ def all_for_field(custom_field)
+ class_name = custom_field.class.customized_class.name
- if format_type = find_by_name(field_format)
- format_type.format(value)
- else
- value
- end
+ available
+ .values
+ .select { |field| field.class_names.nil? || field.class_names.include?(class_name) }
end
end
end
diff --git a/lib/open_project/journal_formatter/custom_field.rb b/lib/open_project/journal_formatter/custom_field.rb
index 461e943067..6c3bbb442c 100644
--- a/lib/open_project/journal_formatter/custom_field.rb
+++ b/lib/open_project/journal_formatter/custom_field.rb
@@ -71,8 +71,8 @@ class OpenProject::JournalFormatter::CustomField < ::JournalFormatter::Base
end
def format_single(custom_field, values)
- old_value = format_value(values.first, custom_field.field_format) if values.first
- value = format_value(values.last, custom_field.field_format) if values.last
+ old_value = format_value(values.first, custom_field) if values.first
+ value = format_value(values.last, custom_field) if values.last
[old_value, value]
end
@@ -89,7 +89,7 @@ class OpenProject::JournalFormatter::CustomField < ::JournalFormatter::Base
String(values)
.split(",")
.map(&:strip)
- .map { |value| format_value value, custom_field.field_format }
+ .map { |value| format_value value, custom_field }
.join(", ")
.presence
end
diff --git a/spec/helpers/custom_fields_helper_spec.rb b/spec/helpers/custom_fields_helper_spec.rb
deleted file mode 100644
index f6cb9eba85..0000000000
--- a/spec/helpers/custom_fields_helper_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-#-- encoding: UTF-8
-#-- copyright
-# OpenProject is a project management system.
-# Copyright (C) 2012-2017 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-2017 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 CustomFieldsHelper, type: :helper do
- include OpenProject::FormTagHelper
- include CustomFieldsHelper
- include Redmine::I18n
-
- it 'should format boolean value' do
- I18n.locale = 'en'
- expect(format_value('1', 'bool')).to eq 'Yes'
- expect(format_value('0', 'bool')).to eq 'No'
- end
-end
diff --git a/spec/lib/api/v3/utilities/custom_field_injector_spec.rb b/spec/lib/api/v3/utilities/custom_field_injector_spec.rb
index a2f87b5162..eb1d86ffca 100644
--- a/spec/lib/api/v3/utilities/custom_field_injector_spec.rb
+++ b/spec/lib/api/v3/utilities/custom_field_injector_spec.rb
@@ -42,7 +42,7 @@ describe ::API::V3::Utilities::CustomFieldInjector do
describe 'TYPE_MAP' do
it 'supports all available formats' do
- Redmine::CustomFieldFormat.available_formats.each do |format|
+ OpenProject::CustomFieldFormat.available_formats.each do |format|
expect(described_class::TYPE_MAP[format]).not_to be_nil
end
end
diff --git a/spec/lib/journal_formatter/custom_field_spec.rb b/spec/lib/journal_formatter/custom_field_spec.rb
index 8345df06a1..ca241b05ff 100644
--- a/spec/lib/journal_formatter/custom_field_spec.rb
+++ b/spec/lib/journal_formatter/custom_field_spec.rb
@@ -45,41 +45,41 @@ describe OpenProject::JournalFormatter::CustomField do
describe '#render' do
describe 'WITH the first value beeing nil, and the second a valid value as string' do
let(:values) { [nil, '1'] }
- let(:formatted_value) { format_value(values.last, custom_field.field_format) }
+ let(:formatted_value) { format_value(values.last, custom_field) }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_set_to,
label: "#{custom_field.name}",
value: "#{formatted_value}")
- }
+ end
it { expect(instance.render(key, values)).to eq(expected) }
end
describe 'WITH the first value beeing a valid value as a string, and the second beeing a valid value as a string' do
let(:values) { ['0', '1'] }
- let(:old_formatted_value) { format_value(values.first, custom_field.field_format) }
- let(:new_formatted_value) { format_value(values.last, custom_field.field_format) }
+ let(:old_formatted_value) { format_value(values.first, custom_field) }
+ let(:new_formatted_value) { format_value(values.last, custom_field) }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_changed,
label: "#{custom_field.name}",
old: "#{old_formatted_value}",
new: "#{new_formatted_value}")
- }
+ end
it { expect(instance.render(key, values)).to eq(expected) }
end
describe 'WITH the first value beeing a valid value as a string, and the second beeing nil' do
let(:values) { ['0', nil] }
- let(:formatted_value) { format_value(values.first, custom_field.field_format) }
+ let(:formatted_value) { format_value(values.first, custom_field) }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_deleted,
label: "#{custom_field.name}",
old: "#{formatted_value}")
- }
+ end
it { expect(instance.render(key, values)).to eq(expected) }
end
@@ -88,11 +88,11 @@ describe OpenProject::JournalFormatter::CustomField do
WITH no html requested" do
let(:values) { [nil, '1'] }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_set_to,
- label: "#{custom_field.name}",
- value: "#{ format_value(values.last, custom_field.field_format) }")
- }
+ label: custom_field.name,
+ value: format_value(values.last, custom_field))
+ end
it { expect(instance.render(key, values, no_html: true)).to eq(expected) }
end
@@ -101,12 +101,12 @@ describe OpenProject::JournalFormatter::CustomField do
WITH no html requested" do
let(:values) { ['0', '1'] }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_changed,
- label: "#{custom_field.name}",
- old: "#{ format_value(values.first, custom_field.field_format) }",
- new: "#{ format_value(values.last, custom_field.field_format) }")
- }
+ label: custom_field.name,
+ old: format_value(values.first, custom_field),
+ new: format_value(values.last, custom_field))
+ end
it { expect(instance.render(key, values, no_html: true)).to eq(expected) }
end
@@ -115,11 +115,11 @@ describe OpenProject::JournalFormatter::CustomField do
WITH no html requested" do
let(:values) { ['0', nil] }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_deleted,
- label: "#{custom_field.name}",
- old: "#{ format_value(values.first, custom_field.field_format) }")
- }
+ label: custom_field.name,
+ old: format_value(values.first, custom_field))
+ end
it { expect(instance.render(key, values, no_html: true)).to eq(expected) }
end
@@ -129,11 +129,11 @@ describe OpenProject::JournalFormatter::CustomField do
let(:values) { [nil, '1'] }
let(:key) { 'custom_values0' }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_set_to,
label: "#{I18n.t(:label_deleted_custom_field)}",
- value: "#{ values.last }")
- }
+ value: "#{values.last}")
+ end
it { expect(instance.render(key, values)).to eq(expected) }
end
@@ -143,12 +143,12 @@ describe OpenProject::JournalFormatter::CustomField do
let(:values) { ['0', '1'] }
let(:key) { 'custom_values0' }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_changed,
label: "#{I18n.t(:label_deleted_custom_field)}",
- old: "#{ values.first }",
- new: "#{ values.last }")
- }
+ old: "#{values.first}",
+ new: "#{values.last}")
+ end
it { expect(instance.render(key, values)).to eq(expected) }
end
@@ -158,11 +158,11 @@ describe OpenProject::JournalFormatter::CustomField do
let(:values) { ['0', nil] }
let(:key) { 'custom_values0' }
- let(:expected) {
+ let(:expected) do
I18n.t(:text_journal_deleted,
label: "#{I18n.t(:label_deleted_custom_field)}",
- old: "#{ values.first }")
- }
+ old: "#{values.first}")
+ end
it { expect(instance.render(key, values)).to eq(expected) }
end
diff --git a/spec/lib/redmine/custom_field_format_spec.rb b/spec/lib/redmine/custom_field_format_spec.rb
deleted file mode 100644
index 0694ffce5d..0000000000
--- a/spec/lib/redmine/custom_field_format_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-#-- copyright
-# OpenProject is a project management system.
-# Copyright (C) 2012-2017 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-2017 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 Redmine::CustomFieldFormat do
- let(:instance) { described_class.new 'test', label: 'blubs', order: '1' }
-
- describe '#format_value' do
- it 'returns a localized float' do
- I18n.with_locale(:de) do
- expect(instance.format_as_float('5.67')).to eql '5,67'
- end
- end
- end
-end
diff --git a/spec/models/custom_value/bool_strategy_spec.rb b/spec/models/custom_value/bool_strategy_spec.rb
index af4e793784..e9b06c27f3 100644
--- a/spec/models/custom_value/bool_strategy_spec.rb
+++ b/spec/models/custom_value/bool_strategy_spec.rb
@@ -29,6 +29,7 @@
require 'spec_helper'
describe CustomValue::BoolStrategy do
+ let(:instance) { described_class.new(custom_value) }
let(:custom_value) do
double('CustomValue',
value: value)
@@ -64,7 +65,7 @@ describe CustomValue::BoolStrategy do
end
describe '#typed_value' do
- subject { described_class.new(custom_value).typed_value }
+ subject { instance.typed_value }
context 'value corresponds to true' do
let(:value) { '1' }
@@ -97,8 +98,60 @@ describe CustomValue::BoolStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'value is present string' do
+ let(:value) { '1' }
+
+ it 'is the true string' do
+ is_expected.to eql I18n.t(:general_text_Yes)
+ end
+ end
+
+ context 'value is zero string' do
+ let(:value) { '0' }
+
+ it 'is the false string' do
+ is_expected.to eql I18n.t(:general_text_No)
+ end
+ end
+
+ context 'value is true' do
+ let(:value) { true }
+
+ it 'is the true string' do
+ is_expected.to eql I18n.t(:general_text_Yes)
+ end
+ end
+
+ context 'value is false' do
+ let(:value) { false }
+
+ it 'is the false string' do
+ is_expected.to eql I18n.t(:general_text_No)
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is the false string' do
+ is_expected.to eql I18n.t(:general_text_No)
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is the false string' do
+ is_expected.to eql I18n.t(:general_text_No)
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
context 'value corresponds to true' do
let(:value) { '1' }
@@ -130,7 +183,7 @@ describe CustomValue::BoolStrategy do
end
describe '#parse_value' do
- subject { described_class.new(custom_value).parse_value(value) }
+ subject { instance.parse_value(value) }
ActiveRecord::Type::Boolean::FALSE_VALUES.each do |falsey_value|
context "for #{falsey_value}" do
diff --git a/spec/models/custom_value/date_strategy_spec.rb b/spec/models/custom_value/date_strategy_spec.rb
index 1b58c04380..0e40c99934 100644
--- a/spec/models/custom_value/date_strategy_spec.rb
+++ b/spec/models/custom_value/date_strategy_spec.rb
@@ -29,13 +29,14 @@
require 'spec_helper'
describe CustomValue::DateStrategy do
- let(:custom_value) {
+ let(:instance) { described_class.new(custom_value) }
+ let(:custom_value) do
double('CustomValue',
value: value)
- }
+ end
describe '#typed_value' do
- subject { described_class.new(custom_value).typed_value }
+ subject { instance.typed_value }
context 'value is some date string' do
let(:value) { '2015-01-03' }
@@ -53,8 +54,36 @@ describe CustomValue::DateStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'value is some date string' do
+ let(:value) { '2015-01-03' }
+
+ it 'is the date' do
+ is_expected.to eql value
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is a blank string' do
+ is_expected.to eql value
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is a blank string' do
+ is_expected.to eql ''
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
context 'value is valid date string' do
let(:value) { '2015-01-03' }
diff --git a/spec/models/custom_value/float_strategy_spec.rb b/spec/models/custom_value/float_strategy_spec.rb
index 88b4f3fed4..eccca0dae2 100644
--- a/spec/models/custom_value/float_strategy_spec.rb
+++ b/spec/models/custom_value/float_strategy_spec.rb
@@ -29,13 +29,14 @@
require 'spec_helper'
describe CustomValue::FloatStrategy do
- let(:custom_value) {
+ let(:instance) { described_class.new(custom_value) }
+ let(:custom_value) do
double('CustomValue',
value: value)
- }
+ end
describe '#typed_value' do
- subject { described_class.new(custom_value).typed_value }
+ subject { instance.typed_value }
context 'value is some float string' do
let(:value) { '3.14' }
@@ -53,8 +54,42 @@ describe CustomValue::FloatStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'value is some float string' do
+ let(:value) { '3.14' }
+
+ it 'is the float string' do
+ is_expected.to eql value
+ end
+
+ it 'is localized' do
+ I18n.with_locale(:de) do
+ is_expected.to eql '3,14'
+ end
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is a blank string' do
+ is_expected.to eql value
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is a blank string' do
+ is_expected.to eql ''
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
context 'value is float string in decimal notation' do
let(:value) { '3.14' }
diff --git a/spec/models/custom_value/int_strategy_spec.rb b/spec/models/custom_value/int_strategy_spec.rb
index 4097da3156..3674c9fcd6 100644
--- a/spec/models/custom_value/int_strategy_spec.rb
+++ b/spec/models/custom_value/int_strategy_spec.rb
@@ -29,13 +29,14 @@
require 'spec_helper'
describe CustomValue::IntStrategy do
- let(:custom_value) {
+ let(:instance) { described_class.new(custom_value) }
+ let(:custom_value) do
double('CustomValue',
value: value)
- }
+ end
describe '#typed_value' do
- subject { described_class.new(custom_value).typed_value }
+ subject { instance.typed_value }
context 'value is some float string' do
let(:value) { '10' }
@@ -53,8 +54,27 @@ describe CustomValue::IntStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.typed_value }
+
+ context 'value is some int string' do
+ let(:value) { '10' }
+ it { is_expected.to eql(10) }
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+ it { is_expected.to be_nil }
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+ it { is_expected.to be_nil }
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
context 'value is positive int string' do
let(:value) { '10' }
diff --git a/spec/models/custom_value/list_strategy_spec.rb b/spec/models/custom_value/list_strategy_spec.rb
index a661f9d6bb..c71419dcdc 100644
--- a/spec/models/custom_value/list_strategy_spec.rb
+++ b/spec/models/custom_value/list_strategy_spec.rb
@@ -29,6 +29,7 @@
require 'spec_helper'
describe CustomValue::ListStrategy do
+ let(:instance) { described_class.new(custom_value) }
let(:custom_field) { FactoryGirl.create :list_wp_custom_field }
let(:custom_value) do
double("CustomField", value: value, custom_field: custom_field, customized: customized)
@@ -37,7 +38,7 @@ describe CustomValue::ListStrategy do
let(:customized) { double('customized') }
describe '#parse_value/#typed_value' do
- subject { described_class.new(custom_value) }
+ subject { instance }
context 'with a CustomOption' do
let(:value) { custom_field.custom_options.first }
@@ -89,8 +90,49 @@ describe CustomValue::ListStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'with a CustomOption' do
+ let(:value) { custom_field.custom_options.first }
+
+ it 'is the custom option to_s (without db access)' do
+ instance.parse_value(value)
+
+ expect(CustomOption)
+ .to_not receive(:where)
+
+ expect(subject).to eql value.to_s
+ end
+ end
+
+ context 'with an id string' do
+ let(:value) { custom_field.custom_options.first.id.to_s }
+
+ it 'is the custom option to_s (with db access)' do
+ expect(subject).to eql custom_field.custom_options.first.to_s
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is blank' do
+ expect(subject).to eql value
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is blank' do
+ expect(subject).to eql ''
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
context 'value is included' do
let(:value) { custom_field.custom_options.first.id.to_s }
diff --git a/spec/models/custom_value/string_strategy_spec.rb b/spec/models/custom_value/string_strategy_spec.rb
index f9e36fd86c..da9f1786ee 100644
--- a/spec/models/custom_value/string_strategy_spec.rb
+++ b/spec/models/custom_value/string_strategy_spec.rb
@@ -29,13 +29,14 @@
require 'spec_helper'
describe CustomValue::StringStrategy do
- let(:custom_value) {
+ let(:instance) { described_class.new(custom_value) }
+ let(:custom_value) do
double('CustomValue',
value: value)
- }
+ end
describe '#typed_value' do
- subject { described_class.new(custom_value).typed_value }
+ subject { instance.typed_value }
context 'value is some string' do
let(:value) { 'foo bar!' }
@@ -53,8 +54,36 @@ describe CustomValue::StringStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'value is some string' do
+ let(:value) { 'foo bar!' }
+
+ it 'is the string' do
+ is_expected.to eql value
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is a blank string' do
+ is_expected.to eql value
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is a blank string' do
+ is_expected.to eql ''
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
context 'value is some string' do
let(:value) { 'foo bar!' }
diff --git a/spec/models/custom_value/user_strategy_spec.rb b/spec/models/custom_value/user_strategy_spec.rb
index 1cd08e2081..0965211bb5 100644
--- a/spec/models/custom_value/user_strategy_spec.rb
+++ b/spec/models/custom_value/user_strategy_spec.rb
@@ -29,6 +29,7 @@
require 'spec_helper'
describe CustomValue::UserStrategy do
+ let(:instance) { described_class.new(custom_value) }
let(:custom_value) do
double('CustomValue',
value: value,
@@ -40,7 +41,7 @@ describe CustomValue::UserStrategy do
let(:user) { FactoryGirl.build_stubbed(:user) }
describe '#parse_value/#typed_value' do
- subject { described_class.new(custom_value) }
+ subject { instance }
context 'with a user' do
let(:value) { user }
@@ -97,8 +98,54 @@ describe CustomValue::UserStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'with a User' do
+ let(:value) { user }
+
+ it 'is the user to_s (without db access)' do
+ instance.parse_value(value)
+
+ expect(User)
+ .to_not receive(:find_by)
+
+ expect(subject).to eql value.to_s
+ end
+ end
+
+ context 'with an id string' do
+ let(:value) { user.id.to_s }
+
+ it 'is the user to_s (with db access)' do
+ allow(User)
+ .to receive(:find_by)
+ .with(id: user.id.to_s)
+ .and_return(user)
+
+ expect(subject).to eql user.to_s
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is blank and does not look for the user' do
+ expect(subject).to eql ''
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is blank and does not look for the user' do
+ expect(subject).to eql ''
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
let(:allowed_ids) { %w(12 13) }
before do
diff --git a/spec/models/custom_value/version_strategy_spec.rb b/spec/models/custom_value/version_strategy_spec.rb
index 1a9be1c0ec..c421125c1e 100644
--- a/spec/models/custom_value/version_strategy_spec.rb
+++ b/spec/models/custom_value/version_strategy_spec.rb
@@ -29,18 +29,19 @@
require 'spec_helper'
describe CustomValue::VersionStrategy do
- let(:custom_value) {
+ let(:instance) { described_class.new(custom_value) }
+ let(:custom_value) do
double('CustomValue',
value: value,
custom_field: custom_field,
customized: customized)
- }
+ end
let(:customized) { double('customized') }
let(:custom_field) { FactoryGirl.build(:custom_field) }
let(:version) { FactoryGirl.build_stubbed(:version) }
describe '#parse_value/#typed_value' do
- subject { described_class.new(custom_value) }
+ subject { instance }
context 'with a version' do
let(:value) { version }
@@ -97,8 +98,60 @@ describe CustomValue::VersionStrategy do
end
end
+ describe '#formatted_value' do
+ subject { instance.formatted_value }
+
+ context 'with a version' do
+ let(:value) { version }
+
+ it 'is the version to_s (without db access)' do
+ expect(Version)
+ .to_not receive(:find_by)
+
+ instance.parse_value(value)
+
+ is_expected.to eql value.to_s
+ end
+ end
+
+ context 'with an id string' do
+ let(:value) { version.id.to_s }
+
+ it 'is the version to_s (with db access)' do
+ allow(Version)
+ .to receive(:find_by)
+ .with(id: version.id.to_s)
+ .and_return(version)
+
+ is_expected.to eql version.to_s
+ end
+ end
+
+ context 'value is blank' do
+ let(:value) { '' }
+
+ it 'is blank and does not look for the version' do
+ expect(Version)
+ .to_not receive(:find_by)
+
+ is_expected.to eql ''
+ end
+ end
+
+ context 'value is nil' do
+ let(:value) { nil }
+
+ it 'is blank and does not look for the version' do
+ expect(Version)
+ .to_not receive(:find_by)
+
+ is_expected.to eql ''
+ end
+ end
+ end
+
describe '#validate_type_of_value' do
- subject { described_class.new(custom_value).validate_type_of_value }
+ subject { instance.validate_type_of_value }
let(:allowed_ids) { %w(12 13) }
before do
diff --git a/spec_legacy/unit/custom_field_user_format_spec.rb b/spec_legacy/unit/custom_field_user_format_spec.rb
index 7a0ed61313..6d95e37ca0 100644
--- a/spec_legacy/unit/custom_field_user_format_spec.rb
+++ b/spec_legacy/unit/custom_field_user_format_spec.rb
@@ -28,7 +28,7 @@
#++
require 'legacy_spec_helper'
-describe 'CustomFieldFormat' do # TODO: what is this?
+describe 'UserCustomField' do
before do
@project = FactoryGirl.create :valid_project
role = FactoryGirl.create :role, permissions: [:view_work_packages, :edit_work_packages]