diff --git a/app/controllers/admin/features_controller.rb b/app/controllers/admin/features_controller.rb
index 3892443..22566e3 100644
--- a/app/controllers/admin/features_controller.rb
+++ b/app/controllers/admin/features_controller.rb
@@ -1,5 +1,6 @@
class FeaturesController < AdminController
protect 'edit_environment_features', :environment
+ helper CustomFieldsHelper
def index
@features = Environment.available_features.sort_by{|k,v|v}
@@ -51,6 +52,34 @@ class FeaturesController < AdminController
redirect_to :action => 'manage_fields'
end
+ def manage_custom_fields
+ custom_field_list = params[:custom_fields] || {}
+
+ custom_fields_to_destroy =
+ params[:customized_type].constantize.custom_fields(environment).map(&:id) - custom_field_list.keys.map(&:to_i)
+ CustomField.destroy(custom_fields_to_destroy)
+
+ custom_field_list.each_pair do |id, custom_field|
+ field = CustomField.find_by_id(id)
+ if not field.blank?
+ params_to_update = custom_field.except(:format, :extras, :customized_type,:environment)
+ field.update_attributes(params_to_update)
+ else
+ if !custom_field[:extras].nil?
+ tmp = []
+ custom_field[:extras].each_pair do |k, v|
+ tmp << v
+ end
+ custom_field[:extras] = tmp
+ end
+ field = CustomField.new custom_field.except(:environment)
+ field.environment=environment
+ field.save if field.valid?
+ end
+ end
+ redirect_to :action => 'manage_fields'
+ end
+
def search_members
arg = params[:q].downcase
result = environment.people.where('LOWER(name) LIKE ? OR identifier LIKE ?', "%#{arg}%", "%#{arg}%")
diff --git a/app/controllers/my_profile/memberships_controller.rb b/app/controllers/my_profile/memberships_controller.rb
index c52e24b..a29b90c 100644
--- a/app/controllers/my_profile/memberships_controller.rb
+++ b/app/controllers/my_profile/memberships_controller.rb
@@ -1,6 +1,7 @@
class MembershipsController < MyProfileController
protect 'manage_memberships', :profile
+ helper CustomFieldsHelper
def index
@roles = environment.roles.select do |role|
diff --git a/app/controllers/my_profile/profile_editor_controller.rb b/app/controllers/my_profile/profile_editor_controller.rb
index 316a4e4..46b2c0c 100644
--- a/app/controllers/my_profile/profile_editor_controller.rb
+++ b/app/controllers/my_profile/profile_editor_controller.rb
@@ -8,6 +8,7 @@ class ProfileEditorController < MyProfileController
before_filter :forbid_destroy_profile, :only => [:destroy_profile]
before_filter :check_user_can_edit_header_footer, :only => [:header_footer]
helper_method :has_welcome_page
+ helper CustomFieldsHelper
def index
@pending_tasks = Task.to(profile).pending.without_spam.select{|i| user.has_permission?(i.permission, profile)}
diff --git a/app/controllers/public/account_controller.rb b/app/controllers/public/account_controller.rb
index acf884b..0e5457b 100644
--- a/app/controllers/public/account_controller.rb
+++ b/app/controllers/public/account_controller.rb
@@ -6,6 +6,7 @@ class AccountController < ApplicationController
before_filter :redirect_if_logged_in, :only => [:login, :signup]
before_filter :protect_from_bots, :only => :signup
+ helper CustomFieldsHelper
# say something nice, you goof! something sweet.
def index
unless logged_in?
diff --git a/app/controllers/public/profile_controller.rb b/app/controllers/public/profile_controller.rb
index 9c72b65..29fffad 100644
--- a/app/controllers/public/profile_controller.rb
+++ b/app/controllers/public/profile_controller.rb
@@ -7,6 +7,7 @@ class ProfileController < PublicController
helper TagsHelper
helper ActionTrackerHelper
+ helper CustomFieldsHelper
protect 'send_mail_to_members', :profile, :only => [:send_mail]
diff --git a/app/helpers/custom_fields_helper.rb b/app/helpers/custom_fields_helper.rb
new file mode 100644
index 0000000..fff9a2f
--- /dev/null
+++ b/app/helpers/custom_fields_helper.rb
@@ -0,0 +1,58 @@
+module CustomFieldsHelper
+
+ def format_name(format)
+ names = {}
+ names['string'] = _('String')
+ names['text'] = _('Text')
+ names['date'] = _('Date')
+ names['numeric'] = _('Numeric')
+ names['link'] = _('Link')
+ names['list'] = _('List')
+ names['checkbox'] = _('Checkbox')
+ names[format]
+ end
+
+ def custom_field_forms(customized_type)
+ forms = []
+ forms << [_('String'), form_for_format(customized_type,'string')]
+ forms << [_('Text'), form_for_format(customized_type,'text')]
+ forms << [_('Date'), form_for_format(customized_type,'date')]
+ forms << [_('Numeric'), form_for_format(customized_type,'numeric')]
+ forms << [_('Link'), form_for_format(customized_type,'link')]
+ forms << [_('List'), form_for_format(customized_type,'list')]
+ forms << [_('Checkbox'), form_for_format(customized_type,'checkbox')]
+ forms
+ end
+
+ def render_extras_field(id, extra=nil, field=nil)
+ if extra.nil?
+ CGI::escapeHTML((render(:partial => 'features/custom_fields/extras_field', :locals => {:id => id, :extra => nil, :field => field})))
+ else
+ render :partial => 'features/custom_fields/extras_field', :locals => {:id => id, :extra => extra, :field => field}
+ end
+ end
+
+ def form_for_field(field, customized_type)
+ render :partial => 'features/custom_fields/form', :locals => {:field => field}
+ end
+
+ def display_custom_field_value(custom_field_value)
+ value = profile.custom_value(custom_field_value.custom_field.name)
+ case custom_field_value.custom_field.format
+ when 'text', 'list', 'numeric', 'date', 'string'
+ value
+ when 'checkbox'
+ value == "1" ? _('Yes') : _('No')
+ when 'link'
+ url = value[/\Ahttps?:\/\//i] ? value : "http://#{value}"
+ link_to(value, url, :target => '_blank')
+ end
+ end
+
+ private
+
+ def form_for_format(customized_type, format)
+ field = CustomField.new(:format => format, :customized_type => customized_type, :environment => environment)
+ CGI::escapeHTML((render(:partial => 'features/custom_fields/form', :locals => {:field => field})))
+ end
+end
diff --git a/app/helpers/forms_helper.rb b/app/helpers/forms_helper.rb
index 672fbcd..7f04574 100644
--- a/app/helpers/forms_helper.rb
+++ b/app/helpers/forms_helper.rb
@@ -186,6 +186,7 @@ module FormsHelper
element_id = html_options[:id] || 'datepicker-date'
value = value.strftime(format) if value.present?
method = datepicker_options[:time] ? 'datetimepicker' : 'datepicker'
+ current_date_or_nil = value.present? ? "new Date('#{value}')" : "null"
result = text_field_tag(name, value, html_options)
result +=
"
@@ -236,7 +237,7 @@ module FormsHelper
weekHeader: #{datepicker_options[:week_header].to_json},
yearRange: #{datepicker_options[:year_range].to_json},
yearSuffix: #{datepicker_options[:year_suffix].to_json}
- }).datepicker('setDate', new Date('#{value}'))
+ }).datepicker('setDate', current_date_or_nil)
".html_safe
result
diff --git a/app/models/community.rb b/app/models/community.rb
index a604884..aa45ea7 100644
--- a/app/models/community.rb
+++ b/app/models/community.rb
@@ -29,7 +29,7 @@ class Community < Organization
# places that call this method are safe from mass-assignment by setting the
# environment key themselves.
def self.create_after_moderation(requestor, attributes = {})
- environment = attributes.delete(:environment)
+ environment = attributes[:environment]
community = Community.new(attributes)
community.environment = environment
if community.environment.enabled?('admin_must_approve_new_communities')
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
new file mode 100644
index 0000000..015d8d2
--- /dev/null
+++ b/app/models/custom_field.rb
@@ -0,0 +1,34 @@
+class CustomField < ActiveRecord::Base
+ attr_accessible :name, :default_value, :format, :extras, :customized_type, :active, :required, :signup, :environment
+ serialize :customized_type
+ serialize :extras
+ has_many :custom_field_values, :dependent => :delete_all
+ belongs_to :environment
+
+ validates_presence_of :name, :format, :customized_type, :environment
+ validate :related_to_other?
+ validate :unique?
+
+ def unique?
+ if environment.custom_fields.any?{|cf| cf.name==name && cf.environment == environment && cf.customized_type==customized_type && new_record?}
+ errors.add(:body, N_("There is a field with the same name for this type in this environment"))
+ return false
+ end
+ true
+ end
+
+ def related_to_other?
+ environment.custom_fields.any? do |cf|
+ if cf.name == name && cf.customized_type != customized_type
+ ancestor = cf.customized_type.constantize < customized_type.constantize
+ descendant = cf.customized_type.constantize > customized_type.constantize
+ if ancestor || descendant
+ errors.add(:body, N_("New field related to existent one with same name"))
+ return false
+ end
+ end
+ end
+ true
+ end
+end
+
diff --git a/app/models/custom_field_value.rb b/app/models/custom_field_value.rb
new file mode 100644
index 0000000..cf776ad
--- /dev/null
+++ b/app/models/custom_field_value.rb
@@ -0,0 +1,14 @@
+class CustomFieldValue < ActiveRecord::Base
+ belongs_to :custom_field
+ belongs_to :customized, :polymorphic => true
+ attr_accessible :value, :public, :customized, :custom_field, :customized_type
+ validate :can_save?
+
+ def can_save?
+ if value.blank? && custom_field.required
+ errors.add(custom_field.name, _("can't be blank"))
+ return false
+ end
+ return true
+ end
+end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 5154648..28b780d 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -24,6 +24,7 @@ class Environment < ActiveRecord::Base
has_many :tasks, :dependent => :destroy, :as => 'target'
has_many :search_terms, :as => :context
+ has_many :custom_fields, :dependent => :destroy
IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/
diff --git a/app/models/profile.rb b/app/models/profile.rb
index e4d57ff..3439925 100644
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -84,6 +84,7 @@ class Profile < ActiveRecord::Base
}
acts_as_accessible
+ acts_as_customizable
include Noosfero::Plugin::HotSpot
diff --git a/app/views/account/_signup_form.html.erb b/app/views/account/_signup_form.html.erb
index 28690e3..49c08d1 100644
--- a/app/views/account/_signup_form.html.erb
+++ b/app/views/account/_signup_form.html.erb
@@ -126,6 +126,7 @@
<%= recaptcha_tags :ajax => true, :display => {:theme => 'clean'} if @block_bot %>
+<%= render :partial => 'shared/custom_fields', :locals => {:f => f, :profile => @person, :signup => true} %>
<%= submit_button('save', _('Create my account')) %>
diff --git a/app/views/custom_fields/_checkbox.html.erb b/app/views/custom_fields/_checkbox.html.erb
new file mode 100644
index 0000000..04010d2
--- /dev/null
+++ b/app/views/custom_fields/_checkbox.html.erb
@@ -0,0 +1 @@
+<%= labelled_check_box(field.name, name, 1, profile.custom_value(field.name) == '1' )%>
diff --git a/app/views/custom_fields/_date.html.erb b/app/views/custom_fields/_date.html.erb
new file mode 100644
index 0000000..95bd803
--- /dev/null
+++ b/app/views/custom_fields/_date.html.erb
@@ -0,0 +1 @@
+<%= labelled_form_field(field.name, date_field(name, profile.custom_value(field.name).to_date, '%Y-%m-%d', {:change_month => true, :change_year => true, :year_range => '-100:-5', :date_format => 'yy-mm-dd'}, {:id => field.name.parameterize.underscore}))%>
diff --git a/app/views/custom_fields/_link.html.erb b/app/views/custom_fields/_link.html.erb
new file mode 100644
index 0000000..898fe48
--- /dev/null
+++ b/app/views/custom_fields/_link.html.erb
@@ -0,0 +1 @@
+<%= render :partial => "custom_fields/string", :locals => {:field => field, :profile => profile, :name => name} %>
diff --git a/app/views/custom_fields/_list.html.erb b/app/views/custom_fields/_list.html.erb
new file mode 100644
index 0000000..05203cb
--- /dev/null
+++ b/app/views/custom_fields/_list.html.erb
@@ -0,0 +1,2 @@
+<%= label_tag field.name, nil, class: 'formlabel'%>
+<%= select_tag name, options_for_select(field.extras.map{|v| [v,v]}, profile.custom_value(field.name)), {:prompt => _('[Select ...]') } %>
diff --git a/app/views/custom_fields/_numeric.html.erb b/app/views/custom_fields/_numeric.html.erb
new file mode 100644
index 0000000..cb842d8
--- /dev/null
+++ b/app/views/custom_fields/_numeric.html.erb
@@ -0,0 +1 @@
+<%= labelled_form_field field.name, number_field_tag(name,profile.custom_value(field.name))%>
diff --git a/app/views/custom_fields/_string.html.erb b/app/views/custom_fields/_string.html.erb
new file mode 100644
index 0000000..720aa3b
--- /dev/null
+++ b/app/views/custom_fields/_string.html.erb
@@ -0,0 +1 @@
+<%= labelled_form_field field.name, text_field_tag(name, profile.custom_value(field.name), :size => 30) %>
diff --git a/app/views/custom_fields/_text.html.erb b/app/views/custom_fields/_text.html.erb
new file mode 100644
index 0000000..e6d2bef
--- /dev/null
+++ b/app/views/custom_fields/_text.html.erb
@@ -0,0 +1 @@
+<%= labelled_form_field field.name, text_area_tag(name,profile.custom_value(field.name), :rows => 5, :cols => 40)%>
diff --git a/app/views/features/_manage_community_fields.html.erb b/app/views/features/_manage_community_fields.html.erb
index 9cb0ebe..cd34387 100644
--- a/app/views/features/_manage_community_fields.html.erb
+++ b/app/views/features/_manage_community_fields.html.erb
@@ -63,6 +63,4 @@
<% end %>
-
-
-
+<%= render :partial => "manage_custom_fields", :locals => {:customized_type => Community} %>
diff --git a/app/views/features/_manage_custom_fields.html.erb b/app/views/features/_manage_custom_fields.html.erb
new file mode 100644
index 0000000..d035bda
--- /dev/null
+++ b/app/views/features/_manage_custom_fields.html.erb
@@ -0,0 +1,29 @@
+
<%= _("Custom Fields") %>
+
+<% form_id = "#{customized_type.to_s.downcase}-custom-fields-form" %>
+<% fields_id = "#{customized_type.to_s.downcase}-custom-fields" %>
+<% format_values_id = "#{customized_type.to_s.downcase}-formats" %>
+
+<%= form_tag({:action => 'manage_custom_fields'}, :id => "#{form_id}") do %>
+
+<%= hidden_field_tag 'customized_type', customized_type.to_s %>
+
+
+ <% customized_type.custom_fields(environment).each do |field|%>
+ <%= form_for_field(field, customized_type.to_s) %>
+ <% end %>
+
+
+
+
+
+
+<% button_bar do %>
+ <%= button(:save, _('Save'), 'javascript: void()', :onClick => "submit_custom_field_form('##{format_values_id}', '##{form_id}');") %>
+<% end %>
+
+<% end %>
diff --git a/app/views/features/_manage_enterprise_fields.html.erb b/app/views/features/_manage_enterprise_fields.html.erb
index a8840bb..53d086e 100644
--- a/app/views/features/_manage_enterprise_fields.html.erb
+++ b/app/views/features/_manage_enterprise_fields.html.erb
@@ -63,6 +63,4 @@
<% end %>
-
-
-
+<%= render :partial => "manage_custom_fields", :locals => {:customized_type => Enterprise} %>
diff --git a/app/views/features/_manage_person_fields.html.erb b/app/views/features/_manage_person_fields.html.erb
index 1d6eddf..18a9e84 100644
--- a/app/views/features/_manage_person_fields.html.erb
+++ b/app/views/features/_manage_person_fields.html.erb
@@ -60,9 +60,7 @@
<%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
<% end %>
-
+
<% end %>
-
-
-
+<%= render :partial => "manage_custom_fields", :locals => {:customized_type => Person} %>
diff --git a/app/views/features/custom_fields/_extras_field.html.erb b/app/views/features/custom_fields/_extras_field.html.erb
new file mode 100644
index 0000000..cf1aa99
--- /dev/null
+++ b/app/views/features/custom_fields/_extras_field.html.erb
@@ -0,0 +1,15 @@
+<% field_id = extra.nil? ? 'EXTRAS_ID' : "#{Time.now.usec}" %>
+<% def_value = field.nil? ? '' : field.default_value%>
+
diff --git a/app/views/features/custom_fields/_form.html.erb b/app/views/features/custom_fields/_form.html.erb
new file mode 100644
index 0000000..56f0cba
--- /dev/null
+++ b/app/views/features/custom_fields/_form.html.erb
@@ -0,0 +1,43 @@
+<% id = field.new_record? ? "NEW_FIELD_ID" : field.id %>
+
+
+
+
diff --git a/app/views/features/custom_fields/_view.html.erb b/app/views/features/custom_fields/_view.html.erb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/views/features/custom_fields/_view.html.erb
diff --git a/app/views/features/custom_fields/edit.html.erb b/app/views/features/custom_fields/edit.html.erb
new file mode 100644
index 0000000..b4b8bbd
--- /dev/null
+++ b/app/views/features/custom_fields/edit.html.erb
@@ -0,0 +1 @@
+<%= render :partial => 'features/custom_fields/form' %>
diff --git a/app/views/features/custom_fields/new.html.erb b/app/views/features/custom_fields/new.html.erb
new file mode 100644
index 0000000..b4b8bbd
--- /dev/null
+++ b/app/views/features/custom_fields/new.html.erb
@@ -0,0 +1 @@
+<%= render :partial => 'features/custom_fields/form' %>
diff --git a/app/views/memberships/new_community.html.erb b/app/views/memberships/new_community.html.erb
index 21017c0..338a0ac 100644
--- a/app/views/memberships/new_community.html.erb
+++ b/app/views/memberships/new_community.html.erb
@@ -13,7 +13,6 @@
<%= labelled_form_for :community, :html => { :multipart => true } do |f| %>
<%= required_fields_message %>
-
<%= required f.text_field(:name) %>
<% @plugins.dispatch(:new_community_hidden_fields).each do |field| %>
@@ -23,6 +22,7 @@
<% end %>
<%= render :partial => 'shared/organization_custom_fields', :locals => { :f => f, :object_name => 'community', :profile => @community } %>
+ <%= render :partial => 'shared/custom_fields', :locals => { :f => f, :profile => @community, :signup => true } %>
<%= f.fields_for :image_builder, @community.image do |i| %>
<%= file_field_or_thumbnail(_('Image:'), @community.image, i) %>
@@ -56,7 +56,3 @@
<% end %>
-
-
-
-
diff --git a/app/views/profile/_custom_fields.html.erb b/app/views/profile/_custom_fields.html.erb
new file mode 100644
index 0000000..4b0e968
--- /dev/null
+++ b/app/views/profile/_custom_fields.html.erb
@@ -0,0 +1,11 @@
+<% public_values = profile.public_values %>
+<% if !public_values.blank?%>
+ <%= _('Others') %> |
+ <% profile.public_values.each do |cv|%>
+
+ <%= cv.custom_field.name %> |
+ <%= display_custom_field_value(cv) %> |
+
+ <% end%>
+<% end %>
+
diff --git a/app/views/profile/_organization_profile.html.erb b/app/views/profile/_organization_profile.html.erb
index 872abff..a7c5f02 100644
--- a/app/views/profile/_organization_profile.html.erb
+++ b/app/views/profile/_organization_profile.html.erb
@@ -3,4 +3,5 @@
<%= display_contact %>
<%= display_economic %>
<%= render :partial => 'common' %>
+ <%= render :partial => 'custom_fields' %>
diff --git a/app/views/profile/_person_profile.html.erb b/app/views/profile/_person_profile.html.erb
index 4048420..b4c7e3a 100644
--- a/app/views/profile/_person_profile.html.erb
+++ b/app/views/profile/_person_profile.html.erb
@@ -10,5 +10,6 @@
<%= render :partial => 'common' %>
<% end %>
-
+ <%= render :partial => 'custom_fields'%>
+
diff --git a/app/views/profile_editor/_organization.html.erb b/app/views/profile_editor/_organization.html.erb
index 2c2f548..eef4357 100644
--- a/app/views/profile_editor/_organization.html.erb
+++ b/app/views/profile_editor/_organization.html.erb
@@ -61,6 +61,7 @@
<% end %>
<%= render :partial => 'shared/organization_custom_fields', :locals => { :f => f, :object_name => 'profile_data', :profile => @profile } %>
+<%= render :partial => 'shared/custom_fields', :locals => {:f => f, :profile => @profile, :editing_profile => true} %>
<%= labelled_check_box(_('Enable "contact us"'), 'profile_data[enable_contact_us]', "1", @profile.enable_contact_us) if @profile.enterprise? %>
diff --git a/app/views/profile_editor/_person.html.erb b/app/views/profile_editor/_person.html.erb
index 0636f8a..f7858a9 100644
--- a/app/views/profile_editor/_person.html.erb
+++ b/app/views/profile_editor/_person.html.erb
@@ -27,6 +27,7 @@
<%= link_to("Reset token", {:controller => :profile_editor, :action => :reset_private_token, :id => @profile.id}, :class => "button with-text") %>
<%= render :partial => 'person_form', :locals => {:f => f} %>
+ <%= render :partial => 'shared/custom_fields', :locals => {:f => f, :profile => @profile, :editing_profile => true} %>
<%= _('Notification options') %>
diff --git a/app/views/shared/_custom_fields.html.erb b/app/views/shared/_custom_fields.html.erb
new file mode 100644
index 0000000..e67306a
--- /dev/null
+++ b/app/views/shared/_custom_fields.html.erb
@@ -0,0 +1,25 @@
+<% if signup ||= false %>
+ <% fields = profile.class.signup_custom_fields environment%>
+<% else %>
+ <% fields = profile.class.active_custom_fields environment%>
+<% end %>
+<% editing_profile ||= false %>
+<% fields.each do |field| %>
+ <% rendered = render(:partial => "custom_fields/#{field.format}", :locals => {:field => field, :profile => profile, :name => "profile_data[custom_values[#{field.name}[value]]]"})%>
+
+
+ <% if field.required%>
+ <%= required rendered%>
+ <% else %>
+ <%= rendered %>
+ <% end %>
+
+ <% if editing_profile %>
+
+ <%= labelled_check_box(_('Public'),"profile_data[custom_values[#{field.name}[public]]]", "true", profile.is_public(field.name))%>
+
+ <% end %>
+
+
+<% end %>
+
diff --git a/app/views/shared/_organization_custom_fields.html.erb b/app/views/shared/_organization_custom_fields.html.erb
index 5b19eb8..ea7ad18 100644
--- a/app/views/shared/_organization_custom_fields.html.erb
+++ b/app/views/shared/_organization_custom_fields.html.erb
@@ -29,4 +29,7 @@
<%= optional_field(profile, 'acronym', f.text_field(:acronym)) %>
<%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %>
<% end %>
+
+<%= render :partial => 'shared/custom_fields', :locals => {:f => f, :profile => profile, :signup => true} %>
+
<%= javascript_include_tag('city_state_validation') %>
diff --git a/config/initializers/dependencies.rb b/config/initializers/dependencies.rb
index cbdd65d..0a38bb0 100644
--- a/config/initializers/dependencies.rb
+++ b/config/initializers/dependencies.rb
@@ -18,6 +18,7 @@ require 'acts_as_having_settings'
require 'acts_as_having_boxes'
require 'acts_as_having_image'
require 'acts_as_having_posts'
+require 'acts_as_customizable'
require 'route_if'
require 'maybe_add_http'
require 'set_profile_region_from_city_state'
diff --git a/db/migrate/20150921140802_create_custom_fields.rb b/db/migrate/20150921140802_create_custom_fields.rb
new file mode 100644
index 0000000..1e53a4f
--- /dev/null
+++ b/db/migrate/20150921140802_create_custom_fields.rb
@@ -0,0 +1,31 @@
+class CreateCustomFields < ActiveRecord::Migration
+ def change
+ create_table :custom_fields do |t|
+ t.string :name
+ t.string :format, :default => ""
+ t.text :default_value, :default => ""
+ t.string :customized_type
+ t.text :extras, :default => ""
+ t.boolean :active, :default => false
+ t.boolean :required, :default => false
+ t.boolean :signup, :default => false
+ t.integer :environment_id
+ t.timestamps
+ end
+
+ create_table :custom_field_values do |t|
+ t.column "customized_type", :string, :default => "", :null => false
+ t.column "customized_id", :integer, :default => 0, :null => false
+ t.column "public", :boolean, :default => false, :null => false
+ t.column "custom_field_id", :integer, :default => 0, :null => false
+ t.column "value", :text, :default => ""
+ t.timestamps
+ end
+
+
+ add_index :custom_field_values, ["customized_type", "customized_id","custom_field_id"], :unique => true, :name => 'index_custom_field_values'
+ add_index :custom_fields, ["customized_type","name","environment_id"], :unique => true, :name => 'index_custom_field'
+
+ end
+end
+
diff --git a/lib/acts_as_customizable.rb b/lib/acts_as_customizable.rb
new file mode 100644
index 0000000..6d9db36
--- /dev/null
+++ b/lib/acts_as_customizable.rb
@@ -0,0 +1,125 @@
+module Customizable
+
+ def self.included(base)
+ base.attr_accessible :custom_values
+ base.extend ClassMethods
+ end
+
+ module ClassMethods
+ def acts_as_customizable(options = {})
+ attr_accessor :custom_values
+ has_many :custom_field_values, :dependent => :delete_all, :as => :customized
+ send :include, Customizable::InstanceMethods
+ after_save :save_custom_values
+ validate :valid_custom_values?
+ end
+
+ def active_custom_fields environment
+ environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.active}
+ end
+
+ def required_custom_fields environment
+ environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.required}
+ end
+
+ def signup_custom_fields environment
+ environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.signup}
+ end
+
+ def custom_fields environment
+ environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type)}
+ end
+
+ def customized_ancestors_list
+ current=self
+ result=[]
+ while current.instance_methods.include? :custom_value do
+ result << current.name
+ current=current.superclass
+ end
+ result
+ end
+
+ end
+
+ module InstanceMethods
+
+ def valid_custom_values?
+ is_valid = true
+ parse_custom_values.each do |cv|
+ unless cv.valid?
+ name = cv.custom_field.name
+ errors.add(name, cv.errors.messages[name.to_sym].first)
+ is_valid = false
+ end
+ end
+ is_valid
+ end
+
+ def customized_class
+ current=self.class
+ while current.instance_methods.include? :custom_fields do
+ result=current
+ current=current.superclass
+ end
+ result.name
+ end
+
+ def is_public(field_name)
+ cv = self.custom_field_values.detect{|cv| cv.custom_field.name==field_name}
+ cv.nil? ? false : cv.public
+ end
+
+ def public_values
+ self.custom_field_values.select{|cv| cv.public}
+ end
+
+ def custom_value(field_name)
+ cv = self.custom_field_values.detect{|cv| cv.custom_field.name==field_name}
+ cv.nil? ? default_value_for(field_name) : cv.value
+ end
+
+ def default_value_for(field_name)
+ field=self.class.custom_fields(environment).detect {|c| c.name == field_name}
+ field.nil? ? nil : field.default_value
+ end
+
+ def parse_custom_values
+ return_list = []
+ return return_list if custom_values.blank?
+ custom_values.each_pair do |key, value|
+ custom_field = environment.custom_fields.detect{|cf|cf.name==key}
+ next if custom_field.blank?
+ custom_field_value = self.custom_field_values.detect{|cv| cv.custom_field.name==key}
+
+ if custom_field_value.nil?
+ custom_field_value = CustomFieldValue.new
+ custom_field_value.custom_field = custom_field
+ custom_field_value.customized = self
+ end
+
+ if value.is_a?(Hash)
+ custom_field_value.value = value['value'].to_s
+ if value.has_key?('public')
+ is_public = value['public']=="true" || value['public']==true
+ custom_field_value.public = is_public
+ else
+ custom_field_value.public = false
+ end
+ else
+ custom_field_value.value = value.to_s
+ custom_field_value.public = false
+ end
+ return_list << custom_field_value
+ end
+ return_list
+ end
+
+ def save_custom_values
+ parse_custom_values.each(&:save)
+ end
+
+ end
+end
+
+ActiveRecord::Base.send(:include, Customizable)
diff --git a/lib/noosfero/api/entities.rb b/lib/noosfero/api/entities.rb
index 8281cb3..7e20b05 100644
--- a/lib/noosfero/api/entities.rb
+++ b/lib/noosfero/api/entities.rb
@@ -15,7 +15,7 @@ module Noosfero
}
def self.can_display? profile, options, field, permission = :friend
- return true if profile.public_fields.include?(field)
+ return true if profile.public_fields.map{|f| f.to_sym}.include?(field.to_sym)
current_person = options[:current_person]
current_permission = if current_person.present?
@@ -31,7 +31,6 @@ module Noosfero
else
:anonymous
end
-
PERMISSIONS[current_permission] <= PERMISSIONS[permission]
end
@@ -84,6 +83,20 @@ module Noosfero
expose :identifier, :name, :id
expose :created_at, :format_with => :timestamp
expose :updated_at, :format_with => :timestamp
+ expose :additional_data do |profile, options|
+ hash ={}
+ profile.public_values.each do |value|
+ hash[value.custom_field.name]=value.value
+ end
+
+ private_values = profile.custom_field_values - profile.public_values
+ private_values.each do |value|
+ if Entities.can_display?(profile,options,:custom_field)
+ hash[value.custom_field.name]=value.value
+ end
+ end
+ hash
+ end
expose :image, :using => Image
expose :region, :using => Region
end
diff --git a/lib/noosfero/api/v1/comments.rb b/lib/noosfero/api/v1/comments.rb
index edbcba8..e64c65a 100644
--- a/lib/noosfero/api/v1/comments.rb
+++ b/lib/noosfero/api/v1/comments.rb
@@ -18,12 +18,12 @@ module Noosfero
article = find_article(environment.articles, params[:id])
comments = select_filtered_collection_of(article, :comments, params)
- present comments, :with => Entities::Comment
+ present comments, :with => Entities::Comment, :current_person => current_person
end
get ":id/comments/:comment_id" do
article = find_article(environment.articles, params[:id])
- present article.comments.find(params[:comment_id]), :with => Entities::Comment
+ present article.comments.find(params[:comment_id]), :with => Entities::Comment, :current_person => current_person
end
# Example Request:
@@ -31,7 +31,7 @@ module Noosfero
post ":id/comments" do
article = find_article(environment.articles, params[:id])
options = params.select { |key,v| !['id','private_token'].include?(key) }.merge(:author => current_person, :source => article)
- present Comment.create(options), :with => Entities::Comment
+ present Comment.create(options), :with => Entities::Comment, :current_person => current_person
end
end
diff --git a/lib/noosfero/api/v1/communities.rb b/lib/noosfero/api/v1/communities.rb
index 0c99150..ead1e51 100644
--- a/lib/noosfero/api/v1/communities.rb
+++ b/lib/noosfero/api/v1/communities.rb
@@ -20,14 +20,21 @@ module Noosfero
communities = select_filtered_collection_of(environment, 'communities', params)
communities = communities.visible_for_person(current_person)
communities = communities.by_location(params) # Must be the last. May return Exception obj.
- present communities, :with => Entities::Community
+ present communities, :with => Entities::Community, :current_person => current_person
end
# Example Request:
# POST api/v1/communties?private_token=234298743290432&community[name]=some_name
+ # for each custom field for community, add &community[field_name]=field_value to the request
post do
params[:community] ||= {}
+
+ params[:community][:custom_values]={}
+ params[:community].keys.each do |key|
+ params[:community][:custom_values][key]=params[:community].delete(key) if Community.custom_fields(environment).any?{|cf| cf.name==key}
+ end
+
begin
community = Community.create_after_moderation(current_person, params[:community].merge({:environment => environment}))
rescue
@@ -38,12 +45,12 @@ module Noosfero
render_api_errors!(community.errors.full_messages)
end
- present community, :with => Entities::Community
+ present community, :with => Entities::Community, :current_person => current_person
end
get ':id' do
community = environment.communities.visible_for_person(current_person).find_by_id(params[:id])
- present community, :with => Entities::Community
+ present community, :with => Entities::Community, :current_person => current_person
end
end
@@ -58,7 +65,7 @@ module Noosfero
person = environment.people.find(params[:person_id])
communities = select_filtered_collection_of(person, 'communities', params)
communities = communities.visible
- present communities, :with => Entities::Community
+ present communities, :with => Entities::Community, :current_person => current_person
end
end
diff --git a/lib/noosfero/api/v1/enterprises.rb b/lib/noosfero/api/v1/enterprises.rb
index aba1e6f..fea8475 100644
--- a/lib/noosfero/api/v1/enterprises.rb
+++ b/lib/noosfero/api/v1/enterprises.rb
@@ -21,13 +21,13 @@ module Noosfero
enterprises = select_filtered_collection_of(environment, 'enterprises', params)
enterprises = enterprises.visible_for_person(current_person)
enterprises = enterprises.by_location(params) # Must be the last. May return Exception obj.
- present enterprises, :with => Entities::Enterprise
+ present enterprises, :with => Entities::Enterprise, :current_person => current_person
end
desc "Return one enterprise by id"
get ':id' do
enterprise = environment.enterprises.visible_for_person(current_person).find_by_id(params[:id])
- present enterprise, :with => Entities::Enterprise
+ present enterprise, :with => Entities::Enterprise, :current_person => current_person
end
end
@@ -42,7 +42,7 @@ module Noosfero
person = environment.people.find(params[:person_id])
enterprises = select_filtered_collection_of(person, 'enterprises', params)
enterprises = enterprises.visible.by_location(params)
- present enterprises, :with => Entities::Enterprise
+ present enterprises, :with => Entities::Enterprise, :current_person => current_person
end
end
diff --git a/lib/noosfero/api/v1/people.rb b/lib/noosfero/api/v1/people.rb
index bf13ea1..f6d21a3 100644
--- a/lib/noosfero/api/v1/people.rb
+++ b/lib/noosfero/api/v1/people.rb
@@ -33,30 +33,31 @@ module Noosfero
get do
people = select_filtered_collection_of(environment, 'people', params)
people = people.visible_for_person(current_person)
- present people, :with => Entities::Person
+ present people, :with => Entities::Person, :current_person => current_person
end
desc "Return the logged user information"
get "/me" do
- present current_person, :with => Entities::Person
+ present current_person, :with => Entities::Person, :current_person => current_person
end
desc "Return the person information"
get ':id' do
person = environment.people.visible_for_person(current_person).find_by_id(params[:id])
return not_found! if person.blank?
- present person, :with => Entities::Person
+ present person, :with => Entities::Person, :current_person => current_person
end
desc "Update person information"
post ':id' do
return forbidden! if current_person.id.to_s != params[:id]
current_person.update_attributes!(params[:person])
- present current_person, :with => Entities::Person
+ present current_person, :with => Entities::Person, :current_person => current_person
end
# Example Request:
# POST api/v1/people?person[login]=some_login&person[password]=some_password&person[name]=Jack
+ # for each custom field for person, add &person[field_name]=field_value to the request
desc "Create person"
post do
user_data = {}
@@ -64,14 +65,21 @@ module Noosfero
user_data[:email] = params[:person].delete(:email)
user_data[:password] = params[:person].delete(:password)
user_data[:password_confirmation] = params[:person].delete(:password_confirmation)
+
+ params[:person][:custom_values]={}
+ params[:person].keys.each do |key|
+ params[:person][:custom_values][key]=params[:person].delete(key) if Person.custom_fields(environment).any?{|cf| cf.name==key}
+ end
+
user = User.build(user_data, params[:person], environment)
+
begin
user.signup!
rescue ActiveRecord::RecordInvalid
render_api_errors!(user.errors.full_messages)
end
- present user.person, :with => Entities::Person
+ present user.person, :with => Entities::Person, :current_person => user.person
end
desc "Return the person friends"
@@ -79,7 +87,7 @@ module Noosfero
person = environment.people.visible_for_person(current_person).find_by_id(params[:id])
return not_found! if person.blank?
friends = person.friends.visible
- present friends, :with => Entities::Person
+ present friends, :with => Entities::Person, :current_person => current_person
end
desc "Return the person permissions on other profiles"
diff --git a/public/javascripts/manage-fields.js b/public/javascripts/manage-fields.js
index 9c0b678..7b7ae55 100644
--- a/public/javascripts/manage-fields.js
+++ b/public/javascripts/manage-fields.js
@@ -36,6 +36,34 @@ function signup_action(name_active, name_required, name_signup) {
update_active(name_active, name_required, name_signup)
}
+function add_content(target_id, content, mask) {
+ var id = new Date().getTime();
+ var regexp = new RegExp(mask, "g");
+ content = content.replace(regexp, id);
+ $(target_id).append(content);
+ $('#' + id).hide().slideDown();
+}
+
+function remove_content(target) {
+ $(target).remove();
+}
+
+function submit_custom_field_form(selector_id, form_id, customized_type) {
+ $(selector_id).attr('disabled', true);
+ $(form_id).submit();
+}
+
+function manage_default_option(source) {
+ var th = $(source);
+ var name = th.prop('name');
+ if(th.is(':checked')){
+ $(':checkbox[name="' + name + '"]').not($(source)).prop('checked',false);
+ }
+}
+
+function update_default_value(source, target) {
+ $(target).val(source);
+}
jQuery(document).ready(function(){
function check_fields(check, table_id, start) {
diff --git a/public/stylesheets/manage-fields.scss b/public/stylesheets/manage-fields.scss
index ef7272c..eb5eae2 100644
--- a/public/stylesheets/manage-fields.scss
+++ b/public/stylesheets/manage-fields.scss
@@ -9,3 +9,11 @@
font-style: italic;
}
+.custom-field-item {
+ position: relative;
+ a.icon-delete {
+ position: absolute;
+ top: 20px;
+ right: 20px;
+ }
+}
diff --git a/test/functional/features_controller_test.rb b/test/functional/features_controller_test.rb
index c1a68de..99fab9f 100644
--- a/test/functional/features_controller_test.rb
+++ b/test/functional/features_controller_test.rb
@@ -8,6 +8,7 @@ class FeaturesControllerTest < ActionController::TestCase
@controller = FeaturesController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
+
login_as(create_admin_user(Environment.find(2)))
end
@@ -159,4 +160,51 @@ class FeaturesControllerTest < ActionController::TestCase
assert_includes json_response, {"id"=>person.id, "name"=>person.name}
end
+ should 'create custom field' do
+ uses_host 'anhetegua.net'
+ assert_nil Environment.find(2).custom_fields.find_by_name('foo')
+ post :manage_custom_fields, :customized_type => 'Person', :custom_fields => {
+ Time.now.to_i => {
+ :name => 'foo',
+ :default_value => 'foobar',
+ :format => 'string',
+ :customized_type => 'Person',
+ :active => true,
+ :required => true,
+ :signup => true
+ }
+ }
+ assert_redirected_to :action => 'manage_fields'
+ assert_not_nil Environment.find(2).custom_fields.find_by_name('foo')
+ end
+
+ should 'update custom field' do
+ uses_host 'anhetegua.net'
+
+ field = CustomField.create! :name => 'foo', :default_value => 'foobar', :format => 'string', :extras => '', :customized_type => 'Enterprise', :active => true, :required => true, :signup => true, :environment => Environment.find(2)
+ post :manage_custom_fields, :customized_type => 'Enterprise', :custom_fields => {
+ field.id => {
+ :name => 'foo bar',
+ :default_value => 'foobar',
+ :active => true,
+ :required => true,
+ :signup => true
+ }
+ }
+ field.reload
+ assert_redirected_to :action => 'manage_fields'
+ assert_equal 'foo bar', field.name
+ end
+
+ should 'destroy custom field' do
+ uses_host 'anhetegua.net'
+
+ field = CustomField.create! :name => 'foo', :default_value => 'foobar', :format => 'string', :extras => '', :customized_type => 'Enterprise', :active => true, :required => true, :signup => true, :environment => Environment.find(2)
+
+ post :manage_custom_fields, :customized_type => 'Enterprise'
+
+ assert_redirected_to :action => 'manage_fields'
+ assert_nil Environment.find(2).custom_fields.find_by_name('foo')
+ end
+
end
diff --git a/test/unit/acts_as_customizable_test.rb b/test/unit/acts_as_customizable_test.rb
new file mode 100644
index 0000000..7a9f57b
--- /dev/null
+++ b/test/unit/acts_as_customizable_test.rb
@@ -0,0 +1,23 @@
+require_relative "../test_helper"
+
+class ActsAsCustomizableTest < ActiveSupport::TestCase
+
+ should 'save custom field values for person' do
+ CustomField.create!(:name => "Blog", :format => "string", :customized_type => "Person", :active => true, :environment => Environment.default)
+ person = create_user('testinguser').person
+ assert_difference 'CustomFieldValue.count' do
+ person.custom_values = { "Blog" => { "value" => "www.blog.org", "public" => "0"} }
+ person.save!
+ assert_equal 'www.blog.org', CustomFieldValue.find(:last, :conditions => {:customized_id => person.id}).value
+ end
+ end
+
+ should 'not be valid when required custom field not filled' do
+ CustomField.create!(:name => "Blog", :format => "string", :customized_type => "Person", :active => true, :environment => Environment.default, :required => true)
+ person = create_user('testinguser').person
+
+ person.custom_values = { "Blog" => { "value" => "", "public" => "0"} }
+ refute person.valid?
+ end
+
+end
diff --git a/test/unit/api/people_test.rb b/test/unit/api/people_test.rb
index 07dd9da..d197310 100644
--- a/test/unit/api/people_test.rb
+++ b/test/unit/api/people_test.rb
@@ -165,4 +165,44 @@ class PeopleTest < ActiveSupport::TestCase
assert_equal another_name, person.name
end
+ should 'display public custom fields' do
+ CustomField.create!(:name => "Custom Blog", :format => "string", :customized_type => "Person", :active => true, :environment => Environment.default)
+ some_person = create_user('some-person').person
+ some_person.custom_values = { "Custom Blog" => { "value" => "www.blog.org", "public" => "true"} }
+ some_person.save!
+
+ get "/api/v1/people/#{some_person.id}?#{params.to_query}"
+ json = JSON.parse(last_response.body)
+ assert json['person']['additional_data'].has_key?('Custom Blog')
+ assert_equal "www.blog.org", json['person']['additional_data']['Custom Blog']
+ end
+
+ should 'not display non-public custom fields' do
+ CustomField.create!(:name => "Custom Blog", :format => "string", :customized_type => "Person", :active => true, :environment => Environment.default)
+ some_person = create_user('some-person').person
+ some_person.custom_values = { "Custom Blog" => { "value" => "www.blog.org", "public" => "0"} }
+ some_person.save!
+
+ get "/api/v1/people/#{some_person.id}?#{params.to_query}"
+ json = JSON.parse(last_response.body)
+ assert_equal json['person']['additional_data'], {}
+ end
+
+ should 'display non-public custom fields to friend' do
+ CustomField.create!(:name => "Custom Blog", :format => "string", :customized_type => "Person", :active => true, :environment => Environment.default)
+ some_person = create_user('some-person').person
+ some_person.custom_values = { "Custom Blog" => { "value" => "www.blog.org", "public" => "0"} }
+ some_person.save!
+
+ f = Friendship.new
+ f.friend = some_person
+ f.person = person
+ f.save!
+
+ get "/api/v1/people/#{some_person.id}?#{params.to_query}"
+ json = JSON.parse(last_response.body)
+ assert json['person']['additional_data'].has_key?("Custom Blog")
+ assert_equal "www.blog.org", json['person']['additional_data']['Custom Blog']
+ end
+
end
diff --git a/test/unit/custom_field_test.rb b/test/unit/custom_field_test.rb
new file mode 100644
index 0000000..8773be0
--- /dev/null
+++ b/test/unit/custom_field_test.rb
@@ -0,0 +1,153 @@
+require_relative "../test_helper"
+
+class CustomFieldTest < ActiveSupport::TestCase
+
+ def setup
+ @person = create_user('test_user').person
+
+ @e1 = Environment.default
+ @e2 = fast_create(Environment)
+
+ @community = create(Community, :environment => @e1, :name => 'my new community')
+
+ @community_custom_field = CustomField.create(:name => "community_field", :format=>"myFormat", :default_value => "value for community", :customized_type=>"Community", :active => true, :environment => @e1)
+ @person_custom_field = CustomField.create(:name => "person_field", :format=>"myFormat", :default_value => "value for person", :customized_type=>"Person", :active => true, :environment => @e1)
+ @profile_custom_field = CustomField.create(:name => "profile_field", :format=>"myFormat", :default_value => "value for any profile", :customized_type=>"Profile", :active => true, :environment => @e1)
+
+ @e1.reload
+ end
+
+ should 'not access another environments custom fields' do
+ @e2_custom_field = CustomField.create(:name => "another_field", :format=>"anoherFormat", :default_value => "default value for e2", :customized_type=>"Profile", :active => true, :environment => @e2)
+ @e2.reload
+
+ assert_equal 1, Profile.custom_fields(@e1).size
+ assert_equal @profile_custom_field, Profile.custom_fields(@e1).first
+
+ assert_equal 1, Profile.custom_fields(@e2).size
+ assert_equal @e2_custom_field, Profile.custom_fields(@e2).first
+
+ end
+
+ should 'no access to custom field on sibling' do
+ refute (Person.custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name})
+ refute (Community.custom_fields(@e1).any?{|cf| cf.name == @person_custom_field.name})
+ end
+
+ should 'inheritance of custom_field' do
+ assert Community.custom_fields(@e1).any?{|cf| cf.name == @profile_custom_field.name}
+ assert Person.custom_fields(@e1).any?{|cf| cf.name == @profile_custom_field.name}
+ end
+
+ should 'save custom_field_values' do
+ @community.custom_values = {"community_field" => "new_value!", "profile_field"=> "another_value!"}
+ @community.save
+
+ assert CustomFieldValue.all.any?{|cv| cv.custom_field_id == @community_custom_field.id && cv.customized_id == @community.id && cv.value == "new_value!"}
+ assert CustomFieldValue.all.any?{|cv| cv.custom_field_id == @profile_custom_field.id && cv.customized_id == @community.id && cv.value = "another_value!"}
+ end
+
+ should 'delete custom field and its values' do
+ @community.custom_values = {"community_field" => "new_value!", "profile_field"=> "another_value!"}
+ @community.save
+
+ old_id = @community_custom_field.id
+ @community_custom_field.destroy
+
+ @e1.reload
+ refute (@e1.custom_fields.any?{|cf| cf.id == old_id})
+ refute (Community.custom_fields(@e1).any?{|cf| cf.name == "community_field"})
+ refute (CustomFieldValue.all.any?{|cv| cv.custom_field_id == old_id})
+ end
+
+ should 'not save related custom field' do
+ another_field = CustomField.create(:name => "profile_field", :format=>"myFormat", :default_value => "value for any profile", :customized_type=>"Community", :environment => @e1)
+ assert another_field.id.nil?
+ end
+
+ should 'not save same custom field twice in the same environment' do
+ field = CustomField.create(:name => "the new field", :format=>"myFormat", :customized_type=>"Community", :environment => @e1)
+ refute field.id.nil?
+ @e1.reload
+ another = CustomField.new(:name => "the new field", :format=>"myFormat", :customized_type=>"Community", :environment => @e1)
+ refute another.valid?
+ end
+
+ should 'save same custom field in another environment' do
+ field = CustomField.create(:name => "the new field", :format=>"myFormat", :customized_type=>"Community", :environment => @e1)
+ refute field.id.nil?
+ another_field = CustomField.create(:name => "the new field", :format=>"myFormat", :customized_type=>"Community", :environment => @e2)
+ refute another_field.id.nil?
+ end
+
+ should 'not return inactive fields' do
+ @community_custom_field.update_attributes(:active=>false)
+ @e1.reload
+ refute Community.active_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+ end
+
+ should 'delete a model and its custom field values' do
+ @community.custom_values = {"community_field" => "new_value!", "profile_field"=> "another_value!"}
+ @community.save
+
+ old_id = @community.id
+ @community.destroy
+ refute (Community.all.any?{|c| c.id == old_id})
+ refute (CustomFieldValue.all.any?{|cv| cv.customized_id == old_id && cv.customized_type == "Community"})
+ end
+
+ should 'keep field value if the field is reactivated' do
+
+ @community.custom_values = {"community_field" => "new_value!"}
+ @community.save
+
+ @community_custom_field.update_attributes(:active=>false)
+ @e1.reload
+ refute Community.active_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+
+ @community_custom_field.update_attributes(:active=>true)
+
+ @e1.reload
+ @community.reload
+ assert Community.active_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+ assert_equal @community.custom_value("community_field"), "new_value!"
+ end
+
+ should 'list of required fields' do
+ refute Community.required_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+
+ @community_custom_field.update_attributes(:required=>true)
+ @community.reload
+ @e1.reload
+ assert Community.required_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+ end
+
+ should 'list of signup fields' do
+ refute Community.signup_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+
+ @community_custom_field.update_attributes(:signup=>true)
+ @community.reload
+ @e1.reload
+ assert Community.signup_custom_fields(@e1).any?{|cf| cf.name == @community_custom_field.name}
+ end
+
+ should 'public values handling' do
+ refute @community.is_public("community_field")
+ @community.custom_values = {"community_field" => {"value" => "new_value!", "public"=>"true"}, "profile_field"=> "another_value!"}
+ @community.save
+ @community.reload
+
+ assert @community.is_public("community_field")
+ refute @community.is_public("profile_field")
+ end
+
+ should 'complete list of fields' do
+ assert Person.custom_fields(@e1).include? @profile_custom_field
+ assert Person.custom_fields(@e1).include? @person_custom_field
+ end
+
+ should 'get correct customized ancestors list' do
+ assert (Person.customized_ancestors_list-["Person","Profile"]).blank?
+ end
+end
+
diff --git a/test/unit/custom_field_values_test.rb b/test/unit/custom_field_values_test.rb
new file mode 100644
index 0000000..e7e5ee8
--- /dev/null
+++ b/test/unit/custom_field_values_test.rb
@@ -0,0 +1,12 @@
+require_relative "../test_helper"
+
+class CustomFieldValuesTest < ActiveSupport::TestCase
+
+ should 'custom field value not be valid' do
+ c = CustomField.create!(:name => "Blog", :format => "string", :customized_type => "Person", :active => true, :required => true, :environment => Environment.default)
+ person = create_user('testinguser').person
+
+ cv=CustomFieldValue.new(:customized => person, :custom_field => c, :value => "")
+ refute cv.valid?
+ end
+end
--
libgit2 0.21.2