diff --git a/.gitignore b/.gitignore index abffb6d..d0efb14 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,4 @@ lib/assets/npm-debug.log lib/assets/.eslintcache !.keep +.byebug_history diff --git a/Gemfile b/Gemfile index 314e27e..185a7e8 100644 --- a/Gemfile +++ b/Gemfile @@ -8,10 +8,6 @@ gem 'railties' -# GEMS ADDED TO HELP HANDLE RAILS MIGRATION FROM 3.x to 4.2 -# THESE GEMS HELP SUPPORT DEPRACATED FUNCTIONALITY AND WILL LOSE SUPPORT IN FUTURE VERSIONS -# WE SHOULD CONSIDER BRINGING THE CODE UP TO DATE INSTEAD -gem 'protected_attributes', '~> 1.1.3' # Provides attr_accessor functions gem 'responders', '~> 2.0' # Allows use of respond_with and respond_to in controllers # ------------------------------------------------ diff --git a/Gemfile.lock b/Gemfile.lock index 29f1a92..ef41814 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -164,8 +164,6 @@ pg (0.19.0) po_to_json (1.0.1) json (>= 1.6.0) - protected_attributes (1.1.3) - activemodel (>= 4.0.1, < 5.0) pundit (1.1.0) activesupport (>= 3.0.0) rack (1.6.10) @@ -268,7 +266,6 @@ omniauth-orcid omniauth-shibboleth pg (~> 0.19.0) - protected_attributes (~> 1.1.3) pundit rack-mini-profiler rack-test diff --git a/app/controllers/guidance_groups_controller.rb b/app/controllers/guidance_groups_controller.rb index 9bbfae9..74db0c5 100644 --- a/app/controllers/guidance_groups_controller.rb +++ b/app/controllers/guidance_groups_controller.rb @@ -19,7 +19,7 @@ # POST /guidance_groups # POST /guidance_groups.json def admin_create - @guidance_group = GuidanceGroup.new(params[:guidance_group]) + @guidance_group = GuidanceGroup.new(guidance_group_params) authorize @guidance_group @guidance_group.org_id = current_user.org_id if params[:save_publish] @@ -49,8 +49,8 @@ @guidance_group.org_id = current_user.org_id @guidance_group.published = true unless params[:save_publish].nil? - if @guidance_group.update_attributes(params[:guidance_group]) - redirect_to admin_index_guidance_path(params[:guidance_group]), notice: success_message(_('guidance group'), _('saved')) + if @guidance_group.update(guidance_group_params) + redirect_to admin_index_guidance_path(guidance_group_params), notice: success_message(_('guidance group'), _('saved')) else flash[:alert] = failed_update_error(@guidance_group, _('guidance group')) render 'admin_edit' @@ -93,4 +93,10 @@ end end + private + + def guidance_group_params + params.require(:guidance_group) + .permit(:org_id, :name, :optional_subset, :published, :org, :guidances) + end end \ No newline at end of file diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 32211b3..061152b 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -6,31 +6,30 @@ def create @note = Note.new - @note.user_id = params[:note][:user_id] - - # create answer if we don't have one already - @answer = nil # if defined within the transaction block, was not accessable afterward + @note.user_id = note_params[:user_id] # ensure user has access to plan BEFORE creating/finding answer - raise Pundit::NotAuthorizedError unless Plan.find(params[:note][:plan_id]).readable_by?(@note.user_id) + unless Plan.find_by(id: note_params[:plan_id]).readable_by?(@note.user_id) + raise Pundit::NotAuthorizedError + end Answer.transaction do - @answer = Answer.find_by(plan_id: params[:note][:plan_id], question_id: params[:note][:question_id]) + @answer = Answer.find_by(plan_id: note_params[:plan_id], question_id: note_params[:question_id]) if @answer.blank? - @answer = Answer.new - @answer.plan_id = params[:note][:plan_id] - @answer.question_id = params[:note][:question_id] - @answer.user_id = @note.user_id + @answer = Answer.new + @answer.plan_id = note_params[:plan_id] + @answer.question_id = note_params[:question_id] + @answer.user_id = @note.user_id @answer.save! end end @note.answer = @answer - @note.text = params[:note][:text] + @note.text = note_params[:text] authorize @note @plan = @answer.plan - @question = Question.find(params[:note][:question_id]) + @question = Question.find(note_params[:question_id]) if @note.save @status = true @@ -43,11 +42,11 @@ @notice = success_message(_('comment'), _('created')) render(json: { "notes" => { - "id" => params[:note][:question_id], + "id" => note_params[:question_id], "html" => render_to_string(partial: 'layout', locals: {plan: @plan, question: @question, answer: @answer }, formats: [:html]) }, "title" => { - "id" => params[:note][:question_id], + "id" => note_params[:question_id], "html" => render_to_string(partial: 'title', locals: { answer: @answer}, formats: [:html]) } }.to_json, status: :created) @@ -63,7 +62,7 @@ def update @note = Note.find(params[:id]) authorize @note - @note.text = params[:note][:text] + @note.text = note_params[:text] @answer = @note.answer @question = @answer.question @@ -71,7 +70,7 @@ question_id = @note.answer.question_id.to_s - if @note.update_attributes(params[:note]) + if @note.update(note_params) @notice = success_message(_('comment'), _('saved')) render(json: { "notes" => { @@ -103,7 +102,7 @@ question_id = @note.answer.question_id.to_s - if @note.update_attributes(params[:note]) + if @note.update(note_params) @notice = success_message(_('comment'), _('removed')) render(json: { "notes" => { @@ -122,4 +121,12 @@ }.to_json, status: :bad_request end end + + private + + def note_params + params.require(:note) + .permit(:text, :archived_by, :user_id, :answer_id, :plan_id, + :question_id) + end end diff --git a/app/controllers/org_admin/questions_controller.rb b/app/controllers/org_admin/questions_controller.rb index 69d008b..f2d7ea3 100644 --- a/app/controllers/org_admin/questions_controller.rb +++ b/app/controllers/org_admin/questions_controller.rb @@ -122,32 +122,33 @@ end private - def question_params - params.require(:question).permit(:number, :text, :question_format_id, :option_comment_display, :default_value, question_options_attributes: [:id, :number, :text, :is_default, :_destroy], annotations_attributes: [:id, :text, :org_id, :org, :type], theme_ids: []) - end - # When a template gets versioned by changes to one of its questions we need to loop - # through the incoming params and ensure that the annotations and question_options - # get attached to the new question - def transfer_associations(question) - attrs = question_params - if attrs[:annotations_attributes].present? - attrs[:annotations_attributes].each_key do |key| - old_annotation = question.annotations.select do |a| - a.org_id.to_s == attrs[:annotations_attributes][key][:org_id] && a.type.to_s == attrs[:annotations_attributes][key][:type] - end - attrs[:annotations_attributes][key][:id] = old_annotation.first.id unless old_annotation.empty? + def question_params + params.require(:question).permit(:number, :text, :question_format_id, :option_comment_display, :default_value, question_options_attributes: [:id, :number, :text, :is_default, :_destroy], annotations_attributes: [:id, :text, :org_id, :org, :type], theme_ids: []) + end + + # When a template gets versioned by changes to one of its questions we need to loop + # through the incoming params and ensure that the annotations and question_options + # get attached to the new question + def transfer_associations(question) + attrs = question_params + if attrs[:annotations_attributes].present? + attrs[:annotations_attributes].each_key do |key| + old_annotation = question.annotations.select do |a| + a.org_id.to_s == attrs[:annotations_attributes][key][:org_id] && a.type.to_s == attrs[:annotations_attributes][key][:type] end + attrs[:annotations_attributes][key][:id] = old_annotation.first.id unless old_annotation.empty? end - # TODO: This question_options id swap feel fragile. We cannot really match on any of the - # data elements because the user may have changed them so we rely on its position - # within the array/query since they should be equivalent. - if attrs[:question_options_attributes].present? - attrs[:question_options_attributes].each_key do |key| - attrs[:question_options_attributes][key][:id] = question.question_options[key.to_i].id.to_s if question.question_options[key.to_i].present? - end - end - attrs end + # TODO: This question_options id swap feel fragile. We cannot really match on any of the + # data elements because the user may have changed them so we rely on its position + # within the array/query since they should be equivalent. + if attrs[:question_options_attributes].present? + attrs[:question_options_attributes].each_key do |key| + attrs[:question_options_attributes][key][:id] = question.question_options[key.to_i].id.to_s if question.question_options[key.to_i].present? + end + end + attrs + end end end diff --git a/app/models/answer.rb b/app/models/answer.rb index 4e8a3e5..750cac8 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -23,12 +23,6 @@ has_many :notes - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :text, :plan_id, :lock_version, :question_id, :user_id, :question_option_ids, - :question, :user, :plan, :question_options, :notes, :note_ids, :id, - :as => [:default, :admin] ## # Validations diff --git a/app/models/exported_plan.rb b/app/models/exported_plan.rb index c1825e2..c2e81f9 100644 --- a/app/models/exported_plan.rb +++ b/app/models/exported_plan.rb @@ -2,8 +2,6 @@ include GlobalHelpers include SettingsTemplateHelper -# TODO: REMOVE AND HANDLE ATTRIBUTE SECURITY IN THE CONTROLLER! - attr_accessible :plan_id, :user_id, :format, :user, :plan, :as => [:default, :admin] #associations between tables belongs_to :plan diff --git a/app/models/guidance_group.rb b/app/models/guidance_group.rb index b898ded..885236f 100644 --- a/app/models/guidance_group.rb +++ b/app/models/guidance_group.rb @@ -9,11 +9,6 @@ # has_and_belongs_to_many :guidances, join_table: "guidance_in_group" - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :org_id, :name, :optional_subset, :published, :org, :guidances, - :as => [:default, :admin] validates :name, :org, presence: {message: _("can't be blank")} diff --git a/app/models/note.rb b/app/models/note.rb index 4341c2a..d5f3e28 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -4,11 +4,7 @@ belongs_to :answer belongs_to :user - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :text, :user_id, :answer_id, :archived, :archived_by, - :answer, :user, :as => [:default, :admin] - + validates :text, :answer, :user, presence: {message: _("can't be blank")} + end diff --git a/app/models/org.rb b/app/models/org.rb index d095160..1c2436a 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -23,16 +23,6 @@ has_many :identifier_schemes, through: :org_identifiers ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :abbreviation, :logo, :remove_logo, - :logo_file_name, :name, :links, - :organisation_type_id, :wayfless_entity, :parent_id, :sort_name, - :token_permission_type_ids, :language_id, :contact_email, :contact_name, - :language, :org_type, :region, :token_permission_types, - :guidance_group_ids, :is_other, :region_id, :logo_uid, :logo_name, - :feedback_enabled, :feedback_email_subject, :feedback_email_msg - ## # Validators validates :name, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} # allow validations for logo upload diff --git a/app/models/perm.rb b/app/models/perm.rb index fcc429f..56f3a7c 100644 --- a/app/models/perm.rb +++ b/app/models/perm.rb @@ -3,13 +3,8 @@ # Associations has_and_belongs_to_many :users, :join_table => :users_perms - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - #attr_accessible :name, :as => [:default, :admin] - validates :name, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} - + scope :add_orgs, -> {Perm.find_by(name: 'add_organisations')} scope :change_affiliation, -> {Perm.find_by(name: 'change_org_affiliation')} scope :grant_permissions, -> {Perm.find_by(name: 'grant_permissions')} diff --git a/app/models/phase.rb b/app/models/phase.rb index 2612f3e..64dfa9b 100644 --- a/app/models/phase.rb +++ b/app/models/phase.rb @@ -13,22 +13,17 @@ belongs_to :template has_many :sections, -> { order(:number => :asc) }, dependent: :destroy - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :description, :number, :title, :template_id, - :template, :sections, :modifiable, :as => [:default, :admin] validates :title, :number, :template, presence: {message: _("can't be blank")} scope :titles, -> (template_id) { Phase.where(template_id: template_id).select(:id, :title) } - + # TODO: Remove after implementing new template versioning logic # Callbacks after_save do |phase| - # Updates the template.updated_at attribute whenever a phase has been created/updated + # Updates the template.updated_at attribute whenever a phase has been created/updated phase.template.touch if template.present? end @@ -37,7 +32,7 @@ copy.modifiable = options.fetch(:modifiable, self.modifiable) copy.template_id = options.fetch(:template_id, nil) copy.save!(validate:false) if options.fetch(:save, false) - options[:phase_id] = id + options[:phase_id] = copy.id self.sections.each{ |section| copy.sections << section.deep_copy(options) } return copy end @@ -47,7 +42,7 @@ def num_answered_questions(plan) return 0 if plan.nil? return sections.reduce(0) do |m, s| - m + s.num_answered_questions(plan) + m + s.num_answered_questions(plan) end end diff --git a/app/models/plan.rb b/app/models/plan.rb index fc40d41..b80b0c5 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -25,15 +25,6 @@ # has_many :users, through: :roles - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :locked, :project_id, :version_id, :version, :plan_sections, - :exported_plans, :project, :title, :template, :grant_number, - :identifier, :principal_investigator, :principal_investigator_identifier, - :description, :data_contact, :funder_name, :visibility, :exported_plans, - :roles, :users, :org, :data_contact_email, :data_contact_phone, :feedback_requested, - :principal_investigator_email, :as => [:default, :admin] accepts_nested_attributes_for :roles # public is a Ruby keyword so using publicly diff --git a/app/models/question.rb b/app/models/question.rb index 8a5a833..459c7d1 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -22,18 +22,9 @@ accepts_nested_attributes_for :question_options, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true accepts_nested_attributes_for :annotations, :allow_destroy => true - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :default_value, :dependency_id, :dependency_text, :guidance,:number, - :annotation, :text, :section_id, :question_format_id, - :question_options_attributes, :annotations_attributes, - :option_comment_display, :theme_ids, :section, :question_format, - :question_options, :annotations, :answers, :themes, - :modifiable, :option_comment_display, :as => [:default, :admin] validates :text, :section, :number, presence: {message: _("can't be blank")} - + ## # returns the text from the question # @@ -58,7 +49,7 @@ self.themes.each{ |theme| copy.themes << theme } return copy end - + # TODO: consider moving this to a view helper instead and use the built in scopes for guidance. May need to add # a new one for 'thematic_guidance'. This method doesn't even make reference to this class and its returning # a hash that is specific to a view diff --git a/app/models/question_format.rb b/app/models/question_format.rb index b6d1e36..4ca045b 100644 --- a/app/models/question_format.rb +++ b/app/models/question_format.rb @@ -5,14 +5,9 @@ has_many :questions enum formattype: [ :textarea, :textfield, :radiobuttons, :checkbox, :dropdown, :multiselectbox, :date, :rda_metadata ] - attr_accessible :formattype validates :title, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :title, :description, :option_based, :questions, :as => [:default, :admin] # Retrieves the id for a given formattype passed scope :id_for, -> (formattype) { where(formattype: formattype).pluck(:id).first } diff --git a/app/models/question_option.rb b/app/models/question_option.rb index 3eeb7e5..c2be0a4 100644 --- a/app/models/question_option.rb +++ b/app/models/question_option.rb @@ -4,11 +4,6 @@ belongs_to :question has_and_belongs_to_many :answers, join_table: :answers_question_options - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :text, :question_id, :is_default, :number, :question, - :as => [:default, :admin] validates :text, :question, :number, presence: {message: _("can't be blank")} diff --git a/app/models/section.rb b/app/models/section.rb index cf9282a..c807015 100644 --- a/app/models/section.rb +++ b/app/models/section.rb @@ -9,10 +9,6 @@ #Link the data accepts_nested_attributes_for :questions, :reject_if => lambda {|a| a[:text].blank? }, :allow_destroy => true - attr_accessible :phase_id, :description, :number, :title, :published, - :questions_attributes, :organisation, :phase, :modifiable, - :as => [:default, :admin] - validates :phase, :title, :number, presence: {message: _("can't be blank")} before_validation :set_defaults @@ -42,7 +38,7 @@ copy.modifiable = options.fetch(:modifiable, self.modifiable) copy.phase_id = options.fetch(:phase_id, nil) copy.save!(validate: false) if options.fetch(:save, false) - options[:section_id] = id + options[:section_id] = copy.id self.questions.map{ |question| copy.questions << question.deep_copy(options) } return copy end diff --git a/app/models/settings/template.rb b/app/models/settings/template.rb index d27957f..9d4969c 100644 --- a/app/models/settings/template.rb +++ b/app/models/settings/template.rb @@ -1,8 +1,6 @@ module Settings class Template < RailsSettings::SettingObject - #attr_accessible :var, :target, :target_id, :target_type - VALID_FONT_FACES = [ '"Times New Roman", Times, Serif', 'Arial, Helvetica, Sans-Serif' diff --git a/app/models/splash_log.rb b/app/models/splash_log.rb index 43dcc4d..307933f 100644 --- a/app/models/splash_log.rb +++ b/app/models/splash_log.rb @@ -1,3 +1,2 @@ class SplashLog < ActiveRecord::Base - #attr_accessible :destination end diff --git a/app/models/template.rb b/app/models/template.rb index 42ef769..edd7a30 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -18,6 +18,7 @@ has_many :phases, dependent: :destroy has_many :sections, through: :phases has_many :questions, through: :sections + has_many :annotations, through: :questions # ========== # = Scopes = @@ -136,13 +137,6 @@ { term: "%#{term}%" }) } - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :id, :org_id, :description, :published, :title, :locale, :customization_of, - :is_default, :guidance_group_ids, :org, :plans, :phases, :family_id, - :archived, :version, :visibility, :published, :links, :as => [:default, :admin] - # A standard template should be organisationally visible. Funder templates that are # meant for external use will be publicly visible. This allows a funder to create 'funder' as # well as organisational templates. The default template should also always be publicly_visible @@ -157,9 +151,11 @@ # Class methods gets defined within this class << self + def current(family_id) unarchived.where(family_id: family_id).order(version: :desc).first end + def live(family_id) if family_id.respond_to?(:each) unarchived.where(family_id: family_id, published: true) @@ -167,14 +163,15 @@ unarchived.where(family_id: family_id, published: true).first end end + def find_or_generate_version!(template) - if template.latest? - if template.generate_version? - return template.generate_version! - end - return template + if template.latest? && template.generate_version? + template.generate_version! + elsif template.latest? && !template.generate_version? + template + else + raise _('A historical template cannot be retrieved for being modified') end - raise _('A historical template cannot be retrieved for being modified') end end diff --git a/app/models/theme.rb b/app/models/theme.rb index 4f0738e..42e3266 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -5,13 +5,6 @@ has_and_belongs_to_many :questions, join_table: "questions_themes" has_and_belongs_to_many :guidances, join_table: "themes_in_guidance" - ## - # Possibly needed for active_admin - # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :guidance_ids , :as => [:default, :admin] - attr_accessible :question_ids, :as => [:default, :admin] - attr_accessible :description, :title, :locale , :as => [:default, :admin] - validates :title, presence: {message: _("can't be blank")} diff --git a/app/models/token_permission_type.rb b/app/models/token_permission_type.rb index 5770e6c..7ffa06a 100644 --- a/app/models/token_permission_type.rb +++ b/app/models/token_permission_type.rb @@ -6,11 +6,6 @@ has_and_belongs_to_many :orgs, join_table: 'org_token_permissions', unique: true ## - # Possibly needed for active_admin - # - relies on proetected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :token_type, :text_description, :as => [:default, :admin] - - ## # Validators validates :token_type, presence: {message: _("can't be blank")}, uniqueness: {message: _("must be unique")} diff --git a/config/environments/development.rb b/config/environments/development.rb index 4e6f302..16c5a81 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -31,9 +31,6 @@ # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - config.action_mailer.perform_deliveries = false BetterErrors::Midleware.allow_ip! "10.0.2.2" if defined?(BetterErrors) && Rails.env == :development diff --git a/db/seeds.rb b/db/seeds.rb index f41156e..1eed058 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -354,8 +354,6 @@ org: Org.find_by(abbreviation: Rails.configuration.branding[:organisation][:abbreviation]), is_default: true, version: 0, - migrated: false, - dmptemplate_id: 1, visibility: Template.visibilities[:publicly_visible], links: {"funder":[],"sample_plan":[]}}, @@ -364,9 +362,7 @@ org: Org.find_by(abbreviation: 'GA'), is_default: false, version: 0, - migrated: false, visibility: Template.visibilities[:organisationally_visible], - dmptemplate_id: 2, links: {"funder":[],"sample_plan":[]}}, {title: "Department of Testing Award", @@ -374,9 +370,7 @@ org: Org.find_by(abbreviation: 'GA'), is_default: false, version: 0, - migrated: false, visibility: Template.visibilities[:organisationally_visible], - dmptemplate_id: 3, links: {"funder":[],"sample_plan":[]}} ] # Template creation calls defaults handler which sets is_default and diff --git a/test/functional/notes_controller_test.rb b/test/functional/notes_controller_test.rb index da3cb39..2dff33a 100644 --- a/test/functional/notes_controller_test.rb +++ b/test/functional/notes_controller_test.rb @@ -12,14 +12,13 @@ @plan.assign_reader(@user.id) @plan.save! - @question = Question.create(text: 'Answer Testing', number: 9, + @question = Question.create!(text: 'Answer Testing', number: 9, section: @plan.template.phases.first.sections.first, question_format: QuestionFormat.find_by(option_based: false)) - @answer = Answer.create(user: @user, plan: @plan, question: @question, text: 'Testing') + @answer = Answer.create!(user: @user, plan: @plan, question: @question, text: 'Testing') - @note = Note.create(user: @user, plan: @plan, answer: @answer, question: @question, archived: false, - text: 'Test Note') + @note = Note.create!(user: @user, answer: @answer, archived: false, text: 'Test Note') end # TODO: The following methods SHOULD probably be restful @@ -45,10 +44,16 @@ # POST /notes (notes_path) # ---------------------------------------------------------- test "create a new note" do - params = {user_id: @user.id, answer_id: @answer.id, plan_id: @plan.id, question_id: @question.id, text: 'Test Note'} + params = { + user_id: @user.id, + answer_id: @answer.id, + plan_id: @plan.id, + question_id: @question.id, + text: 'Test Note' + } # Should redirect user to the root path if they are not logged in! - post notes_path, {note: params} + post notes_path, { note: params } assert_unauthorized_redirect_to_root_path sign_in @user diff --git a/test/functional/org_admin/plans_controller_test.rb b/test/functional/org_admin/plans_controller_test.rb index cb3d50e..c2c7213 100644 --- a/test/functional/org_admin/plans_controller_test.rb +++ b/test/functional/org_admin/plans_controller_test.rb @@ -7,21 +7,21 @@ setup do # Get the first Org Admin @org = Org.funder.first - @admin = User.create!(email: "org-admin-plans-tester@example.com", + @admin = User.create!(email: "org-admin-plans-tester@example.com", firstname: "Org", surname: "Admin", password: "password123", password_confirmation: "password123", org: @org, accept_terms: true, confirmed_at: Time.zone.now) - + # Make sure the user is an org admin - @admin.perms << Perm.where(name: ['grant_permissions', 'modify_guidance', + @admin.perms << Perm.where(name: ['grant_permissions', 'modify_guidance', 'modify_templates', 'change_org_details']) @admin.save! - + @regular_user = User.create!(email: 'org_admin_plans_tester@example.com', firstname: "Tester", surname: "Testing", password: "password123", password_confirmation: "password123", - org: @org, accept_terms: true, confirmed_at: Time.zone.now, ) - @plan = Plan.create!(template: Template.first, title: 'Test Plan', visibility: :privately_visible, feedback_requested: true, - roles: [Role.new(user: @regular_user, creator: true)]) + org: @org, accept_terms: true, confirmed_at: Time.zone.now, ) + @plan = Plan.create!(template: Template.first, title: 'Test Plan', visibility: :privately_visible, feedback_requested: true) + @plan.roles.create!(user: @regular_user, creator: true) Role.create!(user: @admin, plan: @plan, access: Role.access_values_for(:reviewer).min) end @@ -34,7 +34,7 @@ get org_admin_plans_path assert_authorized_redirect_to_plans_page end - + test "org admin can access the plans page" do sign_in @admin get org_admin_plans_path @@ -53,18 +53,18 @@ get feedback_complete_org_admin_plan_path(@plan) assert_authorized_redirect_to_plans_page end - + test "org admin can complete feedback" do sign_in @admin get feedback_complete_org_admin_plan_path(@plan) assert_response :redirect - + # TODO: This one is failing on Travis but not on any other machine # seems to be due to the seeds.rb not loading properly on the # latest instance of Travis #assert_redirected_to org_admin_plans_path end - + test "unauthorized user cannot download the plans as CSV" do # Should redirect user to the root path if they are not logged in! get org_admin_download_plans_path(format: :csv) @@ -74,7 +74,7 @@ get org_admin_download_plans_path(format: :csv) assert_authorized_redirect_to_plans_page end - + test "org admin can download plans as CSV" do sign_in @admin get org_admin_download_plans_path(format: :csv) diff --git a/test/functional/org_admin/questions_controller_test.rb b/test/functional/org_admin/questions_controller_test.rb index 1324e3f..8348ae4 100644 --- a/test/functional/org_admin/questions_controller_test.rb +++ b/test/functional/org_admin/questions_controller_test.rb @@ -1,16 +1,16 @@ require 'test_helper' class QuestionsControllerTest < ActionDispatch::IntegrationTest - + include Devise::Test::IntegrationHelpers - + setup do @institution = init_institution @researcher = init_researcher(@institution) @org_admin = init_org_admin(@institution) @template = init_template(@institution, { - title: 'Test Template', - published: true, + title: 'Test Template', + published: true, visibility: Template.visibilities[:publicly_visible] }) @phase = init_phase(@template) @@ -18,7 +18,7 @@ @text_area = init_question_format({ title: 'Test question format' }) @question = init_question(@section) end - + test 'unauthorized user cannot call question_controller#create' do params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } } post org_admin_template_phase_section_questions_path(@template, @phase, @section), params @@ -27,7 +27,7 @@ post org_admin_template_phase_section_questions_path(@template, @phase, @section), params assert_authorized_redirect_to_plans_page end - + test 'unauthorized user cannot call question_controller#create for another org\'s template' do params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } } funder = init_funder @@ -38,7 +38,7 @@ post org_admin_template_phase_section_questions_path(funder_template, funder_phase, funder_section), params assert_authorized_redirect_to_plans_page end - + test 'authorized user can call question_controller#create for an unpublished template' do @template.update!(published: false) params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } } @@ -47,7 +47,7 @@ assert_response :redirect assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @section.id) end - + test 'authorized user can call question_controller#create for a published template' do params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } } sign_in @org_admin @@ -56,7 +56,7 @@ template = Template.latest_version(@template.family_id).first assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.first.id) end - + test 'unauthorized user cannot call question_controller#edit' do params = { section: { text: 'Edited question' } } put org_admin_template_phase_section_question_path(@template, @phase, @section, @question), params @@ -77,7 +77,7 @@ put org_admin_template_phase_section_question_path(funder_template, funder_phase, funder_section, funder_question), params assert_authorized_redirect_to_plans_page end - + test 'authorized user can call question_controller#edit for an unpublished template' do @template.update!(published: false) params = { section: { text: 'Edited question' } } @@ -86,7 +86,7 @@ assert_response :redirect assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @section.id) end - + test 'authorized user can call question_controller#edit for a published template' do params = { section: { text: 'Edited question' } } sign_in @org_admin @@ -103,7 +103,7 @@ delete org_admin_template_phase_section_question_path(@template, @phase, @section, @question) assert_authorized_redirect_to_plans_page end - + test 'unauthorized user cannot call question_controller#destroy for another org\'s template' do funder = init_funder funder_template = init_template(funder) @@ -114,7 +114,7 @@ delete org_admin_template_phase_section_question_path(funder_template, funder_phase, funder_section, funder_question) assert_authorized_redirect_to_plans_page end - + test 'authorized user can call question_controller#destroy for an unpublished template' do @template.update!(published: false) sign_in @org_admin @@ -122,12 +122,16 @@ assert_response :redirect assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @section.id) end - + test 'authorized user can call question_controller#destroy for a published template' do sign_in @org_admin delete org_admin_template_phase_section_question_path(@template, @phase, @section, @question) assert_response :redirect template = Template.latest_version(@template.family_id).first - assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.first.id) + assert_redirected_to edit_org_admin_template_phase_path({ + id: template.phases.first.id, + template_id: template.id, + section: template.phases.first.sections.first.id + }) end end \ No newline at end of file diff --git a/test/functional/public_pages_controller_test.rb b/test/functional/public_pages_controller_test.rb index 9531032..1f5d95e 100644 --- a/test/functional/public_pages_controller_test.rb +++ b/test/functional/public_pages_controller_test.rb @@ -3,18 +3,19 @@ class PublicPagesControllerTest < ActionDispatch::IntegrationTest include Devise::Test::IntegrationHelpers - + setup do @org = Org.first scaffold_plan - + @plan.visibility = :publicly_visible @plan.save - + @non_public_plans = [] [:privately_visible, :organisationally_visible, :is_test].each do |vis| - @non_public_plans << Plan.create(template: @template, title: "#{vis} Plan", visibility: vis, - roles: [Role.new(user: User.last, creator: true)]) + plan = Plan.create!(template: @template, title: "#{vis} Plan", visibility: vis) + plan.roles.create!(user: User.last, creator: true) + @non_public_plans << plan end @inst_tmplt = Template.create!(title: 'Inst template', org: Org.institution.first, archived: false, published: true) @@ -42,7 +43,7 @@ @non_public_plans.each do |plan| assert_not @response.body.include?(plan_export_path(plan)), "expected to NOT see the on-public plan download link when NOT logged in" end - + # Verify the same results are received when the user is logged in sign_in @user get public_plans_path @@ -53,7 +54,7 @@ assert_not @response.body.include?(plan_export_path(plan)), "expected to NOT see the on-public plan download link when NOT logged in" end end - + # TODO: Need to install the wkhtmltopdf library on Travis for this to work! # GET /plan_export/:id (plan_export_path) # ---------------------------------------------------------- @@ -68,11 +69,11 @@ # assert_redirected_to root_path # end end - + # GET /public_templates (public_templates_path) # ---------------------------------------------------------- test 'load the list of public templates page' do - # Verify that public templates are visible when not logged in and that non-funder and non-default + # Verify that public templates are visible when not logged in and that non-funder and non-default # templates are NOT in the list get public_templates_path assert_response :success @@ -90,7 +91,7 @@ assert @response.body.include?(template_export_path(@dflt_tmplt.family_id)), "expected to see the default template download link when NOT logged in" assert_not @response.body.include?(template_export_path(@inst_tmplt.family_id)), "expected to NOT see the institution template download link when NOT logged in" end - + # TODO: Need to install the wkhtmltopdf library on Travis for this to work! # GET /template_export/:family_id (template_export_path) # ---------------------------------------------------------- diff --git a/test/test_helper.rb b/test/test_helper.rb index 4127f42..e4efa3d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -392,15 +392,18 @@ # ---------------------------------------------------------------------- def scaffold_plan scaffold_template if @template.nil? - - @plan = Plan.new(template: @template, title: 'Test Plan', grant_number: 'Grant-123', - principal_investigator: 'me', principal_investigator_identifier: 'me-1234', - description: "this is my plan's informative description", - identifier: '1234567890', data_contact: 'me@example.com', visibility: :privately_visible, - roles: [Role.new(user: User.last, creator: true)]) - - assert @plan.valid?, "unable to create new Plan: #{@plan.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - @plan.save! + @plan = Plan.create!( + template: @template, + title: 'Test Plan', + grant_number: 'Grant-123', + principal_investigator: 'me', + principal_investigator_identifier: 'me-1234', + description: "this is my plan's informative description", + identifier: '1234567890', + data_contact: 'me@example.com', + visibility: :privately_visible + ) + @plan.roles.create(user: User.last, creator: true) end diff --git a/test/unit/concerns/versionable_test.rb b/test/unit/concerns/versionable_test.rb index 60391ec..429b680 100644 --- a/test/unit/concerns/versionable_test.rb +++ b/test/unit/concerns/versionable_test.rb @@ -6,30 +6,35 @@ setup do @template = create_template end + def create_template - funder = init_funder + funder = init_funder template = init_template(funder) - phase = init_phase(template) - section = init_section(phase) + phase = init_phase(template) + section = init_section(phase) question = init_question(section) init_annotation(funder, question) return template end + test "versionable concern is included" do assert(self.respond_to?(:get_modifiable)) end + test "#find_in_space raises ArgumentError when search_scape does not respond_to to each" do exception = assert_raises(ArgumentError) do find_in_space(nil, nil) end assert_equal(_('The search_space does not respond to each'), exception.message) end + test "#find_in_space raises ArgumentError when search_scape does not have elements" do exception = assert_raises(ArgumentError) do find_in_space(nil, []) end assert_equal(_('The search space does not have elements associated'), exception.message) end + test "#find_in_space looks for the object in the search_scape that has elements of its same class" do # Looking for phase phase = init_phase(@template) @@ -59,6 +64,7 @@ # Looking for something else assert_not(find_in_space({}, [{}])) end + test "#find_in_space looks for the object in the relation" do # Looking for section section = init_section(@template.phases.first) @@ -75,6 +81,7 @@ # Looking for a question in a not known search_space assert_not(find_in_space(Question.new, [{}])) end + test "#find_in_space looks for an object that does not belong to the hierarchy" do question = init_question(@template.phases.first.sections.first) question.phase.number = 2 @@ -175,7 +182,7 @@ @template.phases.first.sections.first.questions.first, @template.phases.first.sections.first.questions.first.annotations.first ] - + hierarchy_objects.each do |obj| exception = assert_raises(RuntimeError) do get_modifiable(obj) @@ -228,21 +235,22 @@ test "#get_modifiable returns new question when template is published" do @template.published = true @template.save! - question = @template.phases.first.sections.first.questions.first + question = @template.phases.first.sections.first.questions.first new_question = get_modifiable(question) - assert_not_equal(question.id, new_question.id, 'returns different question id') - assert_not_equal(question.section.phase.template, new_question.section.phase.template, 'returns different template belonging') + refute_equal(question.id, new_question.id, 'returns different question id') + refute_equal(question.section.phase.template, new_question.section.phase.template, 'returns different template belonging') end test "#get_modifiable returns new annotation when template is published" do @template.published = true @template.save! - annotation = @template.phases.first.sections.first.questions.first.annotations.first - new_annotation = get_modifiable(annotation) - assert_not_equal(annotation.id, new_annotation.id, 'returns different annotation id') - assert_not_equal(annotation.question.section.phase.template, new_annotation.question.section.phase.template, 'returns different template belonging') + @annotation = @template.phases.first.sections.first.questions.first.annotations.first + @new_annotation = get_modifiable(@annotation) + @new_template = @new_annotation.question.section.phase.template + refute_equal(@annotation, @new_annotation, 'returns different annotation id') + refute_equal(@template, @new_template, 'returns different template belonging') end - + test "#get_modifiable returns new question_option when template is published" do @template.published = true @template.save! @@ -254,4 +262,4 @@ assert_not_equal(question_option.id, new_question_option.id, 'returns different question_option id') assert_not_equal(question_option.question.section.phase.template, new_question_option.question.section.phase.template, 'returns different template belonging') end -end \ No newline at end of file +end diff --git a/test/unit/plan_test.rb b/test/unit/plan_test.rb index 9d84917..1b03fa6 100644 --- a/test/unit/plan_test.rb +++ b/test/unit/plan_test.rb @@ -313,8 +313,8 @@ # --------------------------------------------------- test "can CRUD Plan" do - obj = Plan.create(title: 'Testing CRUD', template: Template.where.not(id: @template.id).first, visibility: :is_test, - roles: [Role.new(user: User.last, creator: true)], description: "should change") + obj = Plan.create!(title: 'Testing CRUD', template: Template.where.not(id: @template.id).first, visibility: :is_test, description: "should change") + obj.roles.create!(user: User.last, creator: true) assert_not obj.id.nil?, "was expecting to be able to create a new Plan! - #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" obj.description = 'changed' diff --git a/test/unit/question_test.rb b/test/unit/question_test.rb index c6b3066..0035c97 100644 --- a/test/unit/question_test.rb +++ b/test/unit/question_test.rb @@ -4,7 +4,7 @@ setup do # Need to clear the tables until we get seed.rb out of test_helper.rb - Template.delete_all + Template.delete_all @funder = init_funder @institution = init_institution @template = init_template(@institution, published: true) @@ -30,23 +30,23 @@ test "option_based? returns the correct boolean value" do assert_not @question.option_based? -# TODO: replace with a call to the init_question_format factory method once seeds.rb is no longer being loaded +# TODO: replace with a call to the init_question_format factory method once seeds.rb is no longer being loaded @question.question_format = QuestionFormat.find_by(option_based: true) @question.save! assert @question.option_based? end - + test "#deep_copy creates a new question object and attaches new annotations/question_options objects" do init_annotation(@institution, @question) init_question_option(@question) assert_deep_copy(@question, @question.deep_copy, relations: [:annotations, :question_options]) end - + # TODO: This method should get moved to a view helper instead test "returns the correct themed guidance for the org" do theme = init_theme guidance_group = init_guidance_group(@institution) - funder_guidance_group = init_guidance_group(@funder, { title: 'Test funder guidance group' } ) + funder_guidance_group = init_guidance_group(@funder, { name: 'Test funder guidance group' } ) guidance = init_guidance(guidance_group, { themes: [theme] }) funder_guidance = init_guidance(funder_guidance_group, { themes: [theme] }) @@ -63,14 +63,14 @@ assert_equal 1, funder_guidances.length assert_equal funder_guidance, funder_guidances.first.last end - + # --------------------------------------------------- test "returns the correct annotation for the org" do annotation = init_annotation(@institution, @question, { type: Annotation.types[:example_answer] }) annotation2 = init_annotation(@institution, @question) funder_annotation = init_annotation(@funder, @question, { text: 'Test funder example answer', type: Annotation.types[:example_answer] } ) funder_annotation2 = init_annotation(@funder, @question, { text: 'Test funder guidance'} ) - + institutional_annotations = @question.get_example_answers(@institution) assert_equal 1, institutional_annotations.length assert_equal annotation, institutional_annotations.first