Skip to content

Commit

Permalink
More work on model tests. Finished AnalysisJobs, AnalysisItems, and T…
Browse files Browse the repository at this point in the history
…ags today.

Also fixed errors in  seeds (to update with new validations).

Also fixed #83. Closes #83.

modified:   Gemfile.lock

modified:   app/assets/javascripts/angular/controllers/projects.js
modified:   app/assets/javascripts/angular/controllers/recordings.js
modified:   app/assets/javascripts/angular/controllers/search.js
modified:   app/assets/javascripts/angular/controllers/tags.js
modified:   app/assets/javascripts/angular/services/services.js
modified:   app/assets/javascripts/app.js
	-- wrapped all di methods in array syntax for production build

modified:   config/application.rb
	-- added setting for prod build for assets compilation (skips init step, so cap deploy works)

modified:   db/development_seeds.rb
	-- updated to match validation

modified:   app/models/analysis_item.rb
modified:   app/models/analysis_job.rb
modified:   app/models/analysis_script.rb
modified:   app/models/saved_search.rb
modified:   app/models/tag.rb
modified:   spec/factories/analysis_item_factory.rb
new file:   spec/factories/saved_search_factory.rb
new file:   spec/factories/tag_factory.rb
renamed:    spec/models/analysis_job_spec.rb -> spec/models/analysis_item_spec.rb
modified:   spec/models/analysis_job_spec.rb
modified:   spec/models/analysis_script_spec.rb
renamed:    spec/models/module_audio_spec.rb -> spec/models/module_audio_test.rb
modified:   spec/models/tag_spec.rb
  • Loading branch information
atruskie committed Jan 16, 2013
1 parent da8cf86 commit 6ce7c1f
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 56 deletions.
2 changes: 1 addition & 1 deletion app/assets/javascripts/angular/controllers/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,5 @@ function ProjectCtrl($scope, $location, $resource, $routeParams, Project, Site,
$scope.allSites = Site.query();
}

ProjectCtrl.$inject = ['$scope', '$location', '$resource', '$routeParams', 'Project', 'Site'];
ProjectCtrl.$inject = ['$scope', '$location', '$resource', '$routeParams', 'Project', 'Site', 'Photo'];

2 changes: 1 addition & 1 deletion app/assets/javascripts/angular/controllers/recordings.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ function RecordingCtrl($scope, $resource) {
$scope.recording = recordingResource.get({recordingId:1});
}

RecordingCtrl.$inject = ['$scope', '$resource']
RecordingCtrl.$inject = ['$scope', '$resource'];
4 changes: 2 additions & 2 deletions app/assets/javascripts/angular/controllers/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function SearchesCtrl($scope, $resource, Search) {
// $scope.sites = $scope.sitesResource.get();
}

SearchesCtrl.$inject = ['$scope', '$resource'];
SearchesCtrl.$inject = ['$scope', '$resource', 'Search'];


