diff --git a/app/models/answer.rb b/app/models/answer.rb index f8b0d65..ebc583c 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -7,11 +7,14 @@ belongs_to :plan has_and_belongs_to_many :question_options, join_table: "answers_question_options" + 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, :question_id, :user_id, :question_option_ids, - :question, :user, :plan, :question_options, :as => [:default, :admin] + :question, :user, :plan, :question_options, :notes, :note_ids, + :as => [:default, :admin] ## # Validations @@ -19,7 +22,7 @@ # Make sure there is only one answer per question! validates :question, uniqueness: {scope: [:plan], - message: I18n.t('helpers.errors.answer.only_one_per_question')} + message: I18n.t('helpers.answer.only_one_per_question')} # The answer MUST have a text value if the question is NOT option based or a question_option if # it is option based. @@ -29,4 +32,7 @@ validates :question_options, presence: true, if: Proc.new{|a| (a.question.nil? ? false : a.question.question_format.option_based?) } + + # Make sure the plan and question are associated with the same template! + validates :plan, :question, answer_for_correct_template: true end diff --git a/app/models/exported_plan.rb b/app/models/exported_plan.rb index e1b18fb..eb57e5c 100644 --- a/app/models/exported_plan.rb +++ b/app/models/exported_plan.rb @@ -16,17 +16,17 @@ # Store settings with the exported plan so it can be recreated later # if necessary (otherwise the settings associated with the plan at a # given time can be lost) - has_settings :export, class_name: 'Settings::Dmptemplate' do |s| - s.key :export, defaults: Settings::Dmptemplate::DEFAULT_SETTINGS + has_settings :export, class_name: 'Settings::Template' do |s| + s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS end # TODO: Consider removing the accessor methods, they add no value. The view/controller could # just access the value directly from the project/plan: exported_plan.plan.project.title - # Getters to match Settings::Dmptemplate::VALID_ADMIN_FIELDS + # Getters to match Settings::Template::VALID_ADMIN_FIELDS def project_name name = self.plan.project.title - name += " - #{self.plan.title}" if self.plan.project.dmptemplate.phases.count > 1 + name += " - #{self.plan.title}" if self.plan.project.template.phases.count > 1 name end @@ -51,7 +51,7 @@ end def funder - org = self.plan.project.dmptemplate.try(:organisation) + org = self.plan.project.template.try(:organisation) org.name if org.present? && org.organisation_type.try(:name) == constant("organisation_types.funder") end diff --git a/app/models/file_upload.rb b/app/models/file_upload.rb deleted file mode 100644 index eef1ca3..0000000 --- a/app/models/file_upload.rb +++ /dev/null @@ -1,5 +0,0 @@ -class FileUpload < ActiveRecord::Base - ## - # Associations - belongs_to :file_type -end diff --git a/app/models/guidance.rb b/app/models/guidance.rb index c2f93fb..31f9012 100644 --- a/app/models/guidance.rb +++ b/app/models/guidance.rb @@ -13,7 +13,7 @@ ## # Associations belongs_to :guidance_group - belongs_to :question +# belongs_to :question has_and_belongs_to_many :themes, join_table: "themes_in_guidance" @@ -34,9 +34,11 @@ # @param org_id [Integer] the integer id for an organisation # @return [Boolean] true if this guidance is in a group belonging to the specified organisation, false otherwise def in_group_belonging_to?(org_id) - if guidance_group.org_id == org_id - return true - end + unless guidance_group.nil? + if guidance_group.org.id == org_id + return true + end + end return false end @@ -45,7 +47,7 @@ # # @param org_id [Integer] the integer id for an organisation # @return [Array] list of guidance - def self.by_organisation(org_id) + def self.by_org(org_id) org_guidance = [] # TODO: re-write below querry when guidance_in_group removed from model Org.find_by(id: org_id).guidance_groups.each do |group| @@ -84,27 +86,24 @@ guidance = Guidance.find_by(id: id) viewable = false - # guidances may belong to many guidance groups, so we check the above case for each - guidance.guidance_groups.each do |guidance_group| - - # guidances are viewable if they are owned by any of the user's organisations - user.org do |org| - if guidance_group.org.id == org.id + unless guidance.nil? + unless guidance.guidance_group.nil? + # guidances are viewable if they are owned by any of the user's organisations + if guidance.guidance_group.org == user.org + viewable = true + end + # guidance groups are viewable if they are owned by the Managing Curation Center + if Org.managing_orgs.include?(guidance.guidance_group.org) + viewable = true + end + + # guidance groups are viewable if they are owned by a funder + if Org.funders.include?(guidance.guidance_group.org) viewable = true end end - - # guidance groups are viewable if they are owned by the Managing Curation Center - if guidance_group.organisation.id == Org.find_by( name: GlobalHelpers.constant("organisation_types.managing_organisation")).id - viewable = true - end - - # guidance groups are viewable if they are owned by a funder - if guidance_group.organisation.organisation_type == OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) - viewable = true - end end - + return viewable end @@ -118,20 +117,20 @@ # @param user [User] a user object # @return [Array] a list of all "viewable" guidances to a user def self.all_viewable(user) - managing_groups = (Org.find_by name: GlobalHelpers.constant("organisation_types.managing_organisation")).guidance_groups + managing_groups = Org.managing_orgs.collect{|o| o.guidance_groups} # find all groups owned by a Funder organisation funder_groups = [] - funders = OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) - funders.organisations.each do |funder| + funders = Org.funders + funders.each do |funder| funder_groups += funder.guidance_groups end # find all groups owned by any of the user's organisations - organisation_groups = user.organisation.guidance_groups + organisation_groups = user.org.guidance_groups # find all guidances belonging to any of the viewable groups all_viewable_guidances = [] all_viewable_groups = managing_groups + funder_groups + organisation_groups - all_viewable_groups.each do |group| + all_viewable_groups.flatten.each do |group| all_viewable_guidances += group.guidances end # pass the list of viewable guidances to the view diff --git a/app/models/guidance_group.rb b/app/models/guidance_group.rb index cc4bd8f..afcb456 100644 --- a/app/models/guidance_group.rb +++ b/app/models/guidance_group.rb @@ -10,11 +10,10 @@ ## # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :organisation_id, :name, :optional_subset, :published, - :org, :as => [:default, :admin] - attr_accessible :dmptemplate_ids, :as => [:default, :admin] + attr_accessible :org_id, :name, :optional_subset, :published, :org, :guidances, + :as => [:default, :admin] - + validates :name, :org, presence: true # EVALUATE CLASS AND INSTANCE METHODS BELOW @@ -24,16 +23,7 @@ - - validates :name, :org, presence: true - - ## - # Converts a guidance group to a string containing the display name - # - # @return [String] the name of the organisation, with or without the name of the guidance group - def to_s - "#{display_name}" - end + ## # Converts the current guidance group to a string containing the display name. @@ -42,27 +32,33 @@ # organisation followed by the name of the guidance group. # # @return [String] the display name for the guidance group - def display_name - if organisation.guidance_groups.count > 1 - return "#{organisation.name}: #{name}" - else - return organisation.name - end - end + def display_name + if org.guidance_groups.count > 1 + return "#{org.name}: #{name}" + else + return org.name + end + end ## # Returns the list of all guidance groups not coming from the given organisations # # @param excluded_orgs [Array] a list of organisations to exclude in the result # @return [Array] a list of guidance groups - def self.guidance_groups_excluding(excluded_orgs) - excluded_org_ids = Array.new - excluded_orgs.each do |org| - excluded_org_ids << org.id - end - return_orgs = GuidanceGroup.where("organisation_id NOT IN (?)", excluded_org_ids) - return return_orgs - end + def self.guidance_groups_excluding(excluded_orgs) + excluded_org_ids = Array.new + + if excluded_orgs.is_a?(Array) + excluded_orgs.each do |org| + excluded_org_ids << org.id + end + else + excluded_org_ids << excluded_orgs + end + + return_orgs = GuidanceGroup.where("org_id NOT IN (?)", excluded_org_ids) + return return_orgs + end ## # Returns whether or not a given user can view a given guidance group @@ -79,17 +75,17 @@ viewable = false # groups are viewable if they are owned by any of the user's organisations - if guidance_group.organisation == user.organisation + if guidance_group.org == user.org viewable = true end # groups are viewable if they are owned by the managing curation center Org.where( name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_group| - if guidance_group.organisation.id == managing_group.id + if guidance_group.org.id == managing_group.id viewable = true end end # groups are viewable if they are owned by a funder - if guidance_group.organisation.organisation_type == OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) + if guidance_group.org.org_type == 2 viewable = true end @@ -108,17 +104,17 @@ def self.all_viewable(user) # first find all groups owned by the Managing Curation Center managing_org_groups = [] - Org.where( name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_org| + Org.where(name: GlobalHelpers.constant("organisation_types.managing_organisation")).find_each do |managing_org| managing_org_groups = managing_org_groups + managing_org.guidance_groups end # find all groups owned by a Funder organisation funder_groups = [] - funders = OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder")) - funders.organisations.each do |funder| + funders = Org.where(org_type: 2) + funders.each do |funder| funder_groups = funder_groups + funder.guidance_groups end - organisation_groups = [user.organisation.guidance_groups] + organisation_groups = [user.org.guidance_groups] # pass this organisation guidance groups to the view with respond_with @all_viewable_groups all_viewable_groups = managing_org_groups + funder_groups + organisation_groups diff --git a/app/models/note.rb b/app/models/note.rb index fc0b3ba..74b3078 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -7,6 +7,8 @@ ## # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 - attr_accessible :question_id, :text, :user_id, :archived, :plan_id, :archived_by, + attr_accessible :text, :user_id, :answer_id, :archived, :archived_by, :answer, :user, :as => [:default, :admin] + + validates :text, :answer, :user, presence: true end diff --git a/app/models/org.rb b/app/models/org.rb index 83899ae..1e6764d 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -46,6 +46,9 @@ 6 => :school, column: 'org_type' + # Predefined queries for retrieving the managain organisation and funders + scope :managing_orgs, -> { where(name: GlobalHelpers.constant("organisation_types.managing_organisation")) } + scope :funders, -> { where(org_type: 2) } # EVALUATE CLASS AND INSTANCE METHODS BELOW diff --git a/app/models/perm.rb b/app/models/perm.rb index 7d17efb..114c0f0 100644 --- a/app/models/perm.rb +++ b/app/models/perm.rb @@ -7,4 +7,6 @@ # 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: true, uniqueness: true end diff --git a/app/models/phase.rb b/app/models/phase.rb index fa5109c..49029f8 100644 --- a/app/models/phase.rb +++ b/app/models/phase.rb @@ -23,6 +23,7 @@ friendly_id :title, use: [:slugged, :history, :finders] + validates :title, :number, :template, presence: true @@ -45,20 +46,21 @@ "#{title}" end +# TODO: This function does not belong here anymore. It may be useless now. ## # returns either the latest published version of this phase # also serves to verify if this phase has any published versions as returns nil # if there are no published versions # # @return [Version, nil] - def latest_published_version - pub_vers = versions.where('published = ?', true).order('updated_at DESC') - if pub_vers.any?() then - return pub_vers.first - else - return nil - end - end +# def latest_published_version +# pub_vers = versions.where('published = ?', true).order('updated_at DESC') +# if pub_vers.any?() then +# return pub_vers.first +# else +# return nil +# end +# end # TODO: reevaluate this method. It seems like the 1st query is unecessary ## diff --git a/app/models/plan.rb b/app/models/plan.rb index d1729e8..eba48ae 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -6,35 +6,40 @@ has_many :sections, through: :phases has_many :questions, through: :sections has_many :answers + has_many :roles has_many :notes, through: :answers has_many :users, through: :roles + has_many :exported_plans ## # 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, + 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, - :as => [:default, :admin] + :description, :data_contact, :funder_name, :visibility, :exported_plans, + :roles, :users, :as => [:default, :admin] + accepts_nested_attributes_for :roles # public is a Ruby keyword so using publicly enum visibility: [:organisationally_visible, :publicly_visible, :is_test, :privately_visible] + validates :template, :title, :users, presence: true + ## # Constants - A4_PAGE_HEIGHT = 297 #(in mm) - A4_PAGE_WIDTH = 210 #(in mm) - ROUNDING = 5 #round estimate up to nearest 5% - FONT_HEIGHT_CONVERSION_FACTOR = 0.35278 #convert font point size to mm - FONT_WIDTH_HEIGHT_RATIO = 0.4 #Assume glyph width averages 2/5 the height + A4_PAGE_HEIGHT = 297 #(in mm) + A4_PAGE_WIDTH = 210 #(in mm) + ROUNDING = 5 #round estimate up to nearest 5% + FONT_HEIGHT_CONVERSION_FACTOR = 0.35278 #convert font point size to mm + FONT_WIDTH_HEIGHT_RATIO = 0.4 #Assume glyph width averages 2/5 the height ## # Settings for the template - has_settings :export, class_name: 'Settings::Template' do |s| - s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS - end - alias_method :super_settings, :settings + has_settings :export, class_name: 'Settings::Template' do |s| + s.key :export, defaults: Settings::Template::DEFAULT_SETTINGS + end + alias_method :super_settings, :settings @@ -56,46 +61,51 @@ ## - # Proxy through to the template settings (or defaults if this plan doesn't have - # an associated template) if there are no settings stored for this plan. - # `key` is required by rails-settings, so it's required here, too. + # Proxy through to the template settings (or defaults if this plan doesn't have + # an associated template) if there are no settings stored for this plan. + # `key` is required by rails-settings, so it's required here, too. # # @param key [Key] a key required by rails # @return [Settings] settings for this plan's template - def settings(key) - self_settings = self.super_settings(key) - return self_settings if self_settings.value? -# self.dmptemplate.settings(key) - self.template.settings(key) - end + def settings(key) + self_settings = self.super_settings(key) + return self_settings if self_settings.value? +# self.dmptemplate.settings(key) + self.template.settings(key) unless self.template.nil? + end ## # returns the template for this plan, or generates an empty template and returns that # # @return [Dmptemplate] the template associated with this plan - def dmptemplate -# self.project.try(:dmptemplate) || Dmptemplate.new + def dmptemplate +# self.project.try(:dmptemplate) || Dmptemplate.new self.try(:template) || Template.new - end + end ## # returns the title for this project as defined by the settings # # @return [String] the title for this project - def title - logger.debug "Title in settings: #{self.settings(:export).title}" - if self.settings(:export).title == "" + def title + if self.settings(:export).nil? + return I18n.t('tool_title2') + + else +# logger.debug "Title in settings: #{self.settings(:export).title}" + if self.settings(:export).title == "" # if !self.version.nil? && !self.version.phase.nil? && !self.version.phase.title? then - if !self.template.nil? && !self.template.phases.empty? -# return self.version.phase.title - return self.template.phases.first.title + if !self.template.nil? && !self.template.phases.empty? +# return self.version.phase.title + return self.template.phases.first.title + else + return I18n.t('tool_title2') + end else - return I18n.t('tool_title2') - end - else - return self.settings(:export).title - end - end + return self.settings(:export).title + end + end + end ## # returns the most recent answer to the given question id @@ -104,78 +114,78 @@ # @param qid [Integer] the id for the question to find the answer for # @param create_if_missing [Boolean] if true, will genereate a default answer to the question # @return [Answer,nil] the most recent answer to the question, or a new question with default value, or nil - def answer(qid, create_if_missing = true) - answer = answers.where(:question_id => qid).order("created_at DESC").first - question = Question.find(qid) - if answer.nil? && create_if_missing then - answer = Answer.new - answer.plan_id = id - answer.question_id = qid - answer.text = question.default_value - default_options = Array.new - question.options.each do |option| - if option.is_default - default_options << option - end - end - answer.options = default_options - end - return answer - end + def answer(qid, create_if_missing = true) + answer = answers.where(:question_id => qid).order("created_at DESC").first + question = Question.find(qid) + if answer.nil? && create_if_missing then + answer = Answer.new + answer.plan_id = id + answer.question_id = qid + answer.text = question.default_value + default_options = Array.new + question.options.each do |option| + if option.is_default + default_options << option + end + end + answer.options = default_options + end + return answer + end ## # returns all of the sections for this version of the plan, and for the project's organisation # # @return [Array
,nil] either a list of sections, or nil if none were found - def sections - unless project.organisation.nil? then - sections = version.global_sections + project.organisation.all_sections(version_id) - else - sections = version.global_sections - end - return sections.uniq.sort_by &:number - end + def sections + unless project.organisation.nil? then + sections = version.global_sections + project.organisation.all_sections(version_id) + else + sections = version.global_sections + end + return sections.uniq.sort_by &:number + end ## # returns the guidances associated with the project's organisation, for a specified question # # @param question [Question] the question to find guidance for # @return [Array] the list of guidances which pretain to the specified question - def guidance_for_question(question) - guidances = {} - # If project org isn't nil, get guidance by theme from any "non-subset" groups belonging to project org - unless project.organisation.nil? then - project.organisation.guidance_groups.each do |group| - if !group.optional_subset && (group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0) then - group.guidances.each do |guidance| - guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| - guidances = self.add_guidance_to_array(guidances, group, theme, guidance) - end - end - end - end - end - # Get guidance by theme from any guidance groups selected on creation - project.guidance_groups.each do |group| - if group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0 then - group.guidances.each do |guidance| - guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| - guidances = self.add_guidance_to_array(guidances, group, theme, guidance) - end - end - end - end - # Get guidance by question where guidance group was selected on creation or if group is organisation default - question.guidances.each do |guidance| - guidance.guidance_groups.each do |group| - if (group.organisation == project.organisation && !group.optional_subset) || project.guidance_groups.include?(group) then - guidances = self.add_guidance_to_array(guidances, group, nil, guidance) - end + def guidance_for_question(question) + guidances = {} + # If project org isn't nil, get guidance by theme from any "non-subset" groups belonging to project org + unless project.organisation.nil? then + project.organisation.guidance_groups.each do |group| + if !group.optional_subset && (group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0) then + group.guidances.each do |guidance| + guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| + guidances = self.add_guidance_to_array(guidances, group, theme, guidance) + end + end + end end - end + end + # Get guidance by theme from any guidance groups selected on creation + project.guidance_groups.each do |group| + if group.dmptemplates.pluck(:id).include?(project.dmptemplate_id) || group.dmptemplates.count == 0 then + group.guidances.each do |guidance| + guidance.themes.where("id IN (?)", question.theme_ids).each do |theme| + guidances = self.add_guidance_to_array(guidances, group, theme, guidance) + end + end + end + end + # Get guidance by question where guidance group was selected on creation or if group is organisation default + question.guidances.each do |guidance| + guidance.guidance_groups.each do |group| + if (group.organisation == project.organisation && !group.optional_subset) || project.guidance_groups.include?(group) then + guidances = self.add_guidance_to_array(guidances, group, nil, guidance) + end + end + end - return guidances - end + return guidances + end ## # adds the given guidance to a hash indexed by a passed guidance group and theme @@ -185,27 +195,27 @@ # @param theme [Theme] the theme object for the GuidanceGroup # @param guidance [Guidance] the guidance object to be appended to the correct section of the array # @return [{GuidanceGroup => {Theme => Array}}] the updated object which was passed in - def add_guidance_to_array(guidance_array, guidance_group, theme, guidance) - if guidance_array[guidance_group].nil? then - guidance_array[guidance_group] = {} - end - if theme.nil? then - if guidance_array[guidance_group]["no_theme"].nil? then - guidance_array[guidance_group]["no_theme"] = [] - end - if !guidance_array[guidance_group]["no_theme"].include?(guidance) then - guidance_array[guidance_group]["no_theme"].push(guidance) - end - else - if guidance_array[guidance_group][theme].nil? then - guidance_array[guidance_group][theme] = [] - end - if !guidance_array[guidance_group][theme].include?(guidance) then - guidance_array[guidance_group][theme].push(guidance) - end - end + def add_guidance_to_array(guidance_array, guidance_group, theme, guidance) + if guidance_array[guidance_group].nil? then + guidance_array[guidance_group] = {} + end + if theme.nil? then + if guidance_array[guidance_group]["no_theme"].nil? then + guidance_array[guidance_group]["no_theme"] = [] + end + if !guidance_array[guidance_group]["no_theme"].include?(guidance) then + guidance_array[guidance_group]["no_theme"].push(guidance) + end + else + if guidance_array[guidance_group][theme].nil? then + guidance_array[guidance_group][theme] = [] + end + if !guidance_array[guidance_group][theme].include?(guidance) then + guidance_array[guidance_group][theme].push(guidance) + end + end return guidance_array - end + end ## # determines if the plan is editable by the specified user @@ -213,9 +223,9 @@ # # @param user_id [Integer] the id for a user # @return [Boolean] true if user can edit the plan - def editable_by(user_id) - return project.editable_by(user_id) - end + def editable_by(user_id) + return project.editable_by(user_id) + end ## # determines if the plan is readable by the specified user @@ -223,13 +233,13 @@ # # @param user_id [Integer] the id for a user # @return [Boolean] true if the user can read the plan - def readable_by(user_id) - if project.nil? - return false - else - return project.readable_by(user_id) - end - end + def readable_by(user_id) + if project.nil? + return false + else + return project.readable_by(user_id) + end + end ## # determines if the plan is administerable by the specified user @@ -237,9 +247,9 @@ # # @param user_id [Integer] the id for the user # @return [Boolean] true if the user can administer the plan - def administerable_by(user_id) - return project.readable_by(user_id) - end + def administerable_by(user_id) + return project.readable_by(user_id) + end ## @@ -249,63 +259,63 @@ # for each question, it contains the answer_id, answer_created_by, answer_text, answer_options_id, aand answered_by # # @return [Status] - def status - status = { - "num_questions" => 0, - "num_answers" => 0, - "sections" => {}, - "questions" => {}, - "space_used" => 0 # percentage of available space in pdf used - } + def status + status = { + "num_questions" => 0, + "num_answers" => 0, + "sections" => {}, + "questions" => {}, + "space_used" => 0 # percentage of available space in pdf used + } - space_used = height_of_text(self.project.title, 2, 2) + space_used = height_of_text(self.project.title, 2, 2) - sections.each do |s| - space_used += height_of_text(s.title, 1, 1) - section_questions = 0 - section_answers = 0 - status["sections"][s.id] = {} - status["sections"][s.id]["questions"] = Array.new - s.questions.each do |q| - status["num_questions"] += 1 - section_questions += 1 - status["sections"][s.id]["questions"] << q.id - status["questions"][q.id] = {} - answer = answer(q.id, false) + sections.each do |s| + space_used += height_of_text(s.title, 1, 1) + section_questions = 0 + section_answers = 0 + status["sections"][s.id] = {} + status["sections"][s.id]["questions"] = Array.new + s.questions.each do |q| + status["num_questions"] += 1 + section_questions += 1 + status["sections"][s.id]["questions"] << q.id + status["questions"][q.id] = {} + answer = answer(q.id, false) - space_used += height_of_text(q.text) unless q.text == s.title - space_used += height_of_text(answer.try(:text) || I18n.t('helpers.plan.export.pdf.question_not_answered')) + space_used += height_of_text(q.text) unless q.text == s.title + space_used += height_of_text(answer.try(:text) || I18n.t('helpers.plan.export.pdf.question_not_answered')) - if ! answer.nil? then - status["questions"][q.id] = { - "answer_id" => answer.id, - "answer_created_at" => answer.created_at.to_i, - "answer_text" => answer.text, - "answer_option_ids" => answer.option_ids, - "answered_by" => answer.user.name - } + if ! answer.nil? then + status["questions"][q.id] = { + "answer_id" => answer.id, + "answer_created_at" => answer.created_at.to_i, + "answer_text" => answer.text, + "answer_option_ids" => answer.option_ids, + "answered_by" => answer.user.name + } q_format = q.question_format - status["num_answers"] += 1 if (q_format.title == I18n.t("helpers.checkbox") || q_format.title == I18n.t("helpers.multi_select_box") || + status["num_answers"] += 1 if (q_format.title == I18n.t("helpers.checkbox") || q_format.title == I18n.t("helpers.multi_select_box") || q_format.title == I18n.t("helpers.radio_buttons") || q_format.title == I18n.t("helpers.dropdown")) || answer.text.present? - section_answers += 1 - #TODO: include selected options in space estimate - else - status["questions"][q.id] = { - "answer_id" => nil, - "answer_created_at" => nil, - "answer_text" => nil, - "answer_option_ids" => nil, - "answered_by" => nil - } - end - status["sections"][s.id]["num_questions"] = section_questions - status["sections"][s.id]["num_answers"] = section_answers - end - end + section_answers += 1 + #TODO: include selected options in space estimate + else + status["questions"][q.id] = { + "answer_id" => nil, + "answer_created_at" => nil, + "answer_text" => nil, + "answer_option_ids" => nil, + "answered_by" => nil + } + end + status["sections"][s.id]["num_questions"] = section_questions + status["sections"][s.id]["num_answers"] = section_answers + end + end - status['space_used'] = estimate_space_used(space_used) - return status - end + status['space_used'] = estimate_space_used(space_used) + return status + end ## @@ -314,35 +324,35 @@ # section: title, question text for each question, answer type and answer value # # @return [Details] - def details - details = { - "project_title" => project.title, - "phase_title" => version.phase.title, - "sections" => {} - } - sections.sort_by(&:"number").each do |s| - details["sections"][s.number] = {} - details["sections"][s.number]["title"] = s.title - details["sections"][s.number]["questions"] = {} - s.questions.order("number").each do |q| - details["sections"][s.number]["questions"][q.number] = {} - details["sections"][s.number]["questions"][q.number]["question_text"] = q.text - answer = answer(q.id, false) - if ! answer.nil? then + def details + details = { + "project_title" => project.title, + "phase_title" => version.phase.title, + "sections" => {} + } + sections.sort_by(&:"number").each do |s| + details["sections"][s.number] = {} + details["sections"][s.number]["title"] = s.title + details["sections"][s.number]["questions"] = {} + s.questions.order("number").each do |q| + details["sections"][s.number]["questions"][q.number] = {} + details["sections"][s.number]["questions"][q.number]["question_text"] = q.text + answer = answer(q.id, false) + if ! answer.nil? then q_format = q.question_format - if (q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || + if (q_format.title == t("helpers.checkbox") || q_format.title == t("helpers.multi_select_box") || q_format.title == t("helpers.radio_buttons") || q_format.title == t("helpers.dropdown")) then - details["sections"][s.number]["questions"][q.number]["selections"] = {} - answer.options.each do |o| - details["sections"][s.number]["questions"][q.number]["selections"][o.number] = o.text - end - end - details["sections"][s.number]["questions"][q.number]["answer_text"] = answer.text - end - end - end - return details - end + details["sections"][s.number]["questions"][q.number]["selections"] = {} + answer.options.each do |o| + details["sections"][s.number]["questions"][q.number]["selections"][o.number] = o.text + end + end + details["sections"][s.number]["questions"][q.number]["answer_text"] = answer.text + end + end + end + return details + end ## # determines wether or not a specified section of a plan is locked to a specified user and returns a status hash @@ -350,55 +360,55 @@ # @param section_id [Integer] the setion to determine if locked # @param user_id [Integer] the user to determine if locked for # @return [Hash{String => Hash{String => Boolean, nil, String, Integer}}] - def locked(section_id, user_id) - plan_section = plan_sections.where("section_id = ? AND user_id != ? AND release_time > ?", section_id, user_id, Time.now).last - if plan_section.nil? then - status = { - "locked" => false, - "locked_by" => nil, - "timestamp" => nil, - "id" => nil - } - else - status = { - "locked" => true, - "locked_by" => plan_section.user.name, - "timestamp" => plan_section.updated_at, - "id" => plan_section.id - } - end - end + def locked(section_id, user_id) + plan_section = plan_sections.where("section_id = ? AND user_id != ? AND release_time > ?", section_id, user_id, Time.now).last + if plan_section.nil? then + status = { + "locked" => false, + "locked_by" => nil, + "timestamp" => nil, + "id" => nil + } + else + status = { + "locked" => true, + "locked_by" => plan_section.user.name, + "timestamp" => plan_section.updated_at, + "id" => plan_section.id + } + end + end ## # for each section, lock the section with the given user_id # # @param user_id [Integer] the id for the user who can use the sections - def lock_all_sections(user_id) - sections.each do |s| - lock_section(s.id, user_id, 1800) - end - end + def lock_all_sections(user_id) + sections.each do |s| + lock_section(s.id, user_id, 1800) + end + end ## # for each section, unlock the section # # @param user_id [Integer] the id for the user to unlock the sections for - def unlock_all_sections(user_id) - plan_sections.where(:user_id => user_id).order("created_at DESC").each do |lock| - lock.delete - end - end + def unlock_all_sections(user_id) + plan_sections.where(:user_id => user_id).order("created_at DESC").each do |lock| + lock.delete + end + end ## # for each section, unlock the section # Not sure how this is different from unlock_all_sections # # @param user_id [Integer] - def delete_recent_locks(user_id) - plan_sections.where(:user_id => user_id).each do |lock| - lock.delete - end - end + def delete_recent_locks(user_id) + plan_sections.where(:user_id => user_id).each do |lock| + lock.delete + end + end ## # Locks the specified section to only be used by the specified user, for the number of secconds specified @@ -407,23 +417,23 @@ # @param user_id [Integer] the id of the user who can use the section # @param release_time [Integer] the number of secconds the section will be locked for, defaults to 60 # @return [Boolean] wether or not the section was locked - def lock_section(section_id, user_id, release_time = 60) - status = locked(section_id, user_id) - if ! status["locked"] then - plan_section = PlanSection.new - plan_section.plan_id = id - plan_section.section_id = section_id - plan_section.release_time = Time.now + release_time.seconds - plan_section.user_id = user_id - plan_section.save - elsif status["current_user"] then - plan_section = PlanSection.find(status["id"]) - plan_section.release_time = Time.now + release_time.seconds - plan_section.save - else - return false - end - end + def lock_section(section_id, user_id, release_time = 60) + status = locked(section_id, user_id) + if ! status["locked"] then + plan_section = PlanSection.new + plan_section.plan_id = id + plan_section.section_id = section_id + plan_section.release_time = Time.now + release_time.seconds + plan_section.user_id = user_id + plan_section.save + elsif status["current_user"] then + plan_section = PlanSection.find(status["id"]) + plan_section.release_time = Time.now + release_time.seconds + plan_section.save + else + return false + end + end ## # unlocks the specified section for the specified user @@ -431,28 +441,28 @@ # @param section_id [Integer] the id for the section to be unlocked # @param user_id [Integer] the id for the user for whom the section was previously locked # @return [Boolean] wether or not the lock was removed - def unlock_section(section_id, user_id) - plan_sections.where(:section_id => section_id, :user_id => user_id).order("created_at DESC").each do |lock| - lock.delete - end - end + def unlock_section(section_id, user_id) + plan_sections.where(:section_id => section_id, :user_id => user_id).order("created_at DESC").each do |lock| + lock.delete + end + end ## # returns the time of either the latest answer to any question, or the latest update to the model # # @return [DateTime] the time at which the plan was last changed - def latest_update - if answers.any? then - last_answered = answers.order("updated_at DESC").first.updated_at - if last_answered > updated_at then - return last_answered - else - return updated_at - end - else - return updated_at - end - end + def latest_update + if answers.any? then + last_answered = answers.order("updated_at DESC").first.updated_at + if last_answered > updated_at then + return last_answered + else + return updated_at + end + else + return updated_at + end + end ## # returns an array of hashes. Each hash contains the question's id, the answer_id, @@ -460,89 +470,89 @@ # # @param section_id [Integer] the section to find answers of # @return [Array nil,String,Integer,DateTime}] - def section_answers(section_id) - section = Section.find(section_id) - section_questions = Array.new - counter = 0 - section.questions.each do |q| - section_questions[counter] = {} - section_questions[counter]["id"] = q.id - #section_questions[counter]["multiple_choice"] = q.multiple_choice - q_answer = answer(q.id, false) - if q_answer.nil? then - section_questions[counter]["answer_id"] = nil - if q.suggested_answers.find_by_organisation_id(project.organisation_id).nil? then - section_questions[counter]["answer_text"] = "" - else - section_questions[counter]["answer_text"] = q.default_value - end - section_questions[counter]["answer_timestamp"] = nil - section_questions[counter]["answer_options"] = Array.new - else - section_questions[counter]["answer_id"] = q_answer.id - section_questions[counter]["answer_text"] = q_answer.text - section_questions[counter]["answer_timestamp"] = q_answer.created_at - section_questions[counter]["answer_options"] = q_answer.options.pluck(:id) - end - counter = counter + 1 - end - return section_questions - end + def section_answers(section_id) + section = Section.find(section_id) + section_questions = Array.new + counter = 0 + section.questions.each do |q| + section_questions[counter] = {} + section_questions[counter]["id"] = q.id + #section_questions[counter]["multiple_choice"] = q.multiple_choice + q_answer = answer(q.id, false) + if q_answer.nil? then + section_questions[counter]["answer_id"] = nil + if q.suggested_answers.find_by_organisation_id(project.organisation_id).nil? then + section_questions[counter]["answer_text"] = "" + else + section_questions[counter]["answer_text"] = q.default_value + end + section_questions[counter]["answer_timestamp"] = nil + section_questions[counter]["answer_options"] = Array.new + else + section_questions[counter]["answer_id"] = q_answer.id + section_questions[counter]["answer_text"] = q_answer.text + section_questions[counter]["answer_timestamp"] = q_answer.created_at + section_questions[counter]["answer_options"] = q_answer.options.pluck(:id) + end + counter = counter + 1 + end + return section_questions + end private ## - # Based on the height of the text gathered so far and the available vertical - # space of the pdf, estimate a percentage of how much space has been used. - # This is highly dependent on the layout in the pdf. A more accurate approach - # would be to render the pdf and check how much space had been used, but that - # could be very slow. - # NOTE: This is only an estimate, rounded up to the nearest 5%; it is intended - # for guidance when editing plan data, not to be 100% accurate. + # Based on the height of the text gathered so far and the available vertical + # space of the pdf, estimate a percentage of how much space has been used. + # This is highly dependent on the layout in the pdf. A more accurate approach + # would be to render the pdf and check how much space had been used, but that + # could be very slow. + # NOTE: This is only an estimate, rounded up to the nearest 5%; it is intended + # for guidance when editing plan data, not to be 100% accurate. # # @param used_height [Integer] an estimate of the height used so far # @return [Integer] the estimate of space used of an A4 portrain - def estimate_space_used(used_height) - @formatting ||= self.settings(:export).formatting + def estimate_space_used(used_height) + @formatting ||= self.settings(:export).formatting - return 0 unless @formatting[:font_size] > 0 + return 0 unless @formatting[:font_size] > 0 - margin_height = @formatting[:margin][:top].to_i + @formatting[:margin][:bottom].to_i - page_height = A4_PAGE_HEIGHT - margin_height # 297mm for A4 portrait - available_height = page_height * self.dmptemplate.settings(:export).max_pages + margin_height = @formatting[:margin][:top].to_i + @formatting[:margin][:bottom].to_i + page_height = A4_PAGE_HEIGHT - margin_height # 297mm for A4 portrait + available_height = page_height * self.dmptemplate.settings(:export).max_pages - percentage = (used_height / available_height) * 100 - (percentage / ROUNDING).ceil * ROUNDING # round up to nearest five - end + percentage = (used_height / available_height) * 100 + (percentage / ROUNDING).ceil * ROUNDING # round up to nearest five + end ## - # Take a guess at the vertical height (in mm) of the given text based on the - # font-size and left/right margins stored in the plan's settings. - # This assumes a fixed-width for each glyph, which is obviously - # incorrect for the font-face choices available; the idea is that - # they'll hopefully average out to that in the long-run. - # Allows for hinting different font sizes (offset from base via font_size_inc) - # and vertical margins (i.e. for heading text) + # Take a guess at the vertical height (in mm) of the given text based on the + # font-size and left/right margins stored in the plan's settings. + # This assumes a fixed-width for each glyph, which is obviously + # incorrect for the font-face choices available; the idea is that + # they'll hopefully average out to that in the long-run. + # Allows for hinting different font sizes (offset from base via font_size_inc) + # and vertical margins (i.e. for heading text) # # @param text [String] the text to estimate size of # @param font_size_inc [Integer] the size of the font of the text, defaults to 0 # @param vertical_margin [Integer] the top margin above the text, defaults to 0 - def height_of_text(text, font_size_inc = 0, vertical_margin = 0) - @formatting ||= self.settings(:export).formatting - @margin_width ||= @formatting[:margin][:left].to_i + @formatting[:margin][:right].to_i - @base_font_size ||= @formatting[:font_size] + def height_of_text(text, font_size_inc = 0, vertical_margin = 0) + @formatting ||= self.settings(:export).formatting + @margin_width ||= @formatting[:margin][:left].to_i + @formatting[:margin][:right].to_i + @base_font_size ||= @formatting[:font_size] - return 0 unless @base_font_size > 0 + return 0 unless @base_font_size > 0 - font_height = FONT_HEIGHT_CONVERSION_FACTOR * (@base_font_size + font_size_inc) - font_width = font_height * FONT_WIDTH_HEIGHT_RATIO # Assume glyph width averages at 2/5s the height - leading = font_height / 2 + font_height = FONT_HEIGHT_CONVERSION_FACTOR * (@base_font_size + font_size_inc) + font_width = font_height * FONT_WIDTH_HEIGHT_RATIO # Assume glyph width averages at 2/5s the height + leading = font_height / 2 - chars_in_line = (A4_PAGE_WIDTH - @margin_width) / font_width # 210mm for A4 portrait - num_lines = (text.length / chars_in_line).ceil + chars_in_line = (A4_PAGE_WIDTH - @margin_width) / font_width # 210mm for A4 portrait + num_lines = (text.length / chars_in_line).ceil - (num_lines * font_height) + vertical_margin + leading - end + (num_lines * font_height) + vertical_margin + leading + end diff --git a/app/models/question.rb b/app/models/question.rb index cd15316..ab3ced5 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -27,6 +27,8 @@ :question_options, :suggested_answers, :answers, :themes, :modifiable, :option_comment_display, :as => [:default, :admin] + validates :text, :section, :number, presence: true + # EVALUATE CLASS AND INSTANCE METHODS BELOW # diff --git a/app/models/question_option.rb b/app/models/question_option.rb index 6fa289d..1a079d0 100644 --- a/app/models/question_option.rb +++ b/app/models/question_option.rb @@ -9,4 +9,6 @@ # -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: true end diff --git a/app/models/user.rb b/app/models/user.rb index 1a3df5c..f0aec25 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -16,6 +16,7 @@ belongs_to :org has_many :answers has_many :notes + has_many :exported_plans has_many :roles, dependent: :destroy has_many :projects, through: :roles do def filter(query) diff --git a/app/policies/guidance_policy.rb b/app/policies/guidance_policy.rb index 4aa8245..ee7be10 100644 --- a/app/policies/guidance_policy.rb +++ b/app/policies/guidance_policy.rb @@ -53,7 +53,7 @@ class Scope < Scope def resolve - scope = Guidance.includes(:guidance_group, :question, :themes).by_organisation(user.org_id) + scope = Guidance.includes(:guidance_group, :question, :themes).by_org(user.org_id) end end end \ No newline at end of file diff --git a/app/validators/answer_for_correct_template_validator.rb b/app/validators/answer_for_correct_template_validator.rb new file mode 100644 index 0000000..8ec15ee --- /dev/null +++ b/app/validators/answer_for_correct_template_validator.rb @@ -0,0 +1,10 @@ +class AnswerForCorrectTemplateValidator < ActiveModel::Validator + def validate(record) + # Make sure that the question and plan belong to the same template! + unless record.plan.nil? || record.question.nil? + unless record.plan.template == record.question.section.phase.template + record.errors[:question] << I18n.t('helpers.answer.question_must_belong_to_correct_template') + end + end + end +end \ No newline at end of file diff --git a/app/validators/email_validator.rb b/app/validators/email_validator.rb index a3cc4ed..d47e7c1 100644 --- a/app/validators/email_validator.rb +++ b/app/validators/email_validator.rb @@ -1,7 +1,7 @@ class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i - #record.errors[attribute] << (options[:message] || "is not a valid email address") + record.errors[attribute] << (options[:message] || "is not a valid email address") end end end \ No newline at end of file diff --git a/config/locales/de.yml b/config/locales/de.yml index fc7de1a..d010da5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -408,6 +408,10 @@ add_comment_accordion_label: "Füge Kommentar hinzu" comment_accordion_label: "Kommentare" + answer: + only_one_per_question: "Eine Frage kann nur eine Antwort haben." + question_must_belong_to_correct_template: "Die Frage muss zur richtigen vorlage gehören." + comments: add_comment_label: "Füge Kommentar hinzu" add_comment_text: "Bitte füge einen Kommentar hinzu" diff --git a/config/locales/en-UK.yml b/config/locales/en-UK.yml index db83e6d..33f4b85 100644 --- a/config/locales/en-UK.yml +++ b/config/locales/en-UK.yml @@ -507,6 +507,10 @@ add_comment_accordion_label: "Share note" comment_accordion_label: "Notes" + answer: + only_one_per_question: "A question can only have one answer." + question_must_belong_to_correct_template: "The question must belong to the correct template." + comments: add_comment_label: "Add note" add_comment_text: "Share note with collaborators" diff --git a/config/locales/en-US.yml b/config/locales/en-US.yml index f3f02ba..2d9b60b 100644 --- a/config/locales/en-US.yml +++ b/config/locales/en-US.yml @@ -491,6 +491,10 @@ add_comment_accordion_label: "Share note" comment_accordion_label: "Notes" + answer: + only_one_per_question: "A question can only have one answer." + question_must_belong_to_correct_template: "The question must belong to the correct template." + comments: add_comment_label: "Add note" add_comment_text: "Share note with collaborators" diff --git a/config/locales/es.yml b/config/locales/es.yml index 615b0c5..a7e52e5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -388,6 +388,10 @@ add_comment_accordion_label: "Compartir nota" comment_accordion_label: "Notas" + answer: + only_one_per_question: "Una pregunta sólo puede tener una respuesta." + question_must_belong_to_correct_template: "La pregunta debe pertenecer a la plantilla correcta." + comments: add_comment_label: "Añadir nota" add_comment_text: "Compartir nota con colaboradores" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 2dbc142..d045462 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -392,6 +392,10 @@ add_comment_accordion_label: "Partager la note" comment_accordion_label: "Notes" + answer: + only_one_per_question: "Une question ne peut avoir qu'une seule réponse." + question_must_belong_to_correct_template: "La question doit appartenir au modèle correct." + comments: add_comment_label: "Ajouter une note" add_comment_text: "Partager la note avec des collaborateurs" diff --git a/test/test_helper.rb b/test/test_helper.rb index 671d3b5..9b8050d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -25,13 +25,67 @@ require_relative '../db/seeds.rb' # Add more helper methods to be used by all tests here... - + # Convert Ruby Class Names into attribute names (e.g. MyClass --> my_class) # ---------------------------------------------------------------------- def class_name_to_attribute_name(name) name.gsub(/([a-z]+)([A-Z])/, '\1_\2').gsub('-', '_').downcase end + # Scaffold a new Template with one Phase, one Section, and a Question for + # each of the possible Question Formats. + # ---------------------------------------------------------------------- + def scaffold_template + template = Template.new(title: 'Test template', description: 'My test template', + published: true, org: Org.first, locale: nil, is_default: false, + version: 1, visibility: 0) + + template.phases << Phase.new(title: 'Test phase', description: 'My test phase', + number: 1, modifiable: false) + + section = Section.new(title: 'Test section', description: 'My test section', + number: 99, published: true, modifiable: false) + + i = 1 + # Add each type of Question to the new section + QuestionFormat.all.each do |frmt| + question = Question.new(text: "Test question - #{frmt.title}", number: i, + question_format: frmt) + + if frmt.option_based? + 3.times do |j| + question.question_options << QuestionOption.new(text: "Option #{j}", number: j) + end + end + + section.questions << question + i += 1 + end + + template.phases.first.sections << section + + assert template.valid?, "unable to create new Template: #{template.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + template.save! + + @template = template.reload + end + + # Scaffold a new Plan based on the scaffolded Template + # ---------------------------------------------------------------------- + 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: 0, + users: [User.last]) + + assert @plan.valid?, "unable to create new Plan: #{@plan.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + @plan.save! + end + + # FUNCTIONAL/INTEGRATION TEST HELPERS # ---------------------------------------------------------------------- def assert_unauthorized_redirect_to_root_path @@ -69,7 +123,7 @@ # Add another association for the object object.send(rel) << new_association object.save! - assert_equal (initial_expected_count + 1), object.send(rel).count, "was expecting #{object.class.name} to have #{initial_expected_count + 1} #{rel} after adding a new one" + assert_equal (initial_expected_count + 1), object.send(rel).count, "was expecting #{object.class.name} to have #{initial_expected_count + 1} #{rel} after adding a new one - #{new_association.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" # Remove the newly added association object.send(rel).delete(new_association) diff --git a/test/unit/answer_test.rb b/test/unit/answer_test.rb index 764868e..991ab88 100644 --- a/test/unit/answer_test.rb +++ b/test/unit/answer_test.rb @@ -5,29 +5,13 @@ setup do @user = User.last - @template = Template.first + scaffold_plan - @section = Section.create(title: 'Test section', number: 99, phase: @template.phases.last) - - i = 1 - # Add each type of Question to the new section - QuestionFormat.all.each do |frmt| - q = Question.create(text: "Test question - #{frmt.title}", number: i, - question_format: frmt, section: @section) - - if frmt.option_based? - 3.times do |j| - QuestionOption.create(text: "Option #{j}", number: j, question: q) - end - end - - i += 1 - end - - @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: 0) + q = @plan.template.questions.select{|q| !q.question_format.option_based }.last + q = 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: q, text: 'Testing') end # --------------------------------------------------- @@ -73,6 +57,15 @@ end # --------------------------------------------------- + test "answer's template must match the plan's template" do + plan = Plan.new(title: 'Wrong plan test', template: Template.where.not(id: @plan.template.id).first) + q = @plan.template.questions.select{|q| !q.question_format.option_based }.first + + assert_not Answer.new(user: @user, plan: plan, question: @plan.questions.first, + text: 'Testing').valid?, "expected to only be able to add an answer if it belongs to the template associated with the plan" + end + + # --------------------------------------------------- test "can CRUD answers for text based questions" do QuestionFormat.where(option_based: false).each do |qf| q = @plan.template.questions.select{|q| q.question_format == qf }.first @@ -110,4 +103,26 @@ assert answr.destroy!, "Was unable to delete the Answer for a #{qf.title} question!" end end + + # --------------------------------------------------- + test "can manage belongs_to relationship with User" do + verify_belongs_to_relationship(@answer, User.last) + end + + # --------------------------------------------------- + test "can manage belongs_to relationship with Plan" do + verify_belongs_to_relationship(@answer, @plan) + end + + # --------------------------------------------------- + test "can manage belongs_to relationship with Question" do + q = @plan.template.phases.first.sections.first.questions.last + verify_belongs_to_relationship(@answer, q) + end + + # --------------------------------------------------- + test "can manage has_many relationship with Notes" do + note = Note.new(text: 'Test Note', user: @user) + verify_has_many_relationship(@answer, note, @answer.notes.count) + end end diff --git a/test/unit/comment_test.rb b/test/unit/comment_test.rb deleted file mode 100644 index 510845f..0000000 --- a/test/unit/comment_test.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'test_helper' - -class CommentTest < ActiveSupport::TestCase - - setup do - @user = User.last - - # generate a template and plan - template = generate_complete_template - - project = Project.new({ - title: 'Test Project', - organisation: @user.organisation - }) - project.dmptemplate = template - project.save! - - @plan = project.plans.first - - qs = template.phases.first.versions.first.sections.first.questions - @text_area_question = qs.select{ |q| q.question_format == QuestionFormat.find_by(title: 'Text Area' ) }.first - end - - # --------------------------------------------------- - test "required fields are required" do - assert_not Comment.new.valid? - assert_not Comment.new(user: @user, question: @text_area_question).valid?, "expected the 'text' field to be required" - assert_not Comment.new(plan: @plan, question: @text_area_question, text: 'Testing').valid?, "expected the 'user' field to be required" - assert_not Comment.new(user: @user, question: @text_area_question, text: 'Testing').valid?, "expected the 'plan' field to be required" - assert_not Comment.new(user: @user, plan: @plan, text: 'Testing').valid?, "expected the 'question' field to be required" - - # Ensure the bar minimum and complete versions are valid - a = Comment.new(user: @user, plan: @plan, question: @text_area_question, text: 'Testing') - assert a.valid?, "expected the 'text', 'plan', 'user' and 'question' fields to be enough to create an Comment! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - end - - # --------------------------------------------------- - test "can CRUD Comment" do - cmnt = Comment.create(user: @user, plan: @plan, question: @text_area_question, text: 'Tested ABC') - assert_not cmnt.id.nil?, "was expecting to be able to create a new Comment: #{cmnt.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - - cmnt.text = 'Testing an update' - cmnt.save! - cmnt.reload - assert_equal 'Testing an update', cmnt.text, "Was expecting to be able to update the text of the Comment!" - - assert cmnt.destroy!, "Was unable to delete the Comment!" - end - -end diff --git a/test/unit/exported_plan_test.rb b/test/unit/exported_plan_test.rb index 00ef9cb..28bae85 100644 --- a/test/unit/exported_plan_test.rb +++ b/test/unit/exported_plan_test.rb @@ -5,19 +5,10 @@ setup do @user = User.last - # generate a template and plan - template = generate_complete_template + scaffold_plan - project = Project.new({ - title: 'Test Project', - organisation: @user.organisation - }) - project.dmptemplate = template - project.save! - - @plan = project.plans.first - - @exported = ExportedPlan.create(user: @user, plan: @plan, format: ExportedPlan::VALID_FORMATS.first) + @exported = ExportedPlan.create(user: @user, plan: @plan, + format: ExportedPlan::VALID_FORMATS.first) end # --------------------------------------------------- diff --git a/test/unit/guidance_group_test.rb b/test/unit/guidance_group_test.rb index d768e1d..6019dce 100644 --- a/test/unit/guidance_group_test.rb +++ b/test/unit/guidance_group_test.rb @@ -4,85 +4,69 @@ include GlobalHelpers setup do - Organisation.create(name: GlobalHelpers.constant("organisation_types.managing_organisation")) - @user = User.first - @organisation = Organisation.first + @org = Org.last -<<<<<<< HEAD - @guidance_group = GuidanceGroup.create(name: 'Test Guidance Group', - organisation: @organisation) -======= - @organisations = Org.all ->>>>>>> final_schema + @guidance_group = GuidanceGroup.create(name: 'Test Guidance Group', org: @org, + optional_subset: false, published: true) end # --------------------------------------------------- test "required fields are required" do assert_not GuidanceGroup.new.valid? - assert_not GuidanceGroup.new(organisation: @organisation).valid?, "expected the 'name' field to be required" + assert_not GuidanceGroup.new(org: @org).valid?, "expected the 'name' field to be required" assert_not GuidanceGroup.new(name: 'Tester').valid?, "expected the 'organisation' field to be required" # Ensure the bar minimum and complete versions are valid - a = GuidanceGroup.new(name: 'Tester', organisation: @organisation) + a = GuidanceGroup.new(name: 'Tester', org: @org) assert a.valid?, "expected the 'name' and 'organisation' fields to be enough to create a GuidanceGroup! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" end # --------------------------------------------------- test "display_name returns organisation name and the guidance group name" do - assert_equal "#{@organisation.name}", @guidance_group.display_name, "Expected display_name to return the organisation name if there is only one GuidanceGroup" + assert_equal "#{@org.name}", @guidance_group.display_name, "Expected display_name to return the organisation name if there is only one GuidanceGroup" - GuidanceGroup.create(name: 'Second Test', organisation: @organisation) - assert_equal "#{@organisation.name}: #{@guidance_group.name}", @guidance_group.display_name, "Expected display_name to return the organisation name and guidance group name if there are more than one GuidanceGroup" - end - - # --------------------------------------------------- - test "to_s returns organisation name and the guidance group name" do - assert_equal @guidance_group.display_name, @guidance_group.to_s + GuidanceGroup.create(name: 'Second Test', org: @org) + assert_equal "#{@org.name}: #{@guidance_group.name}", @guidance_group.display_name, "Expected display_name to return the organisation name and guidance group name if there are more than one GuidanceGroup" end # --------------------------------------------------- test "guidance_groups_excluding does not return guidance groups for the current organisation" do - assert_not GuidanceGroup.guidance_groups_excluding([@organisation]).include?(@guidance_group) + assert_not GuidanceGroup.guidance_groups_excluding([@org]).include?(@guidance_group) end # --------------------------------------------------- test "user can view guidance_group if it belongs to their organisation" do - org = @user.organisation - gg = GuidanceGroup.create(name: 'User Test', organisation: org) + org = @user.org + gg = GuidanceGroup.create(name: 'User Test', org: org) assert GuidanceGroup.can_view?(@user, gg.id) end # --------------------------------------------------- test "user can view guidance_group if it belongs to a funder" do - org = Organisation.find_by(organisation_type: OrganisationType.find_by(name: GlobalHelpers.constant("organisation_types.funder"))) - gg = GuidanceGroup.create(name: 'Funder Test', organisation: org) + gg = GuidanceGroup.create(name: 'Funder Test', org: Org.funders.first) assert GuidanceGroup.can_view?(@user, gg.id) end # --------------------------------------------------- test "user can view guidance_group if it belongs to the managing curation centre" do - org = Organisation.find_by(name: GlobalHelpers.constant("organisation_types.managing_organisation")) - gg = GuidanceGroup.create(name: 'Managing CC Test', organisation: org) + gg = GuidanceGroup.create(name: 'Managing CC Test', org: Org.managing_orgs.first) assert GuidanceGroup.can_view?(@user, gg.id) end # --------------------------------------------------- test "user can view all oftheir organisations, funders, and the managing curation centre's guidance groups" do - @organisation.users << @user - @organisation.save - @organisation.reload - - funding = Organisation.where(organisation_type: OrganisationType.find_by(name: GlobalHelpers.constant("organisation_types.funder"))).first - managing = Organisation.find_by(name: GlobalHelpers.constant("organisation_types.managing_organisation")) + @org.users << @user + @org.save + @org.reload ggs = [@guidance_group, - GuidanceGroup.create(name: 'User Test', organisation: @organisation), - GuidanceGroup.create(name: 'Funder Test', organisation: funding), - GuidanceGroup.create(name: 'Managing CC Test', organisation: managing)] + GuidanceGroup.create(name: 'User Test', org: @org), + GuidanceGroup.create(name: 'Funder Test', org: Org.funders.first), + GuidanceGroup.create(name: 'Managing CC Test', org: Org.managing_orgs.first)] v = GuidanceGroup.all_viewable(@user) @@ -93,7 +77,7 @@ # --------------------------------------------------- test "can CRUD GuidanceGroup" do - gg = GuidanceGroup.create(name: 'Tester', organisation: @organisation) + gg = GuidanceGroup.create(name: 'Tester', org: @org) assert_not gg.id.nil?, "was expecting to be able to create a new GuidanceGroup!" gg.name = 'Testing an update' @@ -105,26 +89,14 @@ end # --------------------------------------------------- - test "can manage has_many relationship with Project" do - proj = Project.new(title: 'Test Project', dmptemplate: Dmptemplate.first) - verify_has_many_relationship(@guidance_group, proj, @guidance_group.projects.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with Template" do - t = Dmptemplate.new(title: 'Test Theme', organisation: @organisation) - verify_has_many_relationship(@guidance_group, t, @guidance_group.dmptemplates.count) - end - - # --------------------------------------------------- test "can manage has_many relationship with Guidance" do g = Guidance.new(text: 'Test Guidance') verify_has_many_relationship(@guidance_group, g, @guidance_group.guidances.count) end # --------------------------------------------------- - test "can manage belongs_to relationship with Organisation" do - verify_belongs_to_relationship(@guidance_group, @organisation) + test "can manage belongs_to relationship with Org" do + verify_belongs_to_relationship(@guidance_group, @org) end end diff --git a/test/unit/guidance_test.rb b/test/unit/guidance_test.rb index 67bbf8f..878b953 100644 --- a/test/unit/guidance_test.rb +++ b/test/unit/guidance_test.rb @@ -1,14 +1,11 @@ -<<<<<<< HEAD require 'test_helper' class GuidanceTest < ActiveSupport::TestCase setup do - Organisation.create(name: GlobalHelpers.constant("organisation_types.managing_organisation")) - @user = User.first - - @guidance_group = GuidanceGroup.create(name: 'Tester', organisation: @user.organisation) + + @guidance_group = GuidanceGroup.create(name: 'Tester', org: @user.org) @guidance = Guidance.create(text: 'Testing some new guidance') @guidance_group.guidances << @guidance @@ -20,7 +17,7 @@ # --------------------------------------------------- test "required fields are required" do assert_not Guidance.new.valid? - assert_not Guidance.new(guidance_groups: [GuidanceGroup.first]).valid?, "expected the 'text' field to be required" + assert_not Guidance.new(guidance_group: GuidanceGroup.first).valid?, "expected the 'text' field to be required" # Ensure the bar minimum and complete versions are valid a = Guidance.new(text: 'Testing guidance') @@ -28,21 +25,21 @@ end # --------------------------------------------------- - test "correctly identifies guidance as belonging to the organisation" do - assert @guidance.in_group_belonging_to?(@user.organisation.id), "expected the guidance to belong to the organisation" + test "correctly identifies guidance as belonging to the org" do + assert @guidance.in_group_belonging_to?(@user.org.id), "expected the guidance to belong to the org" - @guidance.guidance_groups = [] + @guidance.guidance_group = nil @guidance.save! - assert_not @guidance.in_group_belonging_to?(@user.organisation), "expected the guidance to NOT belong to the organisation" + assert_not @guidance.in_group_belonging_to?(@user.org), "expected the guidance to NOT belong to the org" end # --------------------------------------------------- - test "retrieves guidance by organisation" do - org = Organisation.create(name: 'Tester 123') - assert Guidance.by_organisation(org.id).empty?, "expected the newly created organisation to have no guidance" + test "retrieves guidance by org" do + org = Org.create(name: 'Tester 123', abbreviation: 'TEST', org_type: 1) + assert Guidance.by_org(org.id).empty?, "expected the newly created org to have no guidance" - assert_not Guidance.by_organisation(@user.organisation.id).empty?, "expected the organisation to have guidance" + assert_not Guidance.by_org(@user.org.id).empty?, "expected the org to have guidance" end # --------------------------------------------------- @@ -51,16 +48,13 @@ assert_not Guidance.can_view?(@user, g.id), "expected guidance that is not attached to a GuidanceGroup to be unviewable" - managing = Organisation.find_by(name: GlobalHelpers.constant("organisation_types.managing_organisation")) - funder = Organisation.find_by(organisation_type: OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder"))) + assert Guidance.can_view?(@user, @guidance.id), "expected the user to be able to view guidance belonging to their org" - assert Guidance.can_view?(@user, @guidance.id), "expected the user to be able to view guidance belonging to their organisation" - - @guidance_group.organisation = managing + @guidance_group.org = Org.managing_orgs.first @guidance_group.save! - assert Guidance.can_view?(@user, @guidance.id), "expected the user to be able to view guidance belonging to the managing organisation" + assert Guidance.can_view?(@user, @guidance.id), "expected the user to be able to view guidance belonging to the managing org" - @guidance_group.organisation = funder + @guidance_group.org = Org.funders.first @guidance_group.save! assert Guidance.can_view?(@user, @guidance.id), "expected the user to be able to view guidance belonging to a funder" end @@ -69,24 +63,17 @@ test "make sure a user can view all appropriate guidance" do viewable = Guidance.all_viewable(@user) - assert viewable.include?(@guidance), "expected the user to be able to view guidance belonging to their organisation" + assert viewable.include?(@guidance), "expected the user to be able to view guidance belonging to their org" + + GuidanceGroup.create(name: 'managing guidance group test', org: Org.managing_orgs.first) + GuidanceGroup.create(name: 'funder guidance group test', org: Org.funders.first) - managing = Organisation.find_by(name: GlobalHelpers.constant("organisation_types.managing_organisation")) - funder = Organisation.find_by(organisation_type: OrganisationType.find_by( name: GlobalHelpers.constant("organisation_types.funder"))) - - GuidanceGroup.create(name: 'managing guidance group test', organisation: managing) - GuidanceGroup.create(name: 'funder guidance group test', organisation: funder) - - managing.guidance_groups.each do |gg| - gg.guidances.each do |g| - assert viewable.include?(g), "expected the user to be able to view all managing organisation guidance" - end + Org.managing_orgs.first.guidance_groups.first.guidances.each do |g| + assert viewable.include?(g), "expected the user to be able to view all managing org guidance" end - funder.guidance_groups.each do |gg| - gg.guidances.each do |g| - assert viewable.include?(g), "expected the user to be able to view all funder guidance" - end + Org.funders.first.guidance_groups.first.guidances.each do |g| + assert viewable.include?(g), "expected the user to be able to view all funder guidance" end end @@ -104,222 +91,14 @@ end # --------------------------------------------------- - test "can manage has_many relationship with GuidanceGroup" do - gg = GuidanceGroup.new(name: 'Test Group', organisation: Organisation.first) - verify_has_many_relationship(@guidance, gg, @guidance.guidance_groups.count) - end - - # --------------------------------------------------- test "can manage has_many relationship with Theme" do t = Theme.new(title: 'Test Theme') verify_has_many_relationship(@guidance, t, @guidance.themes.count) end # --------------------------------------------------- - test "can manage belongs_to relationship with Question" do - verify_belongs_to_relationship(@guidance, @question) + test "can manage belongs_to relationship with GuidanceGroup" do + gg = GuidanceGroup.new(name: 'Test GuidanceGroup', org: Org.last, published: true) + verify_belongs_to_relationship(@guidance, gg) end -end -======= -require 'test_helper' - -class GuidanceTest < ActiveSupport::TestCase - - setup do - @user_one = User.first - @user_two = User.order(surname: :desc).first - @user_three = User.last - - @org_type = OrganisationType.first - - @organisations = Org.all - end - - # ---------- can_view? ---------- - # ensure that the can_view? function returns true all viewable guidances - # should return true for groups owned by funders - # should return true for groups owned by DCC - # should return true for groups owned by the user's organisation - # should not return true for an organisation outwith those above - test "DCC guidances should be viewable" do -=begin - guidance_groups(:dcc_guidance_group_1).guidances.each do |guidance| - assert Guidance.can_view?(@user_one, guidance.id) - end -=end - end - - test "Funder guidances should be viewable" do -=begin - assert Guidance.can_view?(@user_one, guidances(:ahrc_funder_guidance).id) - assert Guidance.can_view?(@user_one, guidances(:bbsrc_funder_guidance).id) -=end - end - - - test "User's organisation guidances should be viewable" do -=begin - assert Guidance.can_view?(@user_one, guidances(:aru_institution_guidance).id) , "user_one cannot view aru_institution_guidance" - - assert Guidance.can_view?(@user_two, guidances(:au_institution_guidance_1).id), "user_two cannot view au_..._1" - assert Guidance.can_view?(@user_two, guidances(:au_institution_guidance_2).id), "user_two cannot view au_..._2" - - assert Guidance.can_view?(@user_three, guidances(:bu_institution_guidance_1).id), "user_three cannot view bu_..._1" - assert Guidance.can_view?(@user_three, guidances(:bu_institution_guidance_2).id), "user_three cannot view bu_..._2" -=end - end - - test "No other organisations's guidances should be viewable" do -=begin - # TOOD: add more fixtures with new types of guidances(i.e. not institution) - # and add test cases - assert_not Guidance.can_view?(@user_one, guidances(:au_institution_guidance_1).id) - assert_not Guidance.can_view?(@user_one, guidances(:au_institution_guidance_2).id) - assert_not Guidance.can_view?(@user_one, guidances(:bu_institution_guidance_1).id) - assert_not Guidance.can_view?(@user_one, guidances(:bu_institution_guidance_2).id) - - assert_not Guidance.can_view?(@user_two, guidances(:aru_institution_guidance).id) - assert_not Guidance.can_view?(@user_two, guidances(:bu_institution_guidance_1).id) - assert_not Guidance.can_view?(@user_two, guidances(:bu_institution_guidance_2).id) - - assert_not Guidance.can_view?(@user_three, guidances(:aru_institution_guidance).id) - assert_not Guidance.can_view?(@user_three, guidances(:au_institution_guidance_1).id) - assert_not Guidance.can_view?(@user_three, guidances(:au_institution_guidance_2).id) -=end - end - -# ---------- all_viewable ---------- - # ensure that the all_viewable function returns all viewable guidances - # should return true for groups owned by funders - # should return true for groups owned by DCC - # should return true for groups owned by the user's organisation - # should not return true for an organisation outwith those above - test "all_viewable returns all DCC guidances" do -=begin - all_viewable_guidances = Guidance.all_viewable(@user_one) - @organisations.first.guidance_groups.each do |group| - group.guidances.each do |guidance| - assert_includes(all_viewable_guidances, guidance) - end - end -=end - end - - test "all_viewable returns all funder guidances" do -=begin - all_viewable_guidances = Guidance.all_viewable(@user_one) - guidance_groups(:funder_guidance_group_1).guidances.each do |guidance| - assert_includes(all_viewable_guidances, guidance) - end - guidance_groups(:funder_guidance_group_2).guidances.each do |guidance| - assert_includes(all_viewable_guidances, guidance) - end -=end - end - - test "all_viewable returns all of a user's organisations's guidances" do -=begin - all_viewable_guidances_one = Guidance.all_viewable(@user_one) - @organisations.first.guidance_groups.each do |group| - group.guidances.each do |guidance| - assert_includes(all_viewable_guidances_one, guidance) - end - end - - all_viewable_guidances_two = Guidance.all_viewable(@user_two) - @organisations[1].guidance_groups.each do |group| - group.guidances.each do |guidance| - assert_includes(all_viewable_guidances_two, guidance) - end - end - - all_viewable_guidances_three = Guidance.all_viewable(@user_three) - @organisations.last.guidance_groups.each do |group| - group.guidances.each do |guidance| - assert_includes(all_viewable_guidances_three, guidance) - end - end -=end - end - - - test "all_viewable does not return any other organisation's guidance" do -=begin - # TODO: Add in a suitable test. should we check for non-institutions? - all_viewable_guidances = Guidance.all_viewable(@user_one) - # remove all of the user's organisation - # remove all of each funder's organisations - # remove each of the dcc's organisations - # check if nill - all_viewable_guidances.delete_if do |guidance| - guidance.guidance_groups.each do |group| - if group.organisation.id == organisations(:dcc).id - true - elsif group.organisation.organisation_type.id == organisation_types(:funder).id - true - elsif group.organisation.id == @user_one.organisations.first.id - true - else - false - end - end - end - assert_empty(all_viewable_guidances, "there must not be any guidances which are not funders, DCC, or our own organisation") -=end - end - - # ---------- in_group_belonging_to? ---------- - test "in_group_belonging_to correctly identifies parent orgs" do -=begin - # test that the association works for all correct usages - Guidance.all.each do |guidance| - guidance.guidance_groups.each do |group| - assert(guidance.in_group_belonging_to?(group.organisation.id), "Guidance: #{guidance.text} should belong to organisation #{group.organisation.name}") - end - end -=end - end - - test "in_group_belonging_to rejects non-parent orgs" do -=begin - # test that in_group_belonging_to rejects a few interesting organisation-guidance pairs - assert_not(guidances(:related_policies).in_group_belonging_to?(organisations(:ahrc)), "Organisation ahrc does not own guidance: related policies") - assert_not(guidances(:ahrc_funder_guidance).in_group_belonging_to?(organisations(:dcc)), "Organisation dcc does not own guidance: ahrc_funder_guidance") -=end - end - - # ---------- by_organisation ---------- - test "by_organisation correctly returns all guidance belonging to a given org" do -=begin - Org.all.each do |org| - org_guidance = Guidance.by_organisation(org) - org.guidance_groups.each do |group| - group.guidances.each do |guidance| - assert_includes(org_guidance, guidance, "Guidance #{guidance.text} should belong to organisation: #{org.name}") - end - end - end -=end - end - - # ---------- get_guidance_group_templates ---------- - ## the main function is completely bugged, so ask to remove it - # test "get_guidance_group_templates retuns all templates belonging to a guidance group" do - # GuidanceGroup.all.each do |group| - # group_templates = guidances(:related_policies).get_guidance_group_templates?(group) - # group.dmptemplates.each do |template| - # assert_includes(group_templates, template, "group #{group.name} should include template #{template.title}") - # end - # end - # end - -end - - - - - - - - ->>>>>>> final_schema +end \ No newline at end of file diff --git a/test/unit/helpers/answers_helper_test.rb b/test/unit/helpers/answers_helper_test.rb deleted file mode 100644 index ba3e2d9..0000000 --- a/test/unit/helpers/answers_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class AnswersHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/dmptemplates_helper_test.rb b/test/unit/helpers/dmptemplates_helper_test.rb deleted file mode 100644 index 7703fda..0000000 --- a/test/unit/helpers/dmptemplates_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class DmptemplatesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/file_types_helper_test.rb b/test/unit/helpers/file_types_helper_test.rb deleted file mode 100644 index 02fd16e..0000000 --- a/test/unit/helpers/file_types_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class FileTypesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/file_uploads_helper_test.rb b/test/unit/helpers/file_uploads_helper_test.rb deleted file mode 100644 index d6bb15e..0000000 --- a/test/unit/helpers/file_uploads_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class FileUploadsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/guidances_helper_test.rb b/test/unit/helpers/guidances_helper_test.rb deleted file mode 100644 index 397b066..0000000 --- a/test/unit/helpers/guidances_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class GuidancesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/home_helper_test.rb b/test/unit/helpers/home_helper_test.rb deleted file mode 100644 index 4e72d63..0000000 --- a/test/unit/helpers/home_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class HomeHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/organisation_types_helper_test.rb b/test/unit/helpers/organisation_types_helper_test.rb deleted file mode 100644 index e355bde..0000000 --- a/test/unit/helpers/organisation_types_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class OrganisationTypesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/organisations_helper_test.rb b/test/unit/helpers/organisations_helper_test.rb deleted file mode 100644 index ba9c1df..0000000 --- a/test/unit/helpers/organisations_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class OrganisationsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/pages_helper_test.rb b/test/unit/helpers/pages_helper_test.rb deleted file mode 100644 index ec7d95a..0000000 --- a/test/unit/helpers/pages_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class PagesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/phases_helper_test.rb b/test/unit/helpers/phases_helper_test.rb deleted file mode 100644 index 5ea83b2..0000000 --- a/test/unit/helpers/phases_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class PhasesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/plan_sections_helper_test.rb b/test/unit/helpers/plan_sections_helper_test.rb deleted file mode 100644 index b196349..0000000 --- a/test/unit/helpers/plan_sections_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class PlanSectionsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/plans_helper_test.rb b/test/unit/helpers/plans_helper_test.rb deleted file mode 100644 index e440041..0000000 --- a/test/unit/helpers/plans_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class PlansHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/project_groups_helper_test.rb b/test/unit/helpers/project_groups_helper_test.rb deleted file mode 100644 index 00536a7..0000000 --- a/test/unit/helpers/project_groups_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class ProjectGroupsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/project_partners_helper_test.rb b/test/unit/helpers/project_partners_helper_test.rb deleted file mode 100644 index e34ac3f..0000000 --- a/test/unit/helpers/project_partners_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class ProjectPartnersHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/projects_helper_test.rb b/test/unit/helpers/projects_helper_test.rb deleted file mode 100644 index 2e6d5a7..0000000 --- a/test/unit/helpers/projects_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class ProjectsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/question_themes_helper_test.rb b/test/unit/helpers/question_themes_helper_test.rb deleted file mode 100644 index 96a1dc7..0000000 --- a/test/unit/helpers/question_themes_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class QuestionThemesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/questions_helper_test.rb b/test/unit/helpers/questions_helper_test.rb deleted file mode 100644 index 0c122f5..0000000 --- a/test/unit/helpers/questions_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class QuestionsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/sections_helper_test.rb b/test/unit/helpers/sections_helper_test.rb deleted file mode 100644 index aff16de..0000000 --- a/test/unit/helpers/sections_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class SectionsHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/themes_helper_test.rb b/test/unit/helpers/themes_helper_test.rb deleted file mode 100644 index 0a5c987..0000000 --- a/test/unit/helpers/themes_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class ThemesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/user_org_roles_helper_test.rb b/test/unit/helpers/user_org_roles_helper_test.rb deleted file mode 100644 index c02d2f2..0000000 --- a/test/unit/helpers/user_org_roles_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class UserOrgRolesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/user_role_types_helper_test.rb b/test/unit/helpers/user_role_types_helper_test.rb deleted file mode 100644 index a1c8e04..0000000 --- a/test/unit/helpers/user_role_types_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class UserRoleTypesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/user_statuses_helper_test.rb b/test/unit/helpers/user_statuses_helper_test.rb deleted file mode 100644 index 3d39852..0000000 --- a/test/unit/helpers/user_statuses_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class UserStatusesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/user_types_helper_test.rb b/test/unit/helpers/user_types_helper_test.rb deleted file mode 100644 index 7460858..0000000 --- a/test/unit/helpers/user_types_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class UserTypesHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/users_helper_test.rb b/test/unit/helpers/users_helper_test.rb deleted file mode 100644 index c77b035..0000000 --- a/test/unit/helpers/users_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class UsersHelperTest < ActionView::TestCase -end diff --git a/test/unit/helpers/versions_helper_test.rb b/test/unit/helpers/versions_helper_test.rb deleted file mode 100644 index f12ea8a..0000000 --- a/test/unit/helpers/versions_helper_test.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'test_helper' - -class VersionsHelperTest < ActionView::TestCase -end diff --git a/test/unit/language_test.rb b/test/unit/language_test.rb index e91143f..8447bbb 100644 --- a/test/unit/language_test.rb +++ b/test/unit/language_test.rb @@ -3,9 +3,9 @@ class LanguageTest < ActiveSupport::TestCase def setup - @lang = Language.first + @lang = Language.find_by(abbreviation: I18n.locale) @user = User.first - @organisation = @user.organisation + @org = @user.org end # --------------------------------------------------- @@ -37,14 +37,13 @@ # --------------------------------------------------- test "can manage has_many relationship with Users" do - user = User.new(email: 'me@example.edu', password: 'password') - verify_has_many_relationship(@lang, user, @lang.users.count) + verify_has_many_relationship(Language.last, User.last, Language.last.users.count) end # --------------------------------------------------- test "can manage has_many relationship with Organisations" do - org = Organisation.create(name: 'testing') - verify_has_many_relationship(@lang, org, @lang.organisations.count) + org = Org.create(name: 'testing', abbreviation: "TEST") + verify_has_many_relationship(Language.last, org, Language.last.orgs.count) end end \ No newline at end of file diff --git a/test/unit/note_test.rb b/test/unit/note_test.rb new file mode 100644 index 0000000..911adfe --- /dev/null +++ b/test/unit/note_test.rb @@ -0,0 +1,51 @@ +require 'test_helper' + +class NoteTest < ActiveSupport::TestCase + + setup do + @user = User.last + + scaffold_plan + + q = @plan.template.questions.select{|q| !q.question_format.option_based }.first + @answer = Answer.create(user: @user, plan: @plan, question: q, text: 'Testing') + + @note = Note.create(answer: @answer, user: @user, text: 'Test Note', archived: true, + archived_by: User.last) + end + + # --------------------------------------------------- + test "required fields are required" do + assert_not Note.new.valid? + assert_not Note.new(user: @user, answer: @answer).valid?, "expected the 'text' field to be required" + assert_not Note.new(answer: @answer, text: 'Testing').valid?, "expected the 'user' field to be required" + assert_not Note.new(user: @user, text: 'Testing').valid?, "expected the 'answer' field to be required" + + # Ensure the bar minimum and complete versions are valid + a = Note.new(user: @user, answer: @answer, text: 'Testing') + assert a.valid?, "expected the 'text', 'answer' and 'user' fields to be enough to create an Note! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + end + + # --------------------------------------------------- + test "can CRUD Note" do + obj = Note.create(user: @user, answer: @answer, text: 'Tested ABC') + assert_not obj.id.nil?, "was expecting to be able to create a new Note: #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + + obj.text = 'Testing an update' + obj.save! + obj.reload + assert_equal 'Testing an update', obj.text, "Was expecting to be able to update the text of the Note!" + + assert obj.destroy!, "Was unable to delete the Note!" + end + + # --------------------------------------------------- + test "can manage belongs_to relationship with Answer" do + verify_belongs_to_relationship(@note, @answer) + end + + # --------------------------------------------------- + test "can manage belongs_to relationship with User" do + verify_belongs_to_relationship(@note, @user) + end +end diff --git a/test/unit/option_test.rb b/test/unit/option_test.rb deleted file mode 100644 index 640b42e..0000000 --- a/test/unit/option_test.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'test_helper' - -class OptionTest < ActiveSupport::TestCase - include GlobalHelpers - - setup do - @user = User.first - - tmplt = generate_complete_template - @plan = Plan.create(project: Project.first, version: tmplt.phases.first.versions.first) - - @question = @plan.version.sections.first.questions.first - - @option = Option.create(question: @question, text: 'Test Option', number: 1) - end - - # --------------------------------------------------- - test "required fields are required" do - assert_not Option.new.valid? - assert_not Option.new(question: @question, text: 'Test').valid?, "expected the 'number' field to be required" - assert_not Option.new(question: @question, number: 1).valid?, "expected the 'text' and 'number' field to be required" - assert_not Option.new(text: 'Test', number: 1).valid?, "expected the 'question' and 'number' field to be required" - - # Ensure the bare minimum and complete versions are valid - a = Option.new(question: @question, text: 'Test', number: 1) - assert a.valid?, "expected the 'text', 'question' and 'number fields to be enough to create an Option! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - end - - # --------------------------------------------------- - test "to_s returns the text of the option warning" do - assert_equal @option.text, @option.to_s, "expected the to_s method to return the text field" - end - - # --------------------------------------------------- - test "can CRUD Guidance" do - obj = Option.create(question: @question, text: 'Test', number: 1) - assert_not obj.id.nil?, "was expecting to be able to create a new Option! #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - - obj.text = 'Testing an update' - obj.save! - obj.reload - assert_equal 'Testing an update', obj.text, "Was expecting to be able to update the text of the Option!" - - assert obj.destroy!, "Was unable to delete the Option!" - end - - # --------------------------------------------------- - test "can manage belongs_to relationship with Question" do - question = Question.new(text: 'Testing 123', section: Section.first, question_format: QuestionFormat.first) - verify_belongs_to_relationship(@option, question) - end - - # --------------------------------------------------- - test "can manage has_many relationship with OptionWarnings" do - ow = OptionWarning.new(text: 'Test', organisation: @user.organisation, option: @option) - verify_has_many_relationship(@option, ow, @option.option_warnings.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with Answers" do - answer = Answer.new(user: @user, plan: @plan, question: @question, text: 'Testing new answer') - verify_has_many_relationship(@option, answer, @option.answers.count) - end -end \ No newline at end of file diff --git a/test/unit/org_test.rb b/test/unit/org_test.rb new file mode 100644 index 0000000..b249f88 --- /dev/null +++ b/test/unit/org_test.rb @@ -0,0 +1,135 @@ +require 'test_helper' + +class OrgTest < ActiveSupport::TestCase + setup do + @org = Org.first + + @language = Language.find_by(abbreviation: I18n.default_locale) + end + + # ---------- required fields are required ------------ + test "required fields should be required" do + org = Org.new + assert_not(org.valid?) + + org.name = 'ABCD' + assert(org.valid?) + end + + # ---------- short_name ---------- + test "short_name should return the abbreviation if it exists" do + assert_equal(@org.abbreviation, @org.short_name) + end + + test "short_name should return the name if no abbreviation exists" do + @org.abbreviation = nil + assert_equal(@org.name, @org.short_name) + end + + # --------------------------------------------------- + test "to_s returns the name" do + assert_equal @org.name, @org.to_s + end + + # --------------------------------------------------- + test "only accepts valid contact_email addresses" do + assert @org.valid? + + @org.contact_email = 'testing' + assert_not @org.valid? + @org.contact_email = 'testing.tester.org' + assert_not @org.valid? + @org.contact_email = 'testing@tester' + assert_not @org.valid? + + @org.contact_email = 'testing@tester.org' + assert @org.valid? + end + + # --------------------------------------------------- + test "should resize logo to a height of 100" do + ['logo.jpg', # this one is at 160x160 + 'logo_300x300.jpg', + 'logo_100x100.jpg'].each do |file| + + path = File.expand_path("../../assets/#{file}", __FILE__) + @org.logo = Dragonfly.app.fetch_file("#{path}") + + assert @org.valid?, "expected the logo to have been attached to the org" + assert_equal 100, @org.logo.height, "expected the logo to have been resized properly" + end + end + + # --------------------------------------------------- + test "should remove all associated User's api tokens if no TokenPermissionTypes are present" do + @org.token_permission_types << TokenPermissionType.first + usr = User.new(email: 'tester@testing.org', password: 'testing123') + usr.keep_or_generate_token! + + original = usr.api_token + @org.users << usr + + # Make sure that the user's API token was saved + @org.save! + usr = @org.reload.users.find_by(email: 'tester@testing.org') + assert_equal original, usr.api_token + + # TODO: Determine if this should just be removed or if it should still be removing these + # Make sure that the user's API token is cleared out when all API permissions + # for the org have been removed + #@org.token_permission_types.clear + #@org.save! + #usr = @org.reload.users.find_by(email: 'tester@testing.org') + #assert_equal nil, usr.api_token + end + + # --------------------------------------------------- + test "can CRUD" do + org = Org.create(name: 'testing') + assert_not org.id.nil?, "was expecting to be able to create a new Org: #{org.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + + org.abbreviation = 'TEST' + org.save! + org.reload + assert_equal 'TEST', org.abbreviation, "Was expecting to be able to update the abbreviation of the Org!" + + assert org.destroy!, "Was unable to delete the Org!" + end + + # --------------------------------------------------- + test "can manage has_many relationship with Users" do + usr = User.create(email: 'test@testing.org', password: 'testing1234') + verify_has_many_relationship(@org, usr, @org.users.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with Dmptemplates" do + tmplt = Template.new(title: 'Added through test') + verify_has_many_relationship(@org, tmplt, @org.templates.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with Customisations" do + tmplt = Template.new(title: 'Testing template') + verify_has_many_relationship(@org, tmplt, @org.templates.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with GuidanceGroups" do + gg = GuidanceGroup.new(name: 'Tester') + verify_has_many_relationship(@org, gg, @org.guidance_groups.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with SuggestedAnswers" do + sa = SuggestedAnswer.new(question: Question.first, text: 'Test Suggested Answer') + verify_has_many_relationship(@org, sa, @org.suggested_answers.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with TokenPermissionTypes" do + tpt = TokenPermissionType.new(token_type: 'testing') + verify_has_many_relationship(@org, tpt, @org.token_permission_types.count) + end + +end diff --git a/test/unit/organisation_test.rb b/test/unit/organisation_test.rb deleted file mode 100644 index 230bbc0..0000000 --- a/test/unit/organisation_test.rb +++ /dev/null @@ -1,147 +0,0 @@ -require 'test_helper' - -class OrganisationTest < ActiveSupport::TestCase - setup do - @org = organisations(:curation_center) - - @org_type = OrganisationType.last - @language = languages(I18n.default_locale) - end - - # ---------- required fields are required ------------ - test "required fields should be required" do - org = Org.new - assert_not(org.valid?) - - org.name = 'ABCD' - assert(org.valid?) - end - - # ---------- short_name ---------- - test "short_name should return the abbreviation if it exists" do - assert_equal(@org.abbreviation, @org.short_name) - end - - test "short_name should return the name if no abbreviation exists" do - @org.abbreviation = nil - assert_equal(@org.name, @org.short_name) - end - - # --------------------------------------------------- - test "to_s returns the name" do - assert_equal @org.name, @org.to_s - end - - # --------------------------------------------------- - test "only accepts valid contact_email addresses" do - assert @org.valid? - - @org.contact_email = 'testing' - assert_not @org.valid? - @org.contact_email = 'testing.tester.org' - assert_not @org.valid? - @org.contact_email = 'testing@tester' - assert_not @org.valid? - - @org.contact_email = 'testing@tester.org' - assert @org.valid? - end - - # --------------------------------------------------- - test "should resize logo to a height of 100" do - ['logo.jpg', # this one is at 160x160 - 'logo_300x300.jpg', - 'logo_100x100.jpg'].each do |file| - - path = File.expand_path("../../assets/#{file}", __FILE__) - @org.logo = Dragonfly.app.fetch_file("#{path}") - - assert @org.valid?, "expected the logo to have been attached to the organisation" - assert_equal 100, @org.logo.height, "expected the logo to have been resized properly" - end - end - - # --------------------------------------------------- - test "should remove all associated User's api tokens if no TokenPermissionTypes are present" do - @org.token_permission_types << token_permission_types(:plans_token_type) - usr = User.new(email: 'tester@testing.org', password: 'testing123') - usr.keep_or_generate_token! - - original = usr.api_token - @org.users << usr - - # Make sure that the user's API token was saved - @org.save! - usr = @org.reload.users.find_by(email: 'tester@testing.org') - assert_equal original, usr.api_token - - # TODO: Determine if this should just be removed or if it should still be removing these - # Make sure that the user's API token is cleared out when all API permissions - # for the organisation have been removed - #@org.token_permission_types.clear - #@org.save! - #usr = @org.reload.users.find_by(email: 'tester@testing.org') - #assert_equal nil, usr.api_token - end - - # --------------------------------------------------- - test "can CRUD" do - org = Org.create(name: 'testing') - assert_not org.id.nil?, "was expecting to be able to create a new Organisation: #{org.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - - org.abbreviation = 'TEST' - org.save! - org.reload - assert_equal 'TEST', org.abbreviation, "Was expecting to be able to update the abbreviation of the Organisation!" - - assert org.destroy!, "Was unable to delete the Organisation!" - end - - # --------------------------------------------------- - test "can manage has_many relationship with Users" do - usr = User.create(email: 'test@testing.org', password: 'testing1234') - verify_has_many_relationship(@org, usr, @org.users.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with Dmptemplates" do - tmplt = Dmptemplate.new(title: 'Added through test') - verify_has_many_relationship(@org, tmplt, @org.dmptemplates.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with Customisations" do - tmplt = Dmptemplate.new(title: 'Testing template') - verify_has_many_relationship(@org, tmplt, @org.dmptemplates.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with GuidanceGroups" do - gg = GuidanceGroup.new(name: 'Tester') - verify_has_many_relationship(@org, gg, @org.guidance_groups.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with OptionWarnings" do - ow = OptionWarning.new(text: 'Test', option: Option.first) - verify_has_many_relationship(@org, ow, @org.option_warnings.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with SuggestedAnswers" do - sa = SuggestedAnswer.new(question: Question.first, text: 'Test Suggested Answer') - verify_has_many_relationship(@org, sa, @org.suggested_answers.count) - end - - # --------------------------------------------------- - test "can manage has_many relationship with TokenPermissionTypes" do - tpt = TokenPermissionType.new(token_type: 'testing') - verify_has_many_relationship(@org, tpt, @org.token_permission_types.count) - end - - # --------------------------------------------------- - test "can manage belongs_to relationship with OrganisationType" do - verify_belongs_to_relationship(@org, @org_type) - end - -end diff --git a/test/unit/organisation_type_test.rb b/test/unit/organisation_type_test.rb deleted file mode 100644 index 2412ea2..0000000 --- a/test/unit/organisation_type_test.rb +++ /dev/null @@ -1,89 +0,0 @@ -<<<<<<< HEAD -require 'test_helper' - -class OrganisationTypeTest < ActiveSupport::TestCase - - setup do - @organisation_type = OrganisationType.first - end - - # --------------------------------------------------- - test "required fields are required" do - assert_not OrganisationType.new.valid? - - # Ensure the bar minimum and complete versions are valid - a = OrganisationType.new(name: 'Tester') - assert a.valid?, "expected the 'name' field to be enough to create an OrganisationType! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - end - - # --------------------------------------------------- - test "can CRUD OrganisationType" do - obj = OrganisationType.create(name: 'Testing CRUD') - assert_not obj.id.nil?, "was expecting to be able to create a new OrganisationType! - #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" - - obj.name = 'Testing an update' - obj.save! - obj.reload - assert_equal 'Testing an update', obj.name, "Was expecting to be able to update the name of the OrganisationType!" - - assert obj.destroy!, "Was unable to delete the OrganisationType!" - end - - # --------------------------------------------------- - test "can manage has_many relationship with Organisation" do - org = Organisation.new(name: 'Test Organisation') - verify_has_many_relationship(@organisation_type, org, @organisation_type.organisations.count) - end - -end -======= -require 'test_helper' - -class OrganisationTypeTest < ActiveSupport::TestCase - def setup - # OrganisationTypes MUST match those defined in the locale's magic strings file - @organisation_type = organisation_types(I18n.t("magic_strings.organisation_types").first[0]) - end - - # --------------------------------------------------- - test "required fields are required" do - assert_not OrganisationType.new.valid? - assert_not OrganisationType.new(description: 'testing').valid? - - assert OrganisationType.new(name: 'test').valid? - assert OrganisationType.new(name: 'test', description: 'testing').valid? - end - - # --------------------------------------------------- - test "name must be unique" do - assert_not OrganisationType.new(name: @organisation_type.name).valid? - end - - # --------------------------------------------------- - test "can manage has_many relationship with Organisations" do - organisation = Org.new(name: 'test') - verify_has_many_relationship(@organisation_type, organisation, - @organisation_type.organisations.count) - end - - # --------------------------------------------------- - test "can CRUD" do - ot = OrganisationType.create(name: 'test', description: 'testing') - assert_not ot.id.nil?, "was expecting to be able to create a new OrganisationType" - - ot.description = 'testing 2' - ot.save! - ot.reload - assert_equal 'testing 2', ot.description, "Was expecting to be able to update the description of the OrganisationType!" - - assert ot.destroy!, "Was unable to delete the OrganisationType!" - end - - # --------------------------------------------------- - test "magic strings match the values in the database/fixtures" do - I18n.t("magic_strings.organisation_types").each do |k,v| - assert_not OrganisationType.find_by(name: v).nil?, "An OrganisationType called #{v} is defined in the magic strings section of the locale file, but no matching value exists in the datbase/fixtures!" - end - end -end ->>>>>>> final_schema diff --git a/test/unit/perm_test.rb b/test/unit/perm_test.rb new file mode 100644 index 0000000..a40c704 --- /dev/null +++ b/test/unit/perm_test.rb @@ -0,0 +1,43 @@ +require 'test_helper' + +class PermTest < ActiveSupport::TestCase + + setup do + @user = User.last + + @perm = Perm.create(name: 'testing') + end + + # --------------------------------------------------- + test "required fields are required" do + assert_not Perm.new.valid? + + # Ensure the bare minimum and complete versions are valid + a = Perm.new(name: 'Testing 2') + assert a.valid?, "expected the 'name' field to be enough to create an Perm! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + end + + # --------------------------------------------------- + test "name field must be unique" do + assert_not Perm.new(name: 'testing').valid? + end + + # --------------------------------------------------- + test "can CRUD Perm" do + obj = Perm.create(name: 'Tested ABC') + assert_not obj.id.nil?, "was expecting to be able to create a new Perm: #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + + obj.name = 'Testing an update' + obj.save! + obj.reload + assert_equal 'Testing an update', obj.name, "Was expecting to be able to update the name of the Perm!" + + assert obj.destroy!, "Was unable to delete the Perm!" + end + + # --------------------------------------------------- + test "can manage has_many relationship with User" do + verify_has_many_relationship(@perm, @user, @perm.users.count) + end + +end diff --git a/test/unit/phase_test.rb b/test/unit/phase_test.rb index 2c98714..40670fb 100644 --- a/test/unit/phase_test.rb +++ b/test/unit/phase_test.rb @@ -3,26 +3,26 @@ class PhaseTest < ActiveSupport::TestCase setup do - @organisation = Organisation.first - @template = Dmptemplate.first - @phase = Phase.create(title: 'Test Phase 1', number: 1, dmptemplate: @template) + @org = Org.first + @template = Template.first + @phase = Phase.create(title: 'Test Phase 1', number: 1, template: @template) end # --------------------------------------------------- test "required fields are required" do assert_not Phase.new.valid? assert_not Phase.new(title: 'Testing', number: 1).valid?, "expected the dmptemplate field to be required" - assert_not Phase.new(number: 2, dmptemplate: @template).valid?, "expected the title field to be required" - assert_not Phase.new(title: 'Testing', dmptemplate: @template).valid?, "expected the number field to be required" + assert_not Phase.new(number: 2, template: @template).valid?, "expected the title field to be required" + assert_not Phase.new(title: 'Testing', template: @template).valid?, "expected the number field to be required" # Ensure the bar minimum and complete versions are valid - a = Phase.new(title: 'Testing', dmptemplate: @template, number: 2) - assert a.valid?, "expected the 'title', 'number' and 'dmptemplate' fields to be enough to create an Phase! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + a = Phase.new(title: 'Testing', template: @template, number: 2) + assert a.valid?, "expected the 'title', 'number' and 'template' fields to be enough to create an Phase! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" end # --------------------------------------------------- test "a slug is properly generated when creating a record" do - a = Phase.create(title: 'Testing 123', dmptemplate: @template, number: 2) + a = Phase.create(title: 'Testing 123', template: @template, number: 2) assert_equal "testing-123", a.slug end @@ -32,28 +32,13 @@ end # --------------------------------------------------- - test "latest_published_version returns the correct version" do - assert_equal nil, @phase.latest_published_version, "expected nil if there is only one version and it was not specifically designated as published" - - 4.times do |i| - @phase.versions << Version.new(title: "Version #{i}", number: i, - published: (i == 3 ? true : false)) - end - - @phase.save! - @phase.reload - - assert_equal 3, @phase.latest_published_version.number, "expected the last published version if there there were multiple published versions" - end - - # --------------------------------------------------- test "has_sections returns false if there are NO published versions with sections" do # TODO: build out this test if the has_sections method is actually necessary end # --------------------------------------------------- test "can CRUD Phase" do - obj = Phase.create(title: 'Testing CRUD', dmptemplate: @template, number: 4) + obj = Phase.create(title: 'Testing CRUD', template: @template, number: 4) assert_not obj.id.nil?, "was expecting to be able to create a new Phase! - #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" obj.title = 'Testing an update' @@ -65,14 +50,14 @@ end # --------------------------------------------------- - test "can manage has_many relationship with Versions" do - v = Version.new(title: 'Test Version', number: 2) - verify_has_many_relationship(@phase, v, @phase.versions.count) + test "can manage has_many relationship with Sections" do + s = Section.new(title: 'Test Section', number: 2) + verify_has_many_relationship(@phase, s, @phase.sections.count) end # --------------------------------------------------- - test "can manage belongs_to relationship with Dmptemplate" do - tmplt = Dmptemplate.create(organisation: @organisation, title: 'Testing relationship') + test "can manage belongs_to relationship with Template" do + tmplt = Template.create(org: @org, title: 'Testing relationship') verify_belongs_to_relationship(@phase, tmplt) end end diff --git a/test/unit/plan_test.rb b/test/unit/plan_test.rb new file mode 100644 index 0000000..1275ab6 --- /dev/null +++ b/test/unit/plan_test.rb @@ -0,0 +1,76 @@ +require 'test_helper' + +class PlanTest < ActiveSupport::TestCase + + setup do + @org = Org.first + @template = Template.first + @plan = Plan.create(title: 'Test Plan', template: @template, grant_number: 'Plan12345', + identifier: '000912', description: 'This is a test plan', + principal_investigator: 'John Doe', principal_investigator_identifier: 'ABC', + data_contact: 'john.doe@example.com', visibility: 1, users: [User.last]) + end + + # --------------------------------------------------- + test "required fields are required" do + assert_not Plan.new.valid? + assert_not Plan.new(users: [User.last], title: 'Testing').valid?, "expected the template field to be required" + assert_not Plan.new(template: @template, title: 'Testing').valid?, "expected at least one user to be required" + + # Make sure that the Settings gem is defaulting the title for us + assert Plan.new(users: [User.last], template: @template).valid?, "expected the title field to have been set by default by the Settings gem" + + # Ensure the bare minimum and complete versions are valid + a = Plan.new(title: 'Testing', template: @template, users: [User.last]) + assert a.valid?, "expected the 'title', 'template' and at least one 'user' fields to be enough to create an Plan! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + end + + # --------------------------------------------------- + test "a slug is properly generated when creating a record" do + #p = Plan.create(title: 'Testing 123', template: @template, users: [User.last]) + #assert_equal "testing-123", p.slug + end + + # --------------------------------------------------- + test "has_sections returns false if there are NO published versions with sections" do + # TODO: build out this test if the has_sections method is actually necessary + end + + # --------------------------------------------------- + test "can CRUD Plan" do + obj = Plan.create(title: 'Testing CRUD', template: Template.where.not(id: @template.id).first, + users: [User.last], description: "should change") + 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' + obj.save! + obj.reload + assert_equal 'changed', obj.description, "Was expecting to be able to update the title of the Plan!" + + assert obj.destroy!, "Was unable to delete the Plan!" + end + + # --------------------------------------------------- + test "can manage has_many relationship with Answers" do + a = Answer.new(user: User.last, plan: @plan, question: @plan.questions.first, text: 'Test!') + verify_has_many_relationship(@plan, a, @plan.answers.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with Users" do + verify_has_many_relationship(@plan, User.first, @plan.users.count) + end + + # --------------------------------------------------- + test "can manage has_many relationship with ExportedPlan" do + ep = ExportedPlan.create(format: ExportedPlan::VALID_FORMATS.last) + verify_has_many_relationship(@plan, ep, @plan.exported_plans.count) + end + + # --------------------------------------------------- + test "can manage belongs_to relationship with Template" do + tmplt = Template.create(org: @org, title: 'Testing relationship') + verify_belongs_to_relationship(@plan, tmplt) + end + +end diff --git a/test/unit/question_option_test.rb b/test/unit/question_option_test.rb new file mode 100644 index 0000000..52b7674 --- /dev/null +++ b/test/unit/question_option_test.rb @@ -0,0 +1,53 @@ +require 'test_helper' + +class QuestionQuestionOptionTest < ActiveSupport::TestCase + include GlobalHelpers + + setup do + @user = User.first + + @question = QuestionFormat.find_by(option_based: true).questions.first + + @plan = Plan.create(title: 'Test Plan', template: @question.section.phase.template) + + @option = QuestionOption.create(question: @question, text: 'Test QuestionOption', number: 1) + end + + # --------------------------------------------------- + test "required fields are required" do + assert_not QuestionOption.new.valid? + assert_not QuestionOption.new(question: @question, text: 'Test').valid?, "expected the 'number' field to be required" + assert_not QuestionOption.new(question: @question, number: 1).valid?, "expected the 'text' and 'number' field to be required" + assert_not QuestionOption.new(text: 'Test', number: 1).valid?, "expected the 'question' and 'number' field to be required" + + # Ensure the bare minimum and complete versions are valid + a = QuestionOption.new(question: @question, text: 'Test', number: 1) + assert a.valid?, "expected the 'text', 'question' and 'number fields to be enough to create an QuestionOption! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + end + + # --------------------------------------------------- + test "can CRUD Guidance" do + obj = QuestionOption.create(question: @question, text: 'Test', number: 1) + assert_not obj.id.nil?, "was expecting to be able to create a new QuestionOption! #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}" + + obj.text = 'Testing an update' + obj.save! + obj.reload + assert_equal 'Testing an update', obj.text, "Was expecting to be able to update the text of the QuestionOption!" + + assert obj.destroy!, "Was unable to delete the QuestionOption!" + end + + # --------------------------------------------------- + test "can manage belongs_to relationship with Question" do + question = Question.new(text: 'Testing 123', section: Section.first, question_format: QuestionFormat.find_by(option_based: true)) + verify_belongs_to_relationship(@option, question) + end + + # --------------------------------------------------- + test "can manage has_many relationship with Answers" do + answer = Answer.new(user: @user, plan: @plan, question: @question, text: 'Testing new answer', + question_options: [@question.question_options.first]) + verify_has_many_relationship(@option, answer, @option.answers.count) + end +end \ No newline at end of file