Commit 81752a5ce130ca0930ed23144f1475c673c6713f

Authored by Rodrigo Souto
1 parent 76560478

[custom-forms] Base model and migrations

Showing 22 changed files with 824 additions and 0 deletions   Show diff stats
plugins/custom_forms/db/migrate/20120727162444_create_custom_forms_plugin_forms.rb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +class CreateCustomFormsPluginForms < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :custom_forms_plugin_forms do |t|
  4 + t.string :name
  5 + t.string :slug
  6 + t.text :description
  7 + t.references :profile
  8 + t.datetime :begining
  9 + t.datetime :ending
  10 + t.boolean :report_submissions, :default => false
  11 + t.boolean :on_membership, :default => false
  12 + t.string :access
  13 + t.timestamps
  14 + end
  15 + end
  16 +
  17 + def self.down
  18 + drop_table :custom_forms_plugin_forms
  19 + end
  20 +end
... ...
plugins/custom_forms/db/migrate/20120727174506_create_custom_forms_plugin_fields.rb 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +class CreateCustomFormsPluginFields < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :custom_forms_plugin_fields do |t|
  4 + t.string :name
  5 + t.string :slug
  6 + t.string :type
  7 + t.string :default_value
  8 + t.string :choices
  9 + t.float :minimum
  10 + t.float :maximum
  11 + t.references :form
  12 + t.boolean :mandatory, :default => false
  13 + t.boolean :multiple
  14 + t.boolean :list
  15 + end
  16 + end
  17 +
  18 + def self.down
  19 + drop_table :custom_forms_plugin_fields
  20 + end
  21 +end
... ...
plugins/custom_forms/db/migrate/20120727175250_create_custom_forms_plugin_answers.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class CreateCustomFormsPluginAnswers < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :custom_forms_plugin_answers do |t|
  4 + t.text :value
  5 + t.references :field
  6 + t.references :submission
  7 + end
  8 + end
  9 +
  10 + def self.down
  11 + drop_table :custom_forms_plugin_answers
  12 + end
  13 +end
... ...
plugins/custom_forms/db/migrate/20120727180512_create_custom_forms_plugin_submissions.rb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +class CreateCustomFormsPluginSubmissions < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :custom_forms_plugin_submissions do |t|
  4 + t.string :author_name
  5 + t.string :author_email
  6 + t.references :profile
  7 + t.references :form
  8 + t.timestamps
  9 + end
  10 + end
  11 +
  12 + def self.down
  13 + drop_table :custom_forms_plugin_submissions
  14 + end
  15 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin.rb 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +require 'ext/role_assignment_trigger'
  2 +
  3 +class CustomFormsPlugin < Noosfero::Plugin
  4 +
  5 + def self.plugin_name
  6 + "Custom Forms"
  7 + end
  8 +
  9 + def self.plugin_description
  10 + _("Enables the creation of forms.")
  11 + end
  12 +
  13 + def stylesheet?
  14 + true
  15 + end
  16 +
  17 + def control_panel_buttons
  18 + {:title => _('Manage Forms'), :icon => 'custom-forms', :url => {:controller => 'custom_forms_plugin_myprofile'}}
  19 + end
  20 +
  21 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/answer.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class CustomFormsPlugin::Answer < Noosfero::Plugin::ActiveRecord
  2 + belongs_to :field, :class_name => 'CustomFormsPlugin::Field'
  3 + belongs_to :submission, :class_name => 'CustomFormsPlugin::Submission'
  4 +
  5 + validates_presence_of :field
  6 + validate :value_mandatory, :if => 'field.present?'
  7 +
  8 + def value_mandatory
  9 + if field.mandatory && value.blank?
  10 + errors.add(field.slug.to_sym, _("is mandatory.").fix_i18n)
  11 + end
  12 + end
  13 +end
  14 +
