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 %> +
+ +
+
+ <%= _('New field') %> + <%= select_tag _('Type: '), options_for_select(custom_field_forms(customized_type.to_s)), {:id => "#{format_values_id}"} %> + <%= button(:add, _('Add'), 'javascript: void()', :onClick => "add_content('##{fields_id}',$('##{format_values_id} option:selected').val(), 'NEW_FIELD_ID');") %> +
+
+ +<% 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%> + + + <%= text_field_tag "custom_fields[#{id}][extras][#{field_id}]", (extra.nil? ? '' : extra), :onkeyup => "update_default_value($(this).val(), '#custom_fields_#{id}_extras_#{field_id}_default')" %> + + + <%= check_box_tag "custom_fields[#{id}][default_value]", extra.blank? ? '' : extra, extra.blank? ? false : def_value == extra, :id => "custom_fields_#{id}_extras_#{field_id}_default", :onclick => "manage_default_option(this);" %> + + + <% if extra.nil? %> + <%= button_to_function_without_text :remove, _('Remove'), "remove_content('#extras_#{field_id}'); ", :class => 'remove-field', :title => 'Remove alternative' %> + <% end %> + + 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 %> + +
+
+ <%= format_name(field.format) %> + <%= required labelled_form_field _('Name'), text_field_tag("custom_fields[#{id}][name]", field.name, :size => 30) %> + <%= button_to_function :delete, _('Remove field'), "remove_content('##{id}');" %> + + <% if field.format != "list" %> + <%= labelled_form_field _('Default value'), text_field_tag("custom_fields[#{id}][default_value]", field.default_value, :size => 30) %> + <% end %> + <%= hidden_field_tag "custom_fields[#{id}][customized_type]", field.customized_type.to_s %> + <%= hidden_field_tag "custom_fields[#{id}][format]", field.format %> + +
+ <%= labelled_check_box _('Active'), "custom_fields[#{id}][active]", 1, field.active, :id => "active_checkbox", :onclick => "active_action('custom_fields[#{id}][active]','custom_fields[#{id}][required]', 'custom_fields[#{id}][signup]')" %> + <%= labelled_check_box _('Required'), "custom_fields[#{id}][required]", 1, field.required, :id => "required_checkbox", :onclick => "required_action('custom_fields[#{id}][active]','custom_fields[#{id}][required]', 'custom_fields[#{id}][signup]')" %> + <%= labelled_check_box _('Display on creation?'), "custom_fields[#{id}][signup]", 1, field.signup, :id => "signup_checkbox",:onclick => "signup_action('custom_fields[#{id}][active]','custom_fields[#{id}][required]', 'custom_fields[#{id}][signup]')" %> +
+ + <% if field.format == "list" %> + + + + + + + + + + + + + <% if !field.extras.blank?%> + <% field.extras.each do |extra|%> + <%= render_extras_field id, extra, field %> + <% end %> + <% end %> + +
<%= _("Alternative") %><%= _("Default") %><%= _("Delete") %>
<%= button(:add, _('Add option'), 'javascript: void()', :id => "btn_opt_#{id}", :onclick => "add_content('##{id} .custom-field-extras', $('#btn_opt_#{id}').attr('value'), 'EXTRAS_ID');", :value => "#{render_extras_field(id)}") %>
+ <% end %> +
+
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