function SearchCtrl($scope, $resource, Search) {
Expand Down Expand Up @@ -34,4 +34,4 @@ function SearchCtrl($scope, $resource, Search) {

}

SearchCtrl.$inject = ['$scope', '$resource'];
SearchCtrl.$inject = ['$scope', '$resource', 'Search'];
4 changes: 2 additions & 2 deletions app/assets/javascripts/angular/controllers/tags.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

function TagsCtrl($scope, $resource, Tag) {
function TagsCtrl($scope, $resource, $routeParams, Tag) {
$scope.tagsResource = $resource('/tags', {});
$scope.tags = $scope.tagsResource.query();

Expand All @@ -20,7 +20,7 @@ TagsCtrl.linkList = function (id) {
};
};

TagsCtrl.$inject = ['$scope', '$resource', 'Tag'];
TagsCtrl.$inject = ['$scope', '$resource', '$routeParams', 'Tag'];

function TagCtrl($scope, $resource, $routeParams, Tag) {

Expand Down
28 changes: 14 additions & 14 deletions app/assets/javascripts/angular/services/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,37 @@
/**
*
*/
bawss.factory('Project', function ($resource) {
bawss.factory('Project', [ '$resource', function ($resource) {
return resourcePut($resource, '/projects/:projectId', {projectId: "@projectId"});
});
}]);

bawss.factory('Site', function ($resource) {
bawss.factory('Site', [ '$resource', function ($resource) {
return resourcePut($resource, '/sites/:siteId', {siteId: "@siteId"});
});
}]);

bawss.factory('Photo', function ($resource) {
bawss.factory('Photo', [ '$resource', function ($resource) {
return resourcePut($resource, '/photos/:photoId', {photoId: "@photoId"});
});
}]);

bawss.factory('AudioRecording', function ($resource) {
bawss.factory('AudioRecording', [ '$resource', function ($resource) {
return resourcePut($resource, '/audio_recordings/:recordingId', {recordingId: '@recordingId'});
});
}]);;

bawss.factory('AudioEvent', function ($resource) {
bawss.factory('AudioEvent', [ '$resource', function ($resource) {
var actions = {
query: { method: 'GET', isArray: true }
};

var resource = resourcePut($resource, '/audio_events/:audioEventId', {audioEventId: '@audioEventId'}, actions);
resource.csvLink = "/audio_events/download.csv";
return resource;
});
}]);

bawss.factory('Tag', function ($resource) {
bawss.factory('Tag', [ '$resource', function ($resource) {
return $resource('/tags/:tagId', {tagId: '@tagId'}, {});
});
}]);

bawss.factory('Media', function ($resource) {
bawss.factory('Media', [ '$resource', function ($resource) {
var mediaResource = $resource('/media/:recordingId', {recordingId: '@recordingId'});

// this is a read only service, remove unnecessary methods
Expand All @@ -59,7 +59,7 @@
//delete mediaResource.update;

return mediaResource;
});
}]);

// authentication
bawss.factory('Authenticator', ['$rootScope', 'authService', '$http', function ($rootScope, authService, $http) {
Expand Down
1 change: 0 additions & 1 deletion app/assets/javascripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ var bawApp = (function (undefined) {
* @param id
* @param controllerMany
* @param controllerOne
* @param addManageView
* @return {*|Object}
*/
function whenDefaults(resourceName, singularResourceName, id, controllerMany, controllerOne) {
Expand Down
20 changes: 16 additions & 4 deletions app/models/analysis_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ class AnalysisItem < ActiveRecord::Base
accepts_nested_attributes_for :analysis_job, :audio_recording

# validations
validates :offset_start_seconds, presence: true, numericality: true
validates :offset_end_seconds, presence: true, numericality: true
validates :offset_start_seconds, presence: true, numericality: {greater_than_or_equal_to: 0}
validates :offset_end_seconds, presence: true, numericality: {greater_than_or_equal_to: 0}
validate :start_must_be_lte_end

validates :audio_recording_id, presence: true

# documentation for timeliness: https://github.com/adzap/validates_timeliness
validates :worker_started_utc, timeliness: {type: :datetime, allow_blank: true}
validates :status, inclusion: {in: %w(ready running complete error)}
validates :worker_started_utc, allow_nil: true, allow_blank: true, timeliness: {type: :datetime, on_or_before: :now}
validates :status, inclusion: {in: [:ready, :running, :complete, :error]}, presence: true

# custom validation methods
def start_must_be_lte_end
return unless offset_end_seconds && offset_start_seconds

if offset_start_seconds > offset_end_seconds then
errors.add(:offset_start_seconds, "must be lower than end time")
end
end
end
12 changes: 8 additions & 4 deletions app/models/analysis_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class AnalysisJob < ActiveRecord::Base

# attr
attr_accessible :description, :name, :notes, :process_new,
# a generated identifier from an ?executed? saved search
# a generated identifier from an ?executed? saved search - this might be a file name
:data_set_identifier,

# this is a copy of the information from the analysis_scripts table
Expand All @@ -21,19 +21,23 @@ class AnalysisJob < ActiveRecord::Base

# userstamp
stampable
belongs_to :user, :class_name => 'User', :foreign_key => :creator_id
belongs_to :user, class_name: 'User', foreign_key: :creator_id

# validations
validates :name, :presence => true, :length => { :minimum => 2, :maximum => 100 }, :uniqueness => { :case_sensitive => false }
validates :name, presence: true, length: { minimum: 2, maximum: 255 }, uniqueness: { case_sensitive: false }

validates :script_name, :presence => true
validates :script_settings, :presence => true
validates :script_version, :presence => true
validates :script_display_name, :presence => true
validates :process_new, :inclusion => { :in => [true, false] }

validates :process_new, :inclusion => { :in => [true, false] }, allow_nil: true
validate :data_set_cannot_process_new

# custom validation methods
def data_set_cannot_process_new
return if process_new.nil?

errors.add(:level, 'An analysis job that references a data set cannot process new recordings.') if self.data_set_identifier && self.process_new
end
end
46 changes: 23 additions & 23 deletions app/models/analysis_script.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
class AnalysisScript < ActiveRecord::Base
before_validation :populate_name
after_initialize :init
after_initialize :after_init

Whitelist_characters = "a-zA-Z0-9_\\-\\."
Negative_whitelist = /[^#{Whitelist_characters}]/
White_listed_filename = /^[#{Whitelist_characters}]+$/
White_listed_filepath = /^([\\\/]?[#{Whitelist_characters}]+)?([\\\/][#{Whitelist_characters}]+)+$/
WHITELIST_CHARACTERS = "a-zA-Z0-9_\\-\\."
NEGATIVE_WHITELIST = /[^#{WHITELIST_CHARACTERS}]/
WHITE_LISTED_FILENAME = /^[#{WHITELIST_CHARACTERS}]+$/
WHITE_LISTED_FILEPATH = /^([\\\/]?[#{WHITELIST_CHARACTERS}]+)?([\\\/][#{WHITELIST_CHARACTERS}]+)+$/

def initialize
def initialize(attributes = nil, options = {})
@name_unforced = true
super()
super(attributes, options)
end


# flex store
store :notes

# attr
attr_accessible :display_name, # the original name given by the user to name the script,
# e.g.: "My awesome/brilliant analysis!!"
:name, # a filesystem safe version of display_name (computed)
# Note, this should not be a path
# e.g.: "my_awesome_brilliant_analysis__"
:extra_data, # a manually entered settings file, copied to script dir on execution
:settings, # a file-path to a settings file
# attr
attr_accessible :display_name, # the original name given by the user to name the script,
# e.g.: "My awesome/brilliant analysis!!"
:name, # a filesystem safe version of display_name (computed)
# Note, this should not be a path
# e.g.: "my_awesome_brilliant_analysis__"
:extra_data, # a manually entered settings file, copied to script dir on execution
:settings, # a file-path to a settings file

:description,
:notes,

:version, # an incrementing field tracking changes
:verified # whether or not this script has been checked (security purposes)
# TODO: THIS FIELD SHOULD BE RESTRICTED
:version, # an incrementing field tracking changes
:verified # whether or not this script has been checked (security purposes)
# TODO: THIS FIELD SHOULD BE RESTRICTED

# userstamp
# userstamp
stampable
belongs_to :user, :class_name => 'User', :foreign_key => :creator_id
acts_as_paranoid
Expand All @@ -41,19 +41,19 @@ def initialize
# validations
validates :name, presence: true, length: { minimum: 2, maximum: 255 },
uniqueness: { case_sensitive: false }
validates_format_of :name, :with => White_listed_filename
validates_format_of :name, :with => WHITE_LISTED_FILENAME

validates :display_name, presence: true, length: { minimum: 2, maximum: 255 }

validates :settings, allow_nil: true, format: White_listed_filepath
validates :settings, allow_nil: true, format: WHITE_LISTED_FILEPATH

validates :version, presence: true
validates :verified, inclusion: { in: [true, false] }


# methods

def init
def after_init
@name_unforced = true if @name_unforced.nil?
end

Expand Down Expand Up @@ -90,7 +90,7 @@ def make_safe_name(old)
return old if old.blank?
old = old.dup

old = old.gsub(Negative_whitelist, '_')
old = old.gsub(NEGATIVE_WHITELIST, '_')

old = old.downcase

Expand Down
4 changes: 3 additions & 1 deletion app/models/saved_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ class SavedSearch < ActiveRecord::Base
has_many :progresses

# attr
attr_accessible :name, :search_object
attr_accessible :name,
:search_object # a string (text type) based representation of a saved search
# the format is json

# userstamp
stampable
Expand Down
16 changes: 13 additions & 3 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,21 @@ class Tag < ActiveRecord::Base
validates_as_paranoid

# enums
enumerize :type_of_tag, :in => [:common_name, :species_name, :looks_like, :sounds_like], predicates: true
enumerize :type_of_tag, in: [:common_name, :species_name, :looks_like, :sounds_like], predicates: true

# validation
validates :is_taxanomic, :inclusion => { :in => [true, false] }
validates :text, :uniqueness => { :case_sensitive => false }
validates :is_taxanomic, inclusion: { in: [true, false] }
validates :text, uniqueness: { case_sensitive: false }
validates :type_of_tag, :presence => true

validate :no_nils

# custom validation methods
def no_nils
if text.nil? then
errors.add(:text, "text must not be nil")
end
end
#validate :class_mutually_exclusive_with_tag_type

# custom validation
Expand Down

0 comments on commit 6ce7c1f

Please sign in to comment.