... ...
plugins/custom_forms/lib/custom_forms_plugin/field.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class CustomFormsPlugin::Field < ActiveRecord::Base
  2 + set_table_name :custom_forms_plugin_fields
  3 +
  4 + validates_presence_of :form, :name
  5 + validates_uniqueness_of :slug, :scope => :form_id
  6 +
  7 + belongs_to :form, :class_name => 'CustomFormsPlugin::Form', :dependent => :destroy
  8 + has_many :answers, :class_name => 'CustomFormsPlugin::Answer'
  9 +
  10 + serialize :choices, Hash
  11 +
  12 + before_validation do |field|
  13 + field.slug = field.name.to_slug if field.name.present?
  14 + end
  15 +end
  16 +
... ...
plugins/custom_forms/lib/custom_forms_plugin/form.rb 0 → 100644
... ... @@ -0,0 +1,70 @@
  1 +class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord
  2 + belongs_to :profile
  3 +
  4 + has_many :fields, :class_name => 'CustomFormsPlugin::Field'
  5 + has_many :submissions, :class_name => 'CustomFormsPlugin::Submission'
  6 +
  7 + serialize :access
  8 +
  9 + validates_presence_of :profile, :name
  10 + validates_uniqueness_of :slug, :scope => :profile_id
  11 + validate :access_format
  12 +
  13 + before_validation do |form|
  14 + form.slug = form.name.to_slug if form.name.present?
  15 + form.access = nil if form.access.blank?
  16 + end
  17 +
  18 + named_scope :from, lambda {|profile| {:conditions => {:profile_id => profile.id}}}
  19 + named_scope :on_memberships, {:conditions => {:on_membership => true}}
  20 +=begin
  21 + named_scope :accessible_to lambda do |profile|
  22 + #TODO should verify is profile is associated with the form owner
  23 + profile_associated = ???
  24 + {:conditions => ["
  25 + access IS NULL OR
  26 + (access='logged' AND :profile_present) OR
  27 + (access='associated' AND :profile_associated) OR
  28 + :profile_id in access
  29 + ", {:profile_present => profile.present?, :profile_associated => ???, :profile_id => profile.id}]}
  30 + end
  31 +=end
  32 +
  33 + def expired?
  34 + (begining.present? && Time.now < begining) || (ending.present? && Time.now > ending)
  35 + end
  36 +
  37 + def accessible_to(target)
  38 + return true if access.nil? || target == profile
  39 + return false if target.nil?
  40 + return true if access == 'logged'
  41 + return true if access == 'associated' && ((profile.organization? && profile.members.include?(target)) || (profile.person? && profile.friends.include?(target)))
  42 + return true if access.kind_of?(Integer) && target.id == access
  43 + return true if access.kind_of?(Array) && access.include?(target.id)
  44 + end
  45 +
  46 + private
  47 +
  48 + def access_format
  49 + if access.present?
  50 + if access.kind_of?(String)
  51 + if access != 'logged' && access != 'associated'
  52 + errors.add(:access, _('Invalid string format of access.'))
  53 + end
  54 + elsif access.kind_of?(Integer)
  55 + if !Profile.exists?(access)
  56 + errors.add(:access, _('There is no profile with the provided id.'))
  57 + end
  58 + elsif access.kind_of?(Array)
  59 + access.each do |value|
  60 + if !value.kind_of?(Integer) || !Profile.exists?(value)
  61 + errors.add(:access, _('There is no profile with the provided id.'))
  62 + break
  63 + end
  64 + end
  65 + else
  66 + errors.add(:access, _('Invalid type format of access.'))
  67 + end
  68 + end
  69 + end
  70 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/helper.rb 0 → 100644
... ... @@ -0,0 +1,119 @@
  1 +module CustomFormsPlugin::Helper
  2 + def access_text(form)
  3 + return _('Public') if form.access.nil?
  4 + return _('Logged users') if form.access == 'logged'
  5 + if form.access == 'associated'
  6 + return _('Members') if form.profile.organization?
  7 + return _('Friends') if form.profile.person?
  8 + end
  9 + return _('Custom')
  10 + end
  11 +
  12 + def period_range(form)
  13 + if form.begining.blank? && form.ending.blank?
  14 + _('Always')
  15 + elsif form.begining.present? && form.ending.blank?
  16 + ('From %s') % time_format(form.begining)
  17 + elsif form.begining.blank? && form.ending.present?
  18 + _('Until %s') % time_format(form.ending)
  19 + elsif form.begining.present? && form.ending.present?
  20 + _('From %s until %s') % [time_format(form.begining), time_format(form.ending)]
  21 + end
  22 + end
  23 +
  24 + def time_format(time)
  25 + minutes = (time.min == 0) ? '' : ':%M'
  26 + hour = (time.hour == 0 && minutes.blank?) ? '' : ' %H'
  27 + h = hour.blank? ? '' : 'h'
  28 + time.strftime("%Y-%m-%d#{hour+minutes+h}")
  29 + end
  30 +
  31 + # TODO add the custom option that should offer the user the hability to
  32 + # choose the profiles one by one, using something like tokeninput
  33 + def access_options(profile)
  34 + associated = profile.organization? ? _('Members') : _('Friends')
  35 + [
  36 + [_('Public'), nil ],
  37 + [_('Logged users'), 'logged' ],
  38 + [ associated, 'associated'],
  39 + ]
  40 + end
  41 +
  42 + def type_options
  43 + [
  44 + [_('Text'), 'text_field' ],
  45 + [_('Select'), 'select_field']
  46 + ]
  47 + end
  48 +
  49 + def type_to_label(type)
  50 + map = {
  51 + 'text_field' => _('Text'),
  52 + 'select_field' => _('Select')
  53 + }
  54 + map[type_for_options(type)]
  55 + end
  56 +
  57 + def type_for_options(type)
  58 + type.to_s.split(':').last.underscore
  59 + end
  60 +
  61 + def display_custom_field(field, submission, form)
  62 + answer = submission.answers.select{|answer| answer.field == field}.first
  63 + field_tag = send("display_#{type_for_options(field.class)}",field, answer, form)
  64 + if field.mandatory? && !radio_button?(field) && !check_box?(field) && submission.id.nil?
  65 + required(labelled_form_field(field.name, field_tag))
  66 + else
  67 + labelled_form_field(field.name, field_tag)
  68 + end
  69 + end
  70 +
  71 + def display_text_field(field, answer, form)
  72 + value = answer.present? ? answer.value : field.default_value
  73 + text_field(form, field.name.to_slug, :value => value, :disabled => answer.present?)
  74 + end
  75 +
  76 + def display_select_field(field, answer, form)
  77 + if field.list && field.multiple
  78 + selected = answer.present? ? answer.value.split(',') : []
  79 + select_tag "#{form}[#{field.name.to_slug}]", options_for_select(field.choices.to_a, selected), :multiple => true, :size => field.choices.size, :disabled => answer.present?
  80 + elsif !field.list && field.multiple
  81 + field.choices.map do |name, value|
  82 + default = answer.present? ? answer.value.split(',').include?(value) : false
  83 + labelled_check_box name, "#{form}[#{field.name.to_slug}][#{value}]", '1', default, :disabled => answer.present?
  84 + end.join("\n")
  85 + elsif field.list && !field.multiple
  86 + selected = answer.present? ? answer.value.split(',') : []
  87 + select_tag "#{form}[#{field.name.to_slug}]", options_for_select([['','']] + field.choices.to_a, selected), :disabled => answer.present?
  88 + elsif !field.list && !field.multiple
  89 + field.choices.map do |name, value|
  90 + default = answer.present? ? answer.value == value : true
  91 + labelled_radio_button name, "#{form}[#{field.name.to_slug}]", value, default, :disabled => answer.present?
  92 + end.join("\n")
  93 + end
  94 + end
  95 +
  96 + def radio_button?(field)
  97 + type_for_options(field.class) == 'select_field' && !field.list && !field.multiple
  98 + end
  99 +
  100 + def check_box?(field)
  101 + type_for_options(field.class) == 'select_field' && !field.list && field.multiple
  102 + end
  103 +
  104 + def build_answers(submission, form)
  105 + answers = []
  106 + submission.each do |slug, value|
  107 + field = form.fields.select {|field| field.slug==slug}.first
  108 + if value.kind_of?(String)
  109 + final_value = value
  110 + elsif value.kind_of?(Array)
  111 + final_value = value.join(',')
  112 + elsif value.kind_of?(Hash)
  113 + final_value = value.map {|option, present| present == '1' ? option : nil}.compact.join(',')
  114 + end
  115 + answers << CustomFormsPlugin::Answer.new(:field => field, :value => final_value)
  116 + end
  117 + answers
  118 + end
  119 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/membership_survey.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +class CustomFormsPlugin::MembershipSurvey < Task
  2 +
  3 + settings_items :form_id, :submission
  4 + validates_presence_of :form_id
  5 +
  6 + include CustomFormsPlugin::Helper
  7 +
  8 + def perform
  9 + form = CustomFormsPlugin::Form.find(form_id)
  10 + answers = build_answers(submission, form)
  11 + s = CustomFormsPlugin::Submission.create!(:form => form, :profile => target)
  12 + answers.map {|answer| answer.submission = s; answer.save!}
  13 + end
  14 +
  15 + def title
  16 + _("Membership survey")
  17 + end
  18 +
  19 + def subject
  20 + nil
  21 + end
  22 +
  23 + def linked_subject
  24 + nil
  25 + end
  26 +
  27 + def information
  28 + {:message => _('%{requestor} wants you to fill in some information.')}
  29 + end
  30 +
  31 + def accept_details
  32 + true
  33 + end
  34 +
  35 + def icon
  36 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
  37 + end
  38 +
  39 + def target_notification_message
  40 + _('After joining %{requestor}, the administrators of this organization
  41 + wants you to fill in some further information.') % {:requestor => requestor.name}
  42 + end
  43 +
  44 + def target_notification_description
  45 + _('%{requestor} wants to fill in some further information.') % {:requestor => requestor.name}
  46 + end
  47 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/numeric.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +class CustomFormsPlugin::Numeric < CustomFormsPlugin::Field
  2 + set_table_name :custom_forms_plugin_fields
  3 +end
  4 +
... ...
plugins/custom_forms/lib/custom_forms_plugin/select_field.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +class CustomFormsPlugin::SelectField < CustomFormsPlugin::Field
  2 + set_table_name :custom_forms_plugin_fields
  3 + validates_presence_of :choices
  4 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/submission.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class CustomFormsPlugin::Submission < Noosfero::Plugin::ActiveRecord
  2 + belongs_to :form, :class_name => 'CustomFormsPlugin::Form'
  3 + belongs_to :profile
  4 +
  5 + has_many :answers, :class_name => 'CustomFormsPlugin::Answer'
  6 +
  7 + validates_presence_of :form
  8 + validates_presence_of :author_name, :author_email, :if => lambda {|submission| submission.profile.nil?}
  9 + validates_uniqueness_of :author_email, :scope => :form_id, :allow_nil => true
  10 + validates_format_of :author_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|submission| !submission.author_email.blank?})
  11 +end
  12 +
... ...
plugins/custom_forms/lib/custom_forms_plugin/text_field.rb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +class CustomFormsPlugin::TextField < CustomFormsPlugin::Field
  2 + set_table_name :custom_forms_plugin_fields
  3 +end
... ...
plugins/custom_forms/lib/ext/role_assignment_trigger.rb 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +module RoleAssignmentTrigger
  2 + def self.included(base)
  3 + base.class_eval do
  4 + before_create do |ra|
  5 + profile = ra.resource
  6 + person = ra.accessor
  7 + ok = !profile.nil? && !person.nil? && profile.environment.present?
  8 + if ok && profile.environment.plugin_enabled?(CustomFormsPlugin) && !person.is_member_of?(profile)
  9 + CustomFormsPlugin::Form.from(profile).on_memberships.each do |form|
  10 + CustomFormsPlugin::MembershipSurvey.create!(:requestor => profile, :target => person, :form_id => form.id)
  11 + end
  12 + end
  13 + end
  14 +
  15 + after_destroy do |ra|
  16 + profile = ra.resource
  17 + person = ra.accessor
  18 + ok = !profile.nil? && !person.nil? && profile.environment.present?
  19 + if ok && profile.environment.plugin_enabled?(CustomFormsPlugin) && !person.is_member_of?(profile)
  20 + CustomFormsPlugin::Form.from(profile).on_memberships.each do |form|
  21 + task = person.tasks.pending.select {|task| task.kind_of?(CustomFormsPlugin::MembershipSurvey) && task.form_id == form.id}.first
  22 + task.cancel if task
  23 + end
  24 + end
  25 + end
  26 + end
  27 + end
  28 +end
  29 +
  30 +RoleAssignment.send :include, RoleAssignmentTrigger
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/answer_test.rb 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class CustomFormsPlugin::AnswerTest < ActiveSupport::TestCase
  4 + should 'validates presence of field' do
  5 + answer = CustomFormsPlugin::Answer.new
  6 + answer.valid?
  7 + assert answer.errors.invalid?(:field)
  8 +
  9 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  10 + field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
  11 + answer.field = field
  12 + answer.valid?
  13 + assert !answer.errors.invalid?(:field)
  14 + end
  15 +
  16 + should 'belong to a submission' do
  17 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  18 + submission = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
  19 + answer = CustomFormsPlugin::Answer.new
  20 + answer.submission = submission
  21 +
  22 + assert_equal submission, answer.submission
  23 + end
  24 +
  25 + should 'require presence of value if field is mandatory' do
  26 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  27 + field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form, :mandatory => true)
  28 + answer = CustomFormsPlugin::Answer.new(:field => field)
  29 + answer.valid?
  30 + assert answer.errors.invalid?(field.slug.to_sym)
  31 +
  32 + answer.value = "GPL"
  33 + answer.valid?
  34 + assert !answer.errors.invalid?(field.slug.to_sym)
  35 + end
  36 +
  37 +end
  38 +
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/field_test.rb 0 → 100644
... ... @@ -0,0 +1,64 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase
  4 + should 'validate presence of form' do
  5 + field = CustomFormsPlugin::Field.new
  6 + field.valid?
  7 + assert field.errors.invalid?(:form)
  8 + assert field.errors.invalid?(:name)
  9 +
  10 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  11 + field.form = form
  12 + field.name = 'License'
  13 + field.valid?
  14 + assert !field.errors.invalid?(:form)
  15 + assert !field.errors.invalid?(:name)
  16 + end
  17 +
  18 + should 'set slug before validation based on name' do
  19 + field = CustomFormsPlugin::Field.new(:name => 'Name')
  20 + field.valid?
  21 + assert_equal field.name.to_slug, field.slug
  22 + end
  23 +
  24 + should 'validate uniqueness of slug scoped on the form' do
  25 + form1 = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  26 + form2 = CustomFormsPlugin::Form.create!(:name => 'Open Source', :profile => fast_create(Profile))
  27 + f1 = CustomFormsPlugin::Field.create!(:name => 'License', :form => form1)
  28 + f2 = CustomFormsPlugin::Field.new(:name => 'License', :form => form1)
  29 + f3 = CustomFormsPlugin::Field.new(:name => 'License', :form => form2)
  30 +
  31 + f2.valid?
  32 + f3.valid?
  33 +
  34 + assert f2.errors.invalid?(:slug)
  35 + assert !f3.errors.invalid?(:slug)
  36 + end
  37 +
  38 + should 'set mandatory field as false by default' do
  39 + field = CustomFormsPlugin::Field.new
  40 + assert !field.mandatory
  41 + end
  42 +
  43 + should 'have answers' do
  44 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  45 + field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
  46 + a1 = CustomFormsPlugin::Answer.create!(:field => field)
  47 + a2 = CustomFormsPlugin::Answer.create!(:field => field)
  48 +
  49 + assert_includes field.answers, a1
  50 + assert_includes field.answers, a2
  51 + end
  52 +
  53 + should 'serialize choices into a hash' do
  54 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  55 + field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
  56 + field.choices = {'First' => 1, 'Second' => 2, 'Third' => 3}
  57 + field.save!
  58 +
  59 + assert_equal 1, field.choices['First']
  60 + assert_equal 2, field.choices['Second']
  61 + assert_equal 3, field.choices['Third']
  62 + end
  63 +end
  64 +
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/form_test.rb 0 → 100644
... ... @@ -0,0 +1,172 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class CustomFormsPlugin::FormTest < ActiveSupport::TestCase
  4 + should 'validates presence of a profile and a name' do
  5 + form = CustomFormsPlugin::Form.new
  6 + form.valid?
  7 + assert form.errors.invalid?(:profile)
  8 + assert form.errors.invalid?(:name)
  9 +
  10 + form.profile = fast_create(Profile)
  11 + form.name = 'Free Software'
  12 + form.valid?
  13 + assert !form.errors.invalid?(:profile)
  14 + assert !form.errors.invalid?(:name)
  15 + end
  16 +
  17 + should 'have many fields including fields subclasses' do
  18 + form = CustomFormsPlugin::Form.create!(:profile => fast_create(Profile), :name => 'Free Software')
  19 + f1 = CustomFormsPlugin::Field.create!(:form => form, :name => 'License')
  20 + f2 = CustomFormsPlugin::Field.create!(:form => form, :name => 'Code')
  21 + f3 = CustomFormsPlugin::TextField.create!(:form => form, :name => 'Developer')
  22 +
  23 + assert_includes form.fields, f1
  24 + assert_includes form.fields, f2
  25 + assert_includes form.fields, f3
  26 + end
  27 +
  28 + should 'have many submissions' do
  29 + form = CustomFormsPlugin::Form.create!(:profile => fast_create(Profile), :name => 'Free Software')
  30 + s1 = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
  31 + s2 = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
  32 +
  33 + assert_includes form.submissions, s1
  34 + assert_includes form.submissions, s2
  35 + end
  36 +
  37 + should 'set slug before validation based on name' do
  38 + form = CustomFormsPlugin::Form.new(:name => 'Name')
  39 + form.valid?
  40 + assert_equal form.name.to_slug, form.slug
  41 + end
  42 +
  43 + should 'validates uniqueness of slug scoped on profile' do
  44 + profile = fast_create(Profile)
  45 + another_profile = fast_create(Profile)
  46 + CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software')
  47 + form = CustomFormsPlugin::Form.new(:profile => profile, :name => 'Free Software')
  48 + form.valid?
  49 + assert form.errors.invalid?(:slug)
  50 +
  51 + form.profile = another_profile
  52 + form.valid?
  53 + assert !form.errors.invalid?(:slug)
  54 + end
  55 +
  56 + should 'define form expiration' do
  57 + form = CustomFormsPlugin::Form.new
  58 + assert !form.expired?
  59 +
  60 + form.begining = Time.now + 1.day
  61 + assert form.expired?
  62 +
  63 + form.begining = Time.now - 1.day
  64 + assert !form.expired?
  65 +
  66 + form.begining = nil
  67 + form.ending = Time.now + 1.day
  68 + assert !form.expired?
  69 +
  70 + form.ending = Time.now - 1.day
  71 + assert form.expired?
  72 +
  73 + form.begining = Time.now - 1.day
  74 + form.ending = Time.now + 1.day
  75 + assert !form.expired?
  76 + end
  77 +
  78 + should 'validates format of access' do
  79 + form = CustomFormsPlugin::Form.new
  80 + form.valid?
  81 + assert !form.errors.invalid?(:access)
  82 +
  83 + form.access = 'bli'
  84 + form.valid?
  85 + assert form.errors.invalid?(:access)
  86 +
  87 + form.access = 'logged'
  88 + form.valid?
  89 + assert !form.errors.invalid?(:access)
  90 +
  91 + form.access = 'associated'
  92 + form.valid?
  93 + assert !form.errors.invalid?(:access)
  94 +
  95 + form.access = {:bli => 1}
  96 + form.valid?
  97 + assert form.errors.invalid?(:access)
  98 +
  99 + form.access = 999
  100 + form.valid?
  101 + assert form.errors.invalid?(:access)
  102 +
  103 + p1 = fast_create(Profile)
  104 + form.access = p1.id
  105 + form.valid?
  106 + assert !form.errors.invalid?(:access)
  107 +
  108 + p2 = fast_create(Profile)
  109 + p3 = fast_create(Profile)
  110 + form.access = [p1,p2,p3].map(&:id)
  111 + form.valid?
  112 + assert !form.errors.invalid?(:access)
  113 + end
  114 +
  115 + should 'defines who is able to access the form' do
  116 + owner = fast_create(Community)
  117 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => owner)
  118 + assert form.accessible_to(nil)
  119 +
  120 + form.access = 'logged'
  121 + assert !form.accessible_to(nil)
  122 + person = fast_create(Person)
  123 + assert form.accessible_to(person)
  124 +
  125 + form.access = 'associated'
  126 + assert !form.accessible_to(person)
  127 + owner.add_member(person)
  128 + assert form.accessible_to(person)
  129 +
  130 + p1 = fast_create(Profile)
  131 + form.access = p1.id
  132 + assert !form.accessible_to(person)
  133 + assert form.accessible_to(p1)
  134 +
  135 + p2 = fast_create(Profile)
  136 + form.access = [person.id, p1.id]
  137 + assert form.accessible_to(person)
  138 + assert form.accessible_to(p1)
  139 + assert !form.accessible_to(p2)
  140 + form.access << p2.id
  141 + assert form.accessible_to(p2)
  142 +
  143 + assert form.accessible_to(owner)
  144 + end
  145 +
  146 + should 'have a named_scope that retrieve forms from a profile' do
  147 + profile = fast_create(Profile)
  148 + another_profile = fast_create(Profile)
  149 + f1 = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => profile)
  150 + f2 = CustomFormsPlugin::Form.create!(:name => 'Open Source', :profile => profile)
  151 + f3 = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => another_profile)
  152 + scope = CustomFormsPlugin::Form.from(profile)
  153 +
  154 + assert_equal ActiveRecord::NamedScope::Scope, scope.class
  155 + assert_includes scope, f1
  156 + assert_includes scope, f2
  157 + assert_not_includes scope, f3
  158 + end
  159 +
  160 + should 'have a named_scope that retrieves all forms that are triggered on membership' do
  161 + profile = fast_create(Profile)
  162 + f1 = CustomFormsPlugin::Form.create!(:name => 'On membership 1', :profile => profile, :on_membership => true)
  163 + f2 = CustomFormsPlugin::Form.create!(:name => 'On membership 2', :profile => profile, :on_membership => true)
  164 + f3 = CustomFormsPlugin::Form.create!(:name => 'Not on memberhsip', :profile => profile, :on_membership => false)
  165 + scope = CustomFormsPlugin::Form.from(profile).on_memberships
  166 +
  167 + assert_equal ActiveRecord::NamedScope::Scope, scope.class
  168 + assert_includes scope, f1
  169 + assert_includes scope, f2
  170 + assert_not_includes scope, f3
  171 + end
  172 +end
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/membership_survey_test.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class CustomFormsPlugin::MembershipSurveyTest < ActiveSupport::TestCase
  4 + should 'validates presence of form_id' do
  5 + task = CustomFormsPlugin::MembershipSurvey.new
  6 + task.valid?
  7 + assert task.errors.invalid?(:form_id)
  8 +
  9 + task.form_id = 1
  10 + task.valid?
  11 + assert !task.errors.invalid?(:form_id)
  12 + end
  13 +
  14 + should 'create submission with answers on perform' do
  15 + profile = fast_create(Profile)
  16 + person = fast_create(Person)
  17 + form = CustomFormsPlugin::Form.create!(:name => 'Simple Form', :profile => profile)
  18 + field = CustomFormsPlugin::Field.create!(:name => 'Name', :form => form)
  19 + task = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form.id, :submission => {'name' => 'Jack'}, :target => person, :requestor => profile)
  20 +
  21 + assert_difference CustomFormsPlugin::Submission, :count, 1 do
  22 + task.finish
  23 + end
  24 +
  25 + submission = CustomFormsPlugin::Submission.last
  26 + assert_equal submission.answers.count, 1
  27 +
  28 + answer = submission.answers.first
  29 + assert_equal answer.value, 'Jack'
  30 + end
  31 +end
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/select_field_test.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class CustomFormsPlugin::SelectFieldTest < ActiveSupport::TestCase
  4 + should 'validate presence of choices, multiple and list' do
  5 + select = CustomFormsPlugin::SelectField.new
  6 + select.valid?
  7 + assert select.errors.invalid?(:choices)
  8 +
  9 + select.choices = {'label' => 'value'}
  10 + select.valid?
  11 + assert !select.errors.invalid?(:choices)
  12 + end
  13 +end
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/submission_test.rb 0 → 100644
... ... @@ -0,0 +1,46 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class CustomFormsPlugin::SubmissionTest < ActiveSupport::TestCase
  4 + should 'validates presence of form' do
  5 + submission = CustomFormsPlugin::Submission.new
  6 + submission.valid?
  7 + assert submission.errors.invalid?(:form)
  8 +
  9 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  10 + submission.form = form
  11 + submission.valid?
  12 + assert !submission.errors.invalid?(:form)
  13 + end
  14 +
  15 + should 'belong to a profile' do
  16 + profile = fast_create(Profile)
  17 + submission = CustomFormsPlugin::Submission.new
  18 + submission.profile = profile
  19 + assert_equal profile, submission.profile
  20 + end
  21 +
  22 + should 'require presence of author name and email if profile is nil' do
  23 + submission = CustomFormsPlugin::Submission.new
  24 + submission.valid?
  25 + assert submission.errors.invalid?(:author_name)
  26 + assert submission.errors.invalid?(:author_email)
  27 +
  28 + submission.author_name = 'Jack Sparrow'
  29 + submission.author_email = 'jack@black-pearl.com'
  30 + submission.valid?
  31 + assert !submission.errors.invalid?(:author_name)
  32 + assert !submission.errors.invalid?(:author_email)
  33 + end
  34 +
  35 + should 'have answers' do
  36 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  37 + field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
  38 + submission = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
  39 + a1 = CustomFormsPlugin::Answer.create!(:field => field, :submission => submission)
  40 + a2 = CustomFormsPlugin::Answer.create!(:field => field, :submission => submission)
  41 +
  42 + assert_includes submission.answers, a1
  43 + assert_includes submission.answers, a2
  44 + end
  45 +end
  46 +
