Merge pull request #154 from mz3944/mz_replace_hardcoded_values_with_constants

Mz replace hardcoded values with constants
This commit is contained in:
mz3944 2016-09-16 16:03:19 +02:00 committed by GitHub
commit 57563b9a18
38 changed files with 127 additions and 122 deletions

View file

@ -301,9 +301,10 @@ function processResult(ev, resultTypeEnum, editMode, forS3) {
switch(resultTypeEnum) {
case ResultTypeEnum.FILE:
var $nameInput = $form.find("#result_name");
var nameValid = textValidator(ev, $nameInput, true);
var nameValid = textValidator(ev, $nameInput, TextLimitEnum.OPTIONAL,
TextLimitEnum.NAME_MAX_LENGTH);
var $fileInput = $form.find("#result_asset_attributes_file");
var filesValid = filesValidator(ev, $fileInput, FileTypeEnum.FILE, editMode);
var filesValid = filesValidator(ev, $fileInput, FileTypeSizeEnum.FILE, editMode);
if(nameValid && filesValid) {
if(forS3) {
@ -318,17 +319,21 @@ function processResult(ev, resultTypeEnum, editMode, forS3) {
break;
case ResultTypeEnum.TABLE:
var $nameInput = $form.find("#result_name");
var nameValid = textValidator(ev, $nameInput, true);
var nameValid = textValidator(ev, $nameInput, TextLimitEnum.OPTIONAL,
TextLimitEnum.NAME_MAX_LENGTH);
break;
case ResultTypeEnum.TEXT:
var $nameInput = $form.find("#result_name");
var nameValid = textValidator(ev, $nameInput, true);
var nameValid = textValidator(ev, $nameInput, TextLimitEnum.OPTIONAL,
TextLimitEnum.NAME_MAX_LENGTH);
var $textInput = $form.find("#result_result_text_attributes_text");
textValidator(ev, $textInput, false, false);
textValidator(ev, $textInput, TextLimitEnum.REQUIRED,
TextLimitEnum.TEXT_MAX_LENGTH);
break;
case ResultTypeEnum.COMMENT:
var $commentInput = $form.find("#comment_message");
var commentValid = textValidator(ev, $commentInput, false, false);
var commentValid = textValidator(ev, $commentInput, TextLimitEnum.REQUIRED,
TextLimitEnum.TEXT_MAX_LENGTH);
break;
}
}

View file

@ -497,7 +497,7 @@ function importProtocolFromFile(
$.extend(data_json, params);
var rough_size = roughSizeOfObject(data_json);
if (rough_size > <%= FILE_SIZE_LIMIT.megabytes %>) {
if (rough_size > <%= FILE_MAX_SIZE.megabytes %>) {
// Call the callback function
resultCallback({ name: protocolJson["name"], new_name: null, status: "size_too_large" });
return;

View file

@ -610,11 +610,12 @@ function processStep(ev, editMode, forS3) {
$form.removeBlankFileForms();
var $fileInputs = $form.find("input[type=file]");
var filesValid = filesValidator(ev, $fileInputs, FileTypeEnum.FILE);
var filesValid = filesValidator(ev, $fileInputs, FileTypeSizeEnum.FILE);
var $checklists = $form.find(".nested_step_checklists");
var checklistsValid = checklistsValidator(ev, $checklists, editMode);
var $nameInput = $form.find("#step_name");
var nameValid = textValidator(ev, $nameInput);
var nameValid = textValidator(ev, $nameInput, TextLimitEnum.REQUIRED,
TextLimitEnum.NAME_MAX_LENGTH);
if (filesValid && checklistsValid && nameValid) {
if (forS3) {

View file

@ -18,16 +18,27 @@ $.fn.onSubmitValidator = function(validatorCb) {
}
};
function textValidator(ev, textInput, canBeBlank, limitLength) {
canBeBlank = (typeof canBeBlank !== 'undefined') ? canBeBlank : false;
limitLength = (typeof limitLength !== 'undefined') ? limitLength : true;
var nameTooShort = $(textInput).val().length === 0;
var nameTooLong = $(textInput).val().length > 50;
var TextLimitEnum = Object.freeze({
OPTIONAL: 0,
REQUIRED: 1,
NAME_MIN_LENGTH: '<%= NAME_MIN_LENGTH %>',
NAME_MAX_LENGTH: '<%= NAME_MAX_LENGTH %>',
TEXT_MAX_LENGTH: '<%= TEXT_MAX_LENGTH %>'
});
function textValidator(ev, textInput, textLimitEnumMin, textLimitEnumMax) {
var nameTooShort = $(textInput).val().length < textLimitEnumMin;
var nameTooLong = $(textInput).val().length > textLimitEnumMax;
var errMsg;
if (!canBeBlank && nameTooShort) {
errMsg = I18n.t("general.text.not_blank");
} else if (limitLength && nameTooLong) {
errMsg = I18n.t("general.text.length_too_long", { max_length: 50 });
if (nameTooShort) {
if (textLimitEnumMin === TextLimitEnum.REQUIRED) {
errMsg = I18n.t("general.text.not_blank");
} else {
errMsg = I18n.t("general.text.length_too_short", { min_length: textLimitEnumMin });
}
} else if (nameTooLong) {
errMsg = I18n.t("general.text.length_too_long", { max_length: textLimitEnumMax });
}
var noErrors = _.isUndefined(errMsg);
@ -52,7 +63,7 @@ function checklistsValidator(ev, checklists, editMode) {
if ($item.css('display') != 'none') {
if ($itemInput.val()) {
var itemNameValid = textValidator(ev, $itemInput);
var itemNameValid = textValidator(ev, $itemInput, TextLimitEnum.REQUIRED, TextLimitEnum.TEXT_MAX_LENGTH);
if (!itemNameValid) {
noErrors = false;
}
@ -64,10 +75,12 @@ function checklistsValidator(ev, checklists, editMode) {
}
})
var $checklistInput = $checklist.find(".checklist_name");
// In edit mode, checklist's name can't be blank if any items present
var allowBlankChklstName = !(anyChecklistItemFilled || editMode);
var $checklistNameInput = $checklist.find(".checklist_name");
var checklistNameValid = textValidator(ev, $checklistNameInput, allowBlankChklstName);
var textLimitEnumMin = allowBlankChklstName ? TextLimitEnum.OPTIONAL : TextLimitEnum.REQUIRED;
var checklistNameValid = textValidator(ev, $checklistInput,
textLimitEnumMin, TextLimitEnum.TEXT_MAX_LENGTH);
if (!checklistNameValid) {
noErrors = false;
} else if (allowBlankChklstName) {
@ -80,9 +93,9 @@ function checklistsValidator(ev, checklists, editMode) {
return noErrors;
}
var FileTypeEnum = Object.freeze({
FILE: 0,
AVATAR: 1
var FileTypeSizeEnum = Object.freeze({
FILE: '<%= FILE_MAX_SIZE.megabytes %>',
AVATAR: '<%= AVATAR_MAX_SIZE.megabytes %>'
});
function filesValidator(ev, fileInputs, fileTypeEnum, canBeEmpty) {
@ -115,14 +128,13 @@ function filesSizeValidator(ev, fileInputs, fileTypeEnum) {
if (!file) {
return ;
}
var size = parseInt(file.size);
<% avatarSizerLimit = AVATAR_SIZE_LIMIT %>;
<% fileSizeLimit = FILE_SIZE_LIMIT %>;
if (fileTypeEnum == FileTypeEnum.FILE && size > <%= fileSizeLimit.megabytes %>) {
return "<%= I18n.t 'general.file.size_exceeded', file_size: fileSizeLimit %>".strToErrorFormat();
} else if (fileTypeEnum == FileTypeEnum.AVATAR && size > <%= avatarSizerLimit.megabytes %>) {
return "<%= I18n.t 'general.file.size_exceeded', file_size: avatarSizerLimit %>".strToErrorFormat();
if (file.size > fileTypeEnum) {
switch (fileTypeEnum) {
case FileTypeSizeEnum.FILE:
return "<%= I18n.t 'general.file.size_exceeded', file_size: FILE_MAX_SIZE %>".strToErrorFormat();
case FileTypeSizeEnum.AVATAR:
return "<%= I18n.t 'general.file.size_exceeded', file_size: AVATAR_MAX_SIZE %>".strToErrorFormat();
}
}
};

View file

@ -68,7 +68,7 @@ function processFile(ev, forS3) {
$form.clearFormErrors();
var $fileInput = $form.find("input[type=file]");
if(filesValidator(ev, $fileInput, FileTypeEnum.AVATAR)) {
if(filesValidator(ev, $fileInput, FileTypeSizeEnum.AVATAR)) {
if(forS3) {
// Redirects file uploading to S3
var url = "/avatar_signature.json";

View file

@ -1,3 +1,7 @@
// Place all the styles related to the StepComments controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.step-panel-collapse-link {
word-wrap: break-word;
}

View file

@ -8,16 +8,16 @@ class AssetsController < ApplicationController
respond_to do |format|
format.json {
asset = Asset.new(asset_params)
if asset.errors.any?
render json: {
status: 'error',
errors: asset.errors
}, status: :bad_request
else
if asset.valid?
posts = generate_upload_posts asset
render json: {
posts: posts
}
else
render json: {
status: 'error',
errors: asset.errors
}, status: :bad_request
end
}
end
@ -106,7 +106,7 @@ class AssetsController < ApplicationController
success_action_status: '201',
acl: 'private',
storage_class: "STANDARD",
content_length_range: 1..(FILE_SIZE_LIMIT.megabytes),
content_length_range: 1..FILE_MAX_SIZE.megabytes,
content_type: asset.file_content_type
)
posts.push({
@ -121,7 +121,7 @@ class AssetsController < ApplicationController
success_action_status: '201',
acl: 'public-read',
storage_class: "REDUCED_REDUNDANCY",
content_length_range: 1..(FILE_SIZE_LIMIT.megabytes),
content_length_range: 1..FILE_MAX_SIZE.megabytes,
content_type: asset.file_content_type
)
posts.push({

View file

@ -11,7 +11,7 @@ class OrganizationsController < ApplicationController
if params[:file]
begin
if params[:file].size > FILE_SIZE_LIMIT.megabytes
if params[:file].size > FILE_MAX_SIZE.megabytes
error = t("organizations.parse_sheet.errors.file_size_exceeded")
format.html {
flash[:alert] = error

View file

@ -228,7 +228,7 @@ class Users::RegistrationsController < Devise::RegistrationsController
success_action_status: '201',
acl: 'public-read',
storage_class: "REDUCED_REDUNDANCY",
content_length_range: 1..(FILE_SIZE_LIMIT.megabytes),
content_length_range: 1..FILE_MAX_SIZE.megabytes,
content_type: content_type
)
posts.push({

View file

@ -12,7 +12,9 @@ class Asset < ActiveRecord::Base
}
}
validates_attachment :file, presence: true, size: { less_than: FILE_SIZE_LIMIT.megabytes }
validates_attachment :file,
presence: true,
size: { less_than: FILE_MAX_SIZE.megabytes }
validates :estimated_size, presence: true
validates :file_present, inclusion: { in: [true, false] }
@ -46,7 +48,7 @@ class Asset < ActiveRecord::Base
# so use just these errors
after_validation :filter_paperclip_errors
# Needed because Paperclip validatates on creation
after_create :filter_paperclip_errors
after_initialize :filter_paperclip_errors, if: :new_record?
attr_accessor :file_content, :file_info, :preview_cached

View file

@ -1,8 +1,6 @@
class Checklist < ActiveRecord::Base
include SearchableModel
validates :name,
presence: true,
length: { maximum: 50 }
validates :name, presence: true, length: { maximum: TEXT_MAX_LENGTH }
validates :step, presence: true
belongs_to :step, inverse_of: :checklists

View file

@ -1,7 +1,5 @@
class ChecklistItem < ActiveRecord::Base
validates :text,
presence: true,
length: { maximum: 1000 }
validates :text, presence: true, length: { maximum: TEXT_MAX_LENGTH }
validates :checklist, presence: true
validates :checked, inclusion: { in: [true, false] }

View file

@ -1,9 +1,7 @@
class Comment < ActiveRecord::Base
include SearchableModel
validates :message,
presence: true,
length: { maximum: 1000 }
validates :message, presence: true, length: { maximum: TEXT_MAX_LENGTH }
validates :user, presence: true
validate :belongs_to_only_one_object

View file

@ -1,7 +1,7 @@
class CustomField < ActiveRecord::Base
validates :name,
presence: true,
length: { maximum: 50 },
length: { maximum: NAME_MAX_LENGTH },
uniqueness: { scope: :organization, case_sensitive: true},
exclusion: {in: ["Assigned", "Sample name", "Sample type", "Sample group", "Added on", "Added by"]}
validates :user, :organization, presence: true

View file

@ -18,10 +18,9 @@ class Experiment < ActiveRecord::Base
if: :workflowimg_check
validates :name,
presence: true,
length: { minimum: 4, maximum: 50 },
length: { minimum: NAME_MIN_LENGTH, maximum: NAME_MAX_LENGTH },
uniqueness: { scope: :project, case_sensitive: false }
validates :description, length: { maximum: 255 }
validates :description, length: { maximum: TEXT_MAX_LENGTH }
validates :project, presence: true
validates :created_by, presence: true
validates :last_modified_by, presence: true

View file

@ -4,8 +4,7 @@ class MyModule < ActiveRecord::Base
before_create :create_blank_protocol
validates :name,
presence: true,
length: { minimum: 2, maximum: 50 }
length: { minimum: NAME_MIN_LENGTH, maximum: NAME_MAX_LENGTH }
validates :x, :y, :workflow_order, presence: true
validates :experiment, presence: true
validates :my_module_group, presence: true, if: "!my_module_group_id.nil?"

View file

@ -1,9 +1,7 @@
class MyModuleGroup < ActiveRecord::Base
include SearchableModel
validates :name,
presence: true,
length: { maximum: 50 }
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :experiment, presence: true
belongs_to :experiment, inverse_of: :my_module_groups

View file

@ -4,10 +4,8 @@ class Organization < ActiveRecord::Base
include ActionView::Helpers::NumberHelper
validates :name,
presence: { message: '' },
length: { minimum: 4, maximum: 100, message: '' }
validates :space_taken,
presence: true
length: { minimum: NAME_MIN_LENGTH, maximum: NAME_MAX_LENGTH }
validates :space_taken, presence: true
belongs_to :created_by, :foreign_key => 'created_by_id', :class_name => 'User'
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User'
@ -49,7 +47,7 @@ class Organization < ActiveRecord::Base
end
end
# Writes to user log.
# Writes to user log
def log(message)
final = "[%s] %s" % [Time.current.to_s, message]
logs.create(message: final)

View file

@ -4,9 +4,8 @@ class Project < ActiveRecord::Base
enum visibility: { hidden: 0, visible: 1 }
validates :name,
presence: true,
length: { minimum: 4, maximum: 30 },
uniqueness: { scope: :organization, case_sensitive: false }
length: { minimum: NAME_MIN_LENGTH, maximum: NAME_MAX_LENGTH },
uniqueness: { scope: :organization, case_sensitive: false }
validates :visibility, presence: true
validates :organization, presence: true

View file

@ -13,7 +13,8 @@ class Protocol < ActiveRecord::Base
in_repository_archived: 4
}
validates :name, length: { maximum: 100 }
# Name is required when its actually specified (i.e. :in_repository? is true)
validates :name, length: { maximum: NAME_MAX_LENGTH }
validates :organization, presence: true
validates :protocol_type, presence: true

View file

@ -1,5 +1,5 @@
class ProtocolKeyword < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 50 }
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :organization, presence: true
belongs_to :organization, inverse_of: :protocol_keywords

View file

@ -2,10 +2,9 @@ class Report < ActiveRecord::Base
include SearchableModel
validates :name,
presence: true,
length: { minimum: 2, maximum: 30 },
uniqueness: { scope: [:user, :project], case_sensitive: false }
validates :description, length: { maximum: 1000 }
length: { minimum: NAME_MIN_LENGTH, maximum: NAME_MAX_LENGTH },
uniqueness: { scope: [:user, :project], case_sensitive: false }
validates :description, length: { maximum: TEXT_MAX_LENGTH }
validates :project, presence: true
validates :user, presence: true

View file

@ -2,8 +2,7 @@ class Result < ActiveRecord::Base
include ArchivableModel, SearchableModel
validates :user, :my_module, presence: true
validates :name,
length: { maximum: 50 }
validates :name, length: { maximum: NAME_MAX_LENGTH }
validate :text_or_asset_or_table
belongs_to :user, inverse_of: :results

View file

@ -4,7 +4,7 @@ class ResultAsset < ActiveRecord::Base
belongs_to :result, inverse_of: :result_asset
belongs_to :asset, inverse_of: :result_asset, dependent: :destroy
def space_taken
asset.present? ? asset.estimated_size : 0
end
def space_taken
asset.present? ? asset.estimated_size : 0
end
end

View file

@ -3,6 +3,5 @@ class ResultComment < ActiveRecord::Base
validates :result_id, uniqueness: { scope: :comment_id }
belongs_to :result, inverse_of: :result_comments
belongs_to :comment,
inverse_of: :result_comment
belongs_to :comment, inverse_of: :result_comment
end

View file

@ -2,7 +2,5 @@ class ResultTable < ActiveRecord::Base
validates :result, :table, presence: true
belongs_to :result, inverse_of: :result_table
belongs_to :table,
inverse_of: :result_table,
dependent: :destroy
belongs_to :table, inverse_of: :result_table, dependent: :destroy
end

View file

@ -1,7 +1,6 @@
class ResultText < ActiveRecord::Base
validates :text, presence: true
validates :text, presence: true, length: { maximum: TEXT_MAX_LENGTH }
validates :result, presence: true
belongs_to :result, inverse_of: :result_text
end

View file

@ -1,9 +1,7 @@
class Sample < ActiveRecord::Base
include SearchableModel
validates :name,
presence: true,
length: { maximum: 50 }
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :user, :organization, presence: true
belongs_to :user, inverse_of: :samples

View file

@ -1,7 +1,5 @@
class SampleCustomField < ActiveRecord::Base
validates :value,
presence: true,
length: { maximum: 100 }
validates :value, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :custom_field, :sample, presence: true
belongs_to :custom_field, inverse_of: :sample_custom_fields

View file

@ -1,10 +1,6 @@
class SampleGroup < ActiveRecord::Base
validates :name,
presence: true,
length: { maximum: 50 }
validates :color,
presence: true,
length: { maximum: 7 }
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :color, presence: true, length: { maximum: COLOR_MAX_LENGTH }
validates :organization, presence: true
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'

View file

@ -1,7 +1,5 @@
class SampleType < ActiveRecord::Base
validates :name,
presence: true,
length: { maximum: 50 }
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :organization, presence: true
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'

View file

@ -1,10 +1,8 @@
class Step < ActiveRecord::Base
include SearchableModel
validates :name, presence: true,
length: { maximum: 255 }
validates :description,
length: { maximum: 4000}
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :description, length: { maximum: TEXT_MAX_LENGTH }
validates :position, presence: true
validates :completed, inclusion: { in: [true, false] }
validates :user, :protocol, presence: true

View file

@ -1,8 +1,8 @@
class Table < ActiveRecord::Base
include SearchableModel
validates :contents,
presence: true,
length: { maximum: 20971520 }
presence: true,
length: { maximum: TABLE_JSON_MAX_SIZE.megabytes }
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User'

View file

@ -1,10 +1,8 @@
class Tag < ActiveRecord::Base
include SearchableModel
validates :name,
presence: true,
length: { maximum: 50 }
validates :color, presence: true
validates :name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :color, presence: true, length: { maximum: COLOR_MAX_LENGTH }
validates :project, presence: true
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'

View file

@ -16,11 +16,13 @@ class User < ActiveRecord::Base
intro_tutorial_done: 1
}
validates :full_name, presence: true, length: { maximum: 50 }
validates :initials, presence: true, length: { minimum: 1, maximum: 4 }
validates :full_name, presence: true, length: { maximum: NAME_MAX_LENGTH }
validates :initials,
presence: true,
length: { maximum: USER_INITIALS_MAX_LENGTH }
validates_attachment :avatar,
:content_type => { :content_type => ["image/jpeg", "image/png"] },
:size => { :less_than => 200.kilobytes }
size: { less_than: AVATAR_MAX_SIZE.megabytes }
validates :time_zone, presence: true
validate :time_zone_check

View file

@ -19,7 +19,7 @@
<li>
<hr>
<%= bootstrap_form_for :comment, url: { format: :json }, method: :post, remote: true do |f| %>
<%= f.text_field :message, hide_label: true, placeholder: t("general.comment_placeholder"), append: f.submit("+"), help: '.' %>
<%= f.text_field :message, hide_label: true, placeholder: t("general.comment_placeholder"), append: f.submit("+", onclick: "processResult(event, ResultTypeEnum.COMMENT, false);"), help: '.' %>
<% end %>
</li>
</ul>

View file

@ -21,11 +21,21 @@ TAG_COLORS = [
"#000000"
]
# Maximum uploaded file size in MB
FILE_SIZE_LIMIT = 50
# Min/max characters for short text fields
NAME_MIN_LENGTH = 2
NAME_MAX_LENGTH = 255
# Max characters for long text fields
TEXT_MAX_LENGTH = 10000
# Max characters for color field (given in HEX format)
COLOR_MAX_LENGTH = 7
USER_INITIALS_MAX_LENGTH = 4
# Maximum uploaded avatar size in MB
AVATAR_SIZE_LIMIT = 0.2
# Max table JSON size in MB
TABLE_JSON_MAX_SIZE = 20
# Max uploaded file size in MB
FILE_MAX_SIZE = 50
# Max uploaded user avatar size in MB
AVATAR_MAX_SIZE = 0.2
SEARCH_LIMIT = 20

View file

@ -1523,6 +1523,7 @@ en:
text:
not_blank: "can't be blank"
length_too_long: "is too long (maximum is %{max_length} characters)"
length_too_short: "is too short (minimum is %{min_length} characters)"
busy: "The server is still processing your request. If you leave this page, the changes will be lost! Are you sure you want to continue?"
Add: "Add"