diff --git a/app/models/document.rb b/app/models/document.rb index b42c78f..6410dda 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -10,9 +10,9 @@ class Document < ApplicationRecord #### VALIDATIONS validates_presence_of :file, :user, :thesis - validate :primary_file_presence, on: :create - validate :supplemental_file_must_be_file_types - validate :primary_file_must_be_pdf + validate :one_primary_file_per_thesis, on: :create + validate :validate_extension + validate :validate_usage #### SCOPES scope :newest, -> { order('created_at desc') } @@ -28,7 +28,8 @@ class Document < ApplicationRecord enum usage: %i[thesis embargo embargo_letter licence] attribute :usage, default: :thesis - + attribute :supplemental, default: true + attribute :deleted, default: false PRIMARY_FILE_EXT = [ '.pdf' ].freeze SUPPLEMENTAL_FILE_EXT = ['.pdf', '.doc', '.docx', '.txt', '.html', '.htm', '.odt', '.odp', @@ -41,14 +42,14 @@ def allowed_extensions list = PRIMARY_FILE_EXT case document_type - when 'primary' - list = PRIMARY_FILE_EXT when 'supplemental' list = SUPPLEMENTAL_FILE_EXT when 'licence' list = LICENCE_FILE_EXT when 'embargo' list = EMBARGO_FILE_EXT + else + list = PRIMARY_FILE_EXT end return list @@ -67,43 +68,48 @@ def display_name name end + def primary? + return !supplemental? + end + ### CUSTOM VALIDATIONS - def primary_file_presence - if thesis && (thesis.documents.primary.not_deleted.size.positive? && supplemental? == false && deleted? == false) - errors.add(:file, 'You can only upload one primary file per thesis') + def one_primary_file_per_thesis + if primary? && !deleted? && thesis && thesis.has_primary_file? + errors.add(:file, 'Only one primary file allowed.') end end - def primary_file_must_be_pdf - return unless file.filename.present? && !supplemental - - return if file.filename.downcase.end_with?('.pdf') - - errors.add(:file, "extension #{ext} is not allowed.") + def file_extension + return nil unless file.filename.present? + ext = '.' + file.filename.downcase.split('.').pop end - def supplemental_file_must_be_file_types - supplemental_file_types = SUPPLEMENTAL_FILE_EXT - embargo_file_types = EMBARGO_FILE_EXT - - return unless file.filename.present? && supplemental + def validate_extension + if !valid_extension? + errors.add(:file, "Extension #{file_extension} is not allowed.") + end + end - ext = '.' + file.filename.downcase.split('.').pop + def valid_extension? + return allowed_extensions.include? file_extension + end - if document_type == "licence" - return if file.filename.downcase.end_with?('.pdf') - elsif document_type == "supplemental" - return if supplemental_file_types.include?(File.extname(file.filename.downcase)) - elsif document_type == "embargo" - return if embargo_file_types.include?(File.extname(file.filename.downcase)) + def validate_usage + if !valid_usage? + errors.add(:usage, 'Primary file usage must be "thesis".') end + end - errors.add(:file, "extension #{ext} is not allowed.") + def valid_usage? + if primary? && usage != 'thesis' + return false + end + return true end def document_type return 'supplemental' if self.usage == "thesis" && self.supplemental? - return 'primary' if self.usage == "thesis" && !self.supplemental? + return 'primary' if self.usage == "thesis" && self.primary? return 'embargo' if self.usage == "embargo" || self.usage == "embargo_letter" return 'licence' if self.usage == "licence" end diff --git a/app/models/thesis.rb b/app/models/thesis.rb index 97d0e10..41d83c3 100644 --- a/app/models/thesis.rb +++ b/app/models/thesis.rb @@ -197,4 +197,8 @@ def publish def self.assigned_to_user(user) Thesis.where('assigned_to_id = ?', user.id) end + + def has_primary_file? + return documents.primary.not_deleted.size > 0 + end end diff --git a/test/models/document_test.rb b/test/models/document_test.rb index cbcb6c5..5d1cdf2 100644 --- a/test/models/document_test.rb +++ b/test/models/document_test.rb @@ -25,6 +25,31 @@ class DocumentTest < ActiveSupport::TestCase assert !build(:document, file: nil).valid?, 'File is required' assert !build(:document, user: nil).valid?, 'User/owner is required' assert !build(:document, thesis: nil).valid?, 'Thesis is required' + + # should not be able to create a primary file with extension .jpg + doc = build(:document, usage: 'thesis', supplemental: false, file: fixture_file_upload('image-example.jpg')) + assert '.jpg', doc.file_extension + assert !doc.valid_extension?, 'extension .jpg should not be valid for primary file' + assert doc.primary?, "must be primary" + assert !doc.supplemental?, "must not be supplemental" + assert_equal 'thesis', doc.usage, 'usage must be "thesis"' + assert !doc.valid?, 'Should not be valid, extension cannot be .jpg' + + # should not be able to create a primary file with usage "licence" + doc = build(:document, usage: 'licence', supplemental: false, file: fixture_file_upload('pdf-document.pdf')) + assert '.pdf', doc.file_extension + assert doc.valid_extension?, 'extension should be valid' + assert doc.primary?, "must be primary" + assert_equal 'licence', doc.usage, 'usage must be "licence"' + assert !doc.valid?, 'Should not be valid, usage can not be "licence" AND not supplemental' + + # should not be able to create a primary file with usage "embargo" + doc = build(:document, usage: 'embargo', supplemental: false, file: fixture_file_upload('pdf-document.pdf')) + assert '.pdf', doc.file_extension + assert doc.valid_extension?, 'extension should be valid' + assert doc.primary?, "must be primary" + assert_equal 'embargo', doc.usage, 'usage must be "embargo"' + assert !doc.valid?, 'Should not be valid, usage can not be "embargo" AND not supplemental' end should 'only allow one primary file per thesis, and it should ignore deleted' do