... ...
plugins/custom_forms/test/unit/ext/role_assingment_test.rb 0 → 100644
... ... @@ -0,0 +1,51 @@
  1 +require File.dirname(__FILE__) + '/../../../../../test/test_helper'
  2 +
  3 +class RoleAssignmentsTest < ActiveSupport::TestCase
  4 + should 'create membership_surveys on membership creation' do
  5 + environment = Environment.default
  6 + environment.enable_plugin(CustomFormsPlugin)
  7 + organization = fast_create(Organization)
  8 + person = fast_create(Person)
  9 + f1 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 1', :on_membership => true)
  10 + f2 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 2', :on_membership => true)
  11 + f3 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 3', :on_membership => false)
  12 +
  13 + assert_difference CustomFormsPlugin::MembershipSurvey, :count, 2 do
  14 + organization.add_member(person)
  15 + end
  16 + end
  17 +
  18 + should 'create membership_survey on membership creation with form accessible to members only' do
  19 + environment = Environment.default
  20 + environment.enable_plugin(CustomFormsPlugin)
  21 + organization = fast_create(Organization)
  22 + person = fast_create(Person)
  23 + form = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form', :on_membership => true, :access => 'associated')
  24 +
  25 + assert_difference CustomFormsPlugin::MembershipSurvey, :count, 1 do
  26 + organization.add_member(person)
  27 + end
  28 + end
  29 +
  30 + should 'cancel membership_surveys if membership is undone and task is active' do
  31 + environment = Environment.default
  32 + environment.enable_plugin(CustomFormsPlugin)
  33 + organization = fast_create(Organization)
  34 + person = fast_create(Person)
  35 + form = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form', :on_membership => true)
  36 + organization.add_member(person)
  37 +
  38 + assert_difference CustomFormsPlugin::MembershipSurvey.pending, :count, -1 do
  39 + organization.remove_member(person)
  40 + end
  41 +
  42 + organization.add_member(person)
  43 + task = CustomFormsPlugin::MembershipSurvey.last
  44 + task.status = Task::Status::FINISHED
  45 + task.save!
  46 + assert_no_difference CustomFormsPlugin::MembershipSurvey.finished, :count do
  47 + organization.remove_member(person)
  48 + end
  49 + end
  50 +end
  51 +
... ...