esp_sdk 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +36 -35
- data/.travis.yml +2 -1
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +63 -85
- data/Rakefile +2 -1
- data/esp_sdk.gemspec +3 -4
- data/lib/esp/aws_clients.rb +2 -2
- data/lib/esp/commands/add_external_account.rb +1 -1
- data/lib/esp/commands/commands_tasks.rb +2 -2
- data/lib/esp/extensions/active_resource/formats/json_api_format.rb +24 -16
- data/lib/esp/extensions/active_resource/validations.rb +1 -1
- data/lib/esp/resources/alert.rb +3 -2
- data/lib/esp/resources/custom_signature/definition.rb +2 -2
- data/lib/esp/resources/dashboard.rb +2 -5
- data/lib/esp/resources/resource.rb +14 -15
- data/lib/esp/resources/stat.rb +2 -5
- data/lib/esp/resources/suppression.rb +1 -1
- data/lib/esp/version.rb +1 -1
- data/test/esp/integration/custom_signature_definition_integration_test.rb +15 -1
- data/test/esp/integration/custom_signature_integration_test.rb +3 -1
- data/test/esp/integration/custom_signature_result_alert_integration_test.rb +4 -4
- data/test/esp/integration/custom_signature_result_integration_test.rb +2 -1
- data/test/esp/integration/json_api_format_integration_test.rb +1 -1
- data/test/esp/integration/suppression_integration_test.rb +1 -1
- data/test/esp/integration/suppression_unique_identifier_integration_test.rb +1 -1
- data/test/esp/resources/custom_signature/definition_test.rb +1 -1
- data/test/esp/resources/custom_signature_test.rb +1 -1
- data/test/esp/resources/external_account_test.rb +1 -1
- data/test/esp/resources/organization_test.rb +6 -6
- data/test/esp/resources/service_test.rb +1 -1
- data/test/esp/resources/sub_organization_test.rb +3 -3
- data/test/esp/resources/team_test.rb +2 -2
- data/test/factories/contact_requests.rb +1 -2
- data/test/factories/custom_signature/definitions.rb +1 -2
- data/test/factories/dashboards.rb +1 -2
- data/test/factories/external_accounts.rb +1 -2
- data/test/factories/organizations.rb +1 -2
- data/test/factories/reports.rb +1 -2
- data/test/factories/scan_intervals.rb +1 -2
- data/test/factories/stat_custom_signatures.rb +1 -2
- data/test/factories/stat_regions.rb +1 -2
- data/test/factories/stat_services.rb +1 -2
- data/test/factories/stat_signautures.rb +1 -2
- data/test/factories/stats.rb +1 -2
- data/test/factories/sub_organizations.rb +1 -2
- data/test/factories/suppression/regions.rb +2 -4
- data/test/factories/suppression/signatures.rb +2 -4
- data/test/factories/suppression/unique_identifiers.rb +2 -4
- data/test/factories/suppressions.rb +1 -2
- data/test/factories/users.rb +1 -2
- data/test/test_helper.rb +3 -10
- metadata +11 -28
- data/lib/tasks/testing.rake +0 -3
- data/test/parallel_reporter.rb +0 -93
    
        data/Rakefile
    CHANGED
    
    | @@ -1,12 +1,13 @@ | |
| 1 1 | 
             
            require 'bundler/gem_tasks'
         | 
| 2 2 | 
             
            require 'rake/testtask'
         | 
| 3 3 | 
             
            load 'lib/tasks/rubocop.rake'
         | 
| 4 | 
            -
            load 'lib/tasks/testing.rake'
         | 
| 5 4 | 
             
            require 'rdoc/task'
         | 
| 6 5 |  | 
| 7 6 | 
             
            Rake::TestTask.new do |task|
         | 
| 8 7 | 
             
              task.libs << 'test'
         | 
| 9 8 | 
             
              task.test_files = FileList['test/*_test.rb', 'test/**/*_test.rb'] - FileList["test/esp/integration/**/*_test.rb"]
         | 
| 9 | 
            +
              task.verbose    = false
         | 
| 10 | 
            +
              task.warning    = false
         | 
| 10 11 | 
             
            end
         | 
| 11 12 |  | 
| 12 13 | 
             
            namespace "test" do
         | 
    
        data/esp_sdk.gemspec
    CHANGED
    
    | @@ -3,7 +3,7 @@ lib = File.expand_path('../lib', __FILE__) | |
| 3 3 | 
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 4 | 
             
            require 'esp/version'
         | 
| 5 5 |  | 
| 6 | 
            -
            Gem::Specification.new do |spec|
         | 
| 6 | 
            +
            Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
         | 
| 7 7 | 
             
              spec.name          = 'esp_sdk'
         | 
| 8 8 | 
             
              spec.version       = ESP::VERSION
         | 
| 9 9 | 
             
              spec.authors       = ['Evident.io']
         | 
| @@ -26,19 +26,18 @@ Gem::Specification.new do |spec| | |
| 26 26 | 
             
              spec.add_development_dependency 'guard-minitest'
         | 
| 27 27 | 
             
              spec.add_development_dependency 'guard-rubocop'
         | 
| 28 28 | 
             
              spec.add_development_dependency 'minitest'
         | 
| 29 | 
            -
              spec.add_development_dependency 'minitest-reporters'
         | 
| 30 29 | 
             
              spec.add_development_dependency 'shoulda'
         | 
| 31 30 | 
             
              spec.add_development_dependency 'mocha'
         | 
| 32 31 | 
             
              spec.add_development_dependency 'bourne'
         | 
| 33 32 | 
             
              spec.add_development_dependency 'webmock'
         | 
| 34 | 
            -
              spec.add_development_dependency 'coveralls'
         | 
| 35 33 | 
             
              spec.add_development_dependency 'factory_girl'
         | 
| 36 34 | 
             
              spec.add_development_dependency 'yard'
         | 
| 37 35 | 
             
              spec.add_development_dependency 'awesome_print'
         | 
| 38 36 | 
             
              spec.add_development_dependency 'aws-sdk'
         | 
| 39 37 | 
             
              spec.add_development_dependency 'rdiscount'
         | 
| 38 | 
            +
              spec.add_development_dependency 'bundler-audit'
         | 
| 40 39 |  | 
| 41 40 | 
             
              spec.add_dependency 'activeresource', '~> 4.0.0'
         | 
| 42 | 
            -
              spec.add_dependency 'api-auth', '~> 2.0 | 
| 41 | 
            +
              spec.add_dependency 'api-auth', '~> 2.0'
         | 
| 43 42 | 
             
              spec.add_dependency 'rack'
         | 
| 44 43 | 
             
            end
         | 
    
        data/lib/esp/aws_clients.rb
    CHANGED
    
    | @@ -35,8 +35,8 @@ module ESP | |
| 35 35 | 
             
                  ESP_OWNER_ID.fetch(ESP.env, "762160981991")
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            -
                def trust_policy(external_account_id) | 
| 39 | 
            -
                   | 
| 38 | 
            +
                def trust_policy(external_account_id)
         | 
| 39 | 
            +
                  <<-TRUST_POLICY.gsub(/^\s*/, '')
         | 
| 40 40 | 
             
              {
         | 
| 41 41 | 
             
                "Version": "2012-10-17",
         | 
| 42 42 | 
             
                "Statement": [
         | 
| @@ -8,7 +8,7 @@ module ESP | |
| 8 8 | 
             
              class CommandsTasks
         | 
| 9 9 | 
             
                attr_reader :argv
         | 
| 10 10 |  | 
| 11 | 
            -
                HELP_MESSAGE = <<-EOT
         | 
| 11 | 
            +
                HELP_MESSAGE = <<-EOT.freeze
         | 
| 12 12 | 
             
            Usage: esp COMMAND [environment] [ARGS]
         | 
| 13 13 |  | 
| 14 14 | 
             
            The ESP commands are:
         | 
| @@ -18,7 +18,7 @@ The ESP commands are: | |
| 18 18 | 
             
            All commands can be run with -h (or --help) for more information.
         | 
| 19 19 | 
             
                EOT
         | 
| 20 20 |  | 
| 21 | 
            -
                COMMAND_WHITELIST = %w(console add_external_account version help)
         | 
| 21 | 
            +
                COMMAND_WHITELIST = %w(console add_external_account version help).freeze
         | 
| 22 22 |  | 
| 23 23 | 
             
                def initialize(argv)
         | 
| 24 24 | 
             
                  @argv = argv
         | 
| @@ -4,9 +4,9 @@ module ActiveResource | |
| 4 4 | 
             
              # @private
         | 
| 5 5 | 
             
              class ConnectionError
         | 
| 6 6 | 
             
                def initialize(response)
         | 
| 7 | 
            -
                  @response = if response.respond_to?(: | 
| 8 | 
            -
                                message = decoded_errors(response. | 
| 9 | 
            -
                                Struct.new(:body, :code, :message).new(response. | 
| 7 | 
            +
                  @response = if response.respond_to?(:body)
         | 
| 8 | 
            +
                                message = decoded_errors(response.body)
         | 
| 9 | 
            +
                                Struct.new(:body, :code, :message).new(response.body, response.code, message)
         | 
| 10 10 | 
             
                              else
         | 
| 11 11 | 
             
                                response
         | 
| 12 12 | 
             
                              end
         | 
| @@ -15,7 +15,7 @@ module ActiveResource | |
| 15 15 | 
             
                private
         | 
| 16 16 |  | 
| 17 17 | 
             
                def decoded_errors(json)
         | 
| 18 | 
            -
                  Array( | 
| 18 | 
            +
                  Array(Hash(ActiveSupport::JSON.decode(json))['errors'].map { |e| e['title'] }).join(" ")
         | 
| 19 19 | 
             
                rescue
         | 
| 20 20 | 
             
                  []
         | 
| 21 21 | 
             
                end
         | 
| @@ -43,9 +43,7 @@ module ActiveResource | |
| 43 43 | 
             
                    Formats.remove_root(parse_json_api(ActiveSupport::JSON.decode(json)))
         | 
| 44 44 | 
             
                  end
         | 
| 45 45 |  | 
| 46 | 
            -
                   | 
| 47 | 
            -
             | 
| 48 | 
            -
                  def self.parse_json_api(elements)
         | 
| 46 | 
            +
                  def parse_json_api(elements)
         | 
| 49 47 | 
             
                    included = elements.delete('included')
         | 
| 50 48 | 
             
                    elements.tap do |e|
         | 
| 51 49 | 
             
                      Array.wrap(e.fetch('data', {})).each do |object|
         | 
| @@ -53,16 +51,18 @@ module ActiveResource | |
| 53 51 | 
             
                      end
         | 
| 54 52 | 
             
                    end
         | 
| 55 53 | 
             
                  end
         | 
| 54 | 
            +
                  private_class_method :parse_json_api
         | 
| 56 55 |  | 
| 57 | 
            -
                  def  | 
| 56 | 
            +
                  def parse_object!(object, included = nil)
         | 
| 58 57 | 
             
                    return object unless object.respond_to?(:each)
         | 
| 59 58 | 
             
                    merge_attributes!(object)
         | 
| 60 59 | 
             
                    parse_elements(object)
         | 
| 61 60 | 
             
                    parse_relationships!(object, included)
         | 
| 62 61 | 
             
                    object
         | 
| 63 62 | 
             
                  end
         | 
| 63 | 
            +
                  private_class_method :parse_object!
         | 
| 64 64 |  | 
| 65 | 
            -
                  def  | 
| 65 | 
            +
                  def parse_elements(object)
         | 
| 66 66 | 
             
                    object.each_value do |value|
         | 
| 67 67 | 
             
                      if value.is_a? Hash
         | 
| 68 68 | 
             
                        parse_object!(value)
         | 
| @@ -71,20 +71,23 @@ module ActiveResource | |
| 71 71 | 
             
                      end
         | 
| 72 72 | 
             
                    end
         | 
| 73 73 | 
             
                  end
         | 
| 74 | 
            +
                  private_class_method :parse_elements
         | 
| 74 75 |  | 
| 75 | 
            -
                  def  | 
| 76 | 
            +
                  def parse_relationships!(object, included)
         | 
| 76 77 | 
             
                    object.fetch('relationships', {}).each do |assoc, details|
         | 
| 77 78 | 
             
                      extract_foreign_keys!(object, assoc, details)
         | 
| 78 79 | 
             
                      merge_included_objects!(object, assoc, details['data'], included)
         | 
| 79 80 | 
             
                    end
         | 
| 80 81 | 
             
                  end
         | 
| 82 | 
            +
                  private_class_method :parse_relationships!
         | 
| 81 83 |  | 
| 82 | 
            -
                  def  | 
| 84 | 
            +
                  def merge_attributes!(object)
         | 
| 83 85 | 
             
                    return unless object.is_a? Hash
         | 
| 84 86 | 
             
                    object.merge! object.delete('attributes') unless object['attributes'].blank?
         | 
| 85 87 | 
             
                  end
         | 
| 88 | 
            +
                  private_class_method :merge_attributes!
         | 
| 86 89 |  | 
| 87 | 
            -
                  def  | 
| 90 | 
            +
                  def extract_foreign_keys!(object, assoc, assoc_details)
         | 
| 88 91 | 
             
                    data = assoc_details['data']
         | 
| 89 92 | 
             
                    related_link = assoc_details.fetch('links', {}).fetch('related', {})
         | 
| 90 93 | 
             
                    if data.present?
         | 
| @@ -93,16 +96,18 @@ module ActiveResource | |
| 93 96 | 
             
                      parse_related_link(object, assoc, related_link)
         | 
| 94 97 | 
             
                    end
         | 
| 95 98 | 
             
                  end
         | 
| 99 | 
            +
                  private_class_method :extract_foreign_keys!
         | 
| 96 100 |  | 
| 97 | 
            -
                  def  | 
| 101 | 
            +
                  def parse_data(object, assoc, data)
         | 
| 98 102 | 
             
                    if data.is_a? Array
         | 
| 99 103 | 
             
                      object["#{assoc.singularize}_ids"] = data.map { |d| d['id'] }
         | 
| 100 104 | 
             
                    else
         | 
| 101 105 | 
             
                      object["#{assoc}_id"] = data['id']
         | 
| 102 106 | 
             
                    end
         | 
| 103 107 | 
             
                  end
         | 
| 108 | 
            +
                  private_class_method :parse_data
         | 
| 104 109 |  | 
| 105 | 
            -
                  def  | 
| 110 | 
            +
                  def parse_related_link(object, assoc, related_link)
         | 
| 106 111 | 
             
                    # parse the url to get the id if the data node is not returned
         | 
| 107 112 | 
             
                    related_link.scan(%r{/(\d+)\.json$}) do |id|
         | 
| 108 113 | 
             
                      object["#{assoc}_id"] = id.first
         | 
| @@ -111,8 +116,9 @@ module ActiveResource | |
| 111 116 | 
             
                    uri = URI.parse(related_link)
         | 
| 112 117 | 
             
                    object["#{assoc.singularize}_ids"] = Rack::Utils.parse_nested_query(CGI.unescape(uri.query)).fetch('filter', {}).fetch('id_in', []) if uri.query.present?
         | 
| 113 118 | 
             
                  end
         | 
| 119 | 
            +
                  private_class_method :parse_related_link
         | 
| 114 120 |  | 
| 115 | 
            -
                  def  | 
| 121 | 
            +
                  def merge_included_objects!(object, assoc, data, included)
         | 
| 116 122 | 
             
                    return if included.blank?
         | 
| 117 123 | 
             
                    object[assoc] = case data
         | 
| 118 124 | 
             
                                    when Array
         | 
| @@ -121,14 +127,16 @@ module ActiveResource | |
| 121 127 | 
             
                                      merge_nested_included_objects(object, [data], included).first
         | 
| 122 128 | 
             
                                    end
         | 
| 123 129 | 
             
                  end
         | 
| 130 | 
            +
                  private_class_method :merge_included_objects!
         | 
| 124 131 |  | 
| 125 | 
            -
                  def  | 
| 132 | 
            +
                  def merge_nested_included_objects(object, data, included)
         | 
| 126 133 | 
             
                    assocs = included.compact.select { |i| data.include?(i.slice('type', 'id')) }
         | 
| 127 134 | 
             
                    # Remove the object from the included array to prevent an infinite loop if one of it's associations relates back to itself.
         | 
| 128 135 | 
             
                    assoc_included = included.dup
         | 
| 129 136 | 
             
                    assoc_included.delete(object)
         | 
| 130 137 | 
             
                    assocs.map { |i| parse_object!(i, assoc_included) }
         | 
| 131 138 | 
             
                  end
         | 
| 139 | 
            +
                  private_class_method :merge_nested_included_objects
         | 
| 132 140 | 
             
                end
         | 
| 133 141 | 
             
              end
         | 
| 134 142 | 
             
            end
         | 
    
        data/lib/esp/resources/alert.rb
    CHANGED
    
    | @@ -133,12 +133,13 @@ module ESP | |
| 133 133 | 
             
                  suppress(Suppression::UniqueIdentifier, reason)
         | 
| 134 134 | 
             
                end
         | 
| 135 135 |  | 
| 136 | 
            -
                private
         | 
| 137 | 
            -
             | 
| 138 136 | 
             
                # Overridden because alerts does not use ransack for searching
         | 
| 139 137 | 
             
                def self.filters(params)
         | 
| 140 138 | 
             
                  { filter: params }
         | 
| 141 139 | 
             
                end
         | 
| 140 | 
            +
                private_class_method :filters
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                private
         | 
| 142 143 |  | 
| 143 144 | 
             
                def suppress(klass, reason)
         | 
| 144 145 | 
             
                  fail ArgumentError, "You must specify the reason.".freeze unless reason.present?
         | 
| @@ -11,7 +11,7 @@ module ESP | |
| 11 11 | 
             
                    patch(:activate).tap do |response|
         | 
| 12 12 | 
             
                      load_attributes_from_response(response)
         | 
| 13 13 | 
             
                    end
         | 
| 14 | 
            -
                  rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess => error
         | 
| 14 | 
            +
                  rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess, ActiveResource::ForbiddenAccess => error
         | 
| 15 15 | 
             
                    load_remote_errors(error, true)
         | 
| 16 16 | 
             
                    self.code = error.response.code
         | 
| 17 17 | 
             
                    false
         | 
| @@ -22,7 +22,7 @@ module ESP | |
| 22 22 | 
             
                    patch(:archive).tap do |response|
         | 
| 23 23 | 
             
                      load_attributes_from_response(response)
         | 
| 24 24 | 
             
                    end
         | 
| 25 | 
            -
                  rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess => error
         | 
| 25 | 
            +
                  rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess, ActiveResource::ForbiddenAccess => error
         | 
| 26 26 | 
             
                    load_remote_errors(error, true)
         | 
| 27 27 | 
             
                    self.code = error.response.code
         | 
| 28 28 | 
             
                    false
         | 
| @@ -16,11 +16,8 @@ module ESP | |
| 16 16 | 
             
                # @return [void]
         | 
| 17 17 | 
             
                def self.where(attrs)
         | 
| 18 18 | 
             
                  # when calling `recent.next_page` it will come into here
         | 
| 19 | 
            -
                  if attrs[:from].to_s.include?('recent')
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  else
         | 
| 22 | 
            -
                    fail ESP::NotImplementedError, 'Regular ARELlike methods are disabled.  Use the .recent method.'
         | 
| 23 | 
            -
                  end
         | 
| 19 | 
            +
                  return super if attrs[:from].to_s.include?('recent')
         | 
| 20 | 
            +
                  fail ESP::NotImplementedError, 'Regular ARELlike methods are disabled.  Use the .recent method.'
         | 
| 24 21 | 
             
                end
         | 
| 25 22 |  | 
| 26 23 | 
             
                # Not Implemented. You cannot create or update a Dashboard.
         | 
| @@ -1,30 +1,30 @@ | |
| 1 1 | 
             
            module ESP
         | 
| 2 2 | 
             
              # @private
         | 
| 3 3 | 
             
              class Resource < ActiveResource::Base
         | 
| 4 | 
            -
                self.site | 
| 5 | 
            -
                self.proxy | 
| 4 | 
            +
                self.site   = ESP.site
         | 
| 5 | 
            +
                self.proxy  = ESP.http_proxy
         | 
| 6 6 | 
             
                self.format = ActiveResource::Formats::JsonAPIFormat
         | 
| 7 7 | 
             
                with_api_auth(ESP.access_key_id, ESP.secret_access_key)
         | 
| 8 8 | 
             
                headers["Content-Type"] = format.mime_type
         | 
| 9 | 
            -
                headers["User-Agent"] | 
| 9 | 
            +
                headers["User-Agent"]   = "Ruby SDK #{ESP::VERSION}"
         | 
| 10 10 |  | 
| 11 11 | 
             
                self.collection_parser = ActiveResource::PaginatedCollection
         | 
| 12 12 |  | 
| 13 13 | 
             
                # List of predicates that can be used for searching
         | 
| 14 | 
            -
                PREDICATES | 
| 14 | 
            +
                PREDICATES             = %w(sorts m eq eq_any eq_all not_eq not_eq_any not_eq_all matches matches_any matches_all does_not_match does_not_match_any does_not_match_all lt lt_any lt_all lteq lteq_any lteq_all gt gt_any gt_all gteq gteq_any gteq_all in in_any in_all not_in not_in_any not_in_all cont cont_any cont_all not_cont not_cont_any not_cont_all start start_any start_all not_start not_start_any not_start_all end end_any end_all not_end not_end_any not_end_all true false present blank null not_null).join('|').freeze
         | 
| 15 15 |  | 
| 16 16 | 
             
                # Pass a json api compliant hash to the api.
         | 
| 17 17 | 
             
                def serializable_hash(*)
         | 
| 18 | 
            -
                  h | 
| 19 | 
            -
                  h['data'] | 
| 20 | 
            -
             | 
| 18 | 
            +
                  h               = attributes.extract!('included')
         | 
| 19 | 
            +
                  h['data']       = { 'type'       => self.class.to_s.underscore.sub('esp/', '').pluralize,
         | 
| 20 | 
            +
                                      'attributes' => changed_attributes.except('id', 'type', 'created_at', 'updated_at', 'relationships') }
         | 
| 21 21 | 
             
                  h['data']['id'] = id if id.present?
         | 
| 22 22 | 
             
                  h
         | 
| 23 23 | 
             
                end
         | 
| 24 24 |  | 
| 25 25 | 
             
                def self.where(clauses = {})
         | 
| 26 26 | 
             
                  fail ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
         | 
| 27 | 
            -
                  from | 
| 27 | 
            +
                  from    = clauses.delete(:from) || "#{prefix}#{name.demodulize.pluralize.underscore}"
         | 
| 28 28 | 
             
                  clauses = { params: clauses }.with_indifferent_access
         | 
| 29 29 | 
             
                  arrange_options(clauses)
         | 
| 30 30 | 
             
                  prefix_options, query_options = split_options(clauses)
         | 
| @@ -34,7 +34,7 @@ module ESP | |
| 34 34 | 
             
                end
         | 
| 35 35 |  | 
| 36 36 | 
             
                def self.find(*arguments)
         | 
| 37 | 
            -
                  scope | 
| 37 | 
            +
                  scope   = arguments.slice!(0)
         | 
| 38 38 | 
             
                  options = (arguments.slice!(0) || {}).with_indifferent_access
         | 
| 39 39 | 
             
                  arrange_options(options)
         | 
| 40 40 | 
             
                  super(scope, options).tap do |object|
         | 
| @@ -63,22 +63,21 @@ module ESP | |
| 63 63 | 
             
                  return object unless object.is_a? ActiveResource::PaginatedCollection
         | 
| 64 64 | 
             
                  # Need to set from so paginated collection can use it for page calls.
         | 
| 65 65 | 
             
                  object.tap do |collection|
         | 
| 66 | 
            -
                    collection.from | 
| 66 | 
            +
                    collection.from            = options['from']
         | 
| 67 67 | 
             
                    collection.original_params = options.fetch('params', {})
         | 
| 68 68 | 
             
                  end
         | 
| 69 69 | 
             
                end
         | 
| 70 70 |  | 
| 71 71 | 
             
                def self.arrange_options(options)
         | 
| 72 72 | 
             
                  if options[:params].present?
         | 
| 73 | 
            -
                    page | 
| 73 | 
            +
                    page    = options[:params][:page] ? { page: options[:params].delete(:page) } : {}
         | 
| 74 74 | 
             
                    include = options[:params][:include] ? { include: options[:params].delete(:include) } : {}
         | 
| 75 75 | 
             
                    options[:params].merge!(options[:params].delete(:filter)) if options[:params][:filter]
         | 
| 76 76 | 
             
                    options[:params] = filters(options[:params]).merge!(page).merge!(include)
         | 
| 77 77 | 
             
                  end
         | 
| 78 | 
            -
                   | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
                  end
         | 
| 78 | 
            +
                  return unless options[:include].present?
         | 
| 79 | 
            +
                  options[:params] ||= {}
         | 
| 80 | 
            +
                  options[:params].merge!(options.extract!(:include))
         | 
| 82 81 | 
             
                end
         | 
| 83 82 | 
             
              end
         | 
| 84 83 | 
             
            end
         | 
    
        data/lib/esp/resources/stat.rb
    CHANGED
    
    | @@ -32,11 +32,8 @@ module ESP | |
| 32 32 | 
             
                # @return [void]
         | 
| 33 33 | 
             
                def self.where(attrs)
         | 
| 34 34 | 
             
                  # when calling `latest_for_teams.next_page` it will come into here
         | 
| 35 | 
            -
                  if attrs[:from].to_s.include?('latest_for_teams')
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                  else
         | 
| 38 | 
            -
                    fail ESP::NotImplementedError
         | 
| 39 | 
            -
                  end
         | 
| 35 | 
            +
                  return super if attrs[:from].to_s.include?('latest_for_teams')
         | 
| 36 | 
            +
                  fail ESP::NotImplementedError
         | 
| 40 37 | 
             
                end
         | 
| 41 38 |  | 
| 42 39 | 
             
                # Not Implemented. You cannot search for a Stat.
         | 
| @@ -98,7 +98,7 @@ module ESP | |
| 98 98 | 
             
                  patch(:deactivate).tap do |response|
         | 
| 99 99 | 
             
                    load_attributes_from_response(response)
         | 
| 100 100 | 
             
                  end
         | 
| 101 | 
            -
                rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess => error
         | 
| 101 | 
            +
                rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess, ActiveResource::ForbiddenAccess => error
         | 
| 102 102 | 
             
                  load_remote_errors(error, true)
         | 
| 103 103 | 
             
                  self.code = error.response.code
         | 
| 104 104 | 
             
                  false
         | 
    
        data/lib/esp/version.rb
    CHANGED
    
    
| @@ -53,7 +53,11 @@ module ESP::Integration | |
| 53 53 | 
             
                      should 'activate definition' do
         | 
| 54 54 | 
             
                        custom_signature = ESP::CustomSignature.last
         | 
| 55 55 | 
             
                        fail 'Missing custom signature' if custom_signature.blank?
         | 
| 56 | 
            -
                        definition =  | 
| 56 | 
            +
                        definition = custom_signature.definitions.last
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                        if definition.blank? || definition.status != 'editable'
         | 
| 59 | 
            +
                          definition = ESP::CustomSignature::Definition.create(custom_signature_id: custom_signature.id)
         | 
| 60 | 
            +
                        end
         | 
| 57 61 |  | 
| 58 62 | 
             
                        assert_equal 'editable', definition.status
         | 
| 59 63 |  | 
| @@ -67,6 +71,16 @@ module ESP::Integration | |
| 67 71 | 
             
                      should 'be able to create, update and destroy' do
         | 
| 68 72 | 
             
                        custom_signature = ESP::CustomSignature.last
         | 
| 69 73 | 
             
                        fail 'Missing custom signature' if custom_signature.blank?
         | 
| 74 | 
            +
                        old_definition = custom_signature.definitions.last
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                        if old_definition.present? && old_definition.status == 'editable'
         | 
| 77 | 
            +
                          old_definition.destroy
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                          assert_raises ActiveResource::ResourceNotFound do
         | 
| 80 | 
            +
                            ESP::CustomSignature::Definition.find(old_definition.id)
         | 
| 81 | 
            +
                          end
         | 
| 82 | 
            +
                        end
         | 
| 83 | 
            +
             | 
| 70 84 | 
             
                        definition = ESP::CustomSignature::Definition.new(custom_signature_id: custom_signature.id)
         | 
| 71 85 |  | 
| 72 86 | 
             
                        assert_predicate definition, :new?
         | 
| @@ -36,7 +36,9 @@ module ESP::Integration | |
| 36 36 |  | 
| 37 37 | 
             
                    context '#CRUD' do
         | 
| 38 38 | 
             
                      should 'be able to create, update and destroy' do
         | 
| 39 | 
            -
                         | 
| 39 | 
            +
                        team = ESP::Team.last
         | 
| 40 | 
            +
                        assert_predicate team, :present?
         | 
| 41 | 
            +
                        custom_signature = ESP::CustomSignature.new(@custom_signature.attributes.merge(team_ids: [team.id]))
         | 
| 40 42 |  | 
| 41 43 | 
             
                        assert_predicate custom_signature, :new?
         | 
| 42 44 |  | 
| @@ -6,7 +6,7 @@ module ESP::Integration | |
| 6 6 | 
             
                  context 'live calls' do
         | 
| 7 7 | 
             
                    context '#for_result' do
         | 
| 8 8 | 
             
                      should 'return alerts' do
         | 
| 9 | 
            -
                        result = ESP::CustomSignature::Result.first
         | 
| 9 | 
            +
                        result = ESP::CustomSignature::Result.first(params: { sorts: 'id' })
         | 
| 10 10 | 
             
                        fail 'Missing result' if result.blank?
         | 
| 11 11 |  | 
| 12 12 | 
             
                        alerts = ESP::CustomSignature::Result::Alert.for_result(result.id)
         | 
| @@ -17,7 +17,7 @@ module ESP::Integration | |
| 17 17 |  | 
| 18 18 | 
             
                    context '#custom_signature' do
         | 
| 19 19 | 
             
                      should 'return a custom_signature' do
         | 
| 20 | 
            -
                        result = ESP::CustomSignature::Result.first
         | 
| 20 | 
            +
                        result = ESP::CustomSignature::Result.first(params: { sorts: 'id' })
         | 
| 21 21 | 
             
                        fail 'Missing result' if result.blank?
         | 
| 22 22 | 
             
                        alert = ESP::CustomSignature::Result::Alert.for_result(result.id).first
         | 
| 23 23 |  | 
| @@ -30,7 +30,7 @@ module ESP::Integration | |
| 30 30 |  | 
| 31 31 | 
             
                    context '#external_account' do
         | 
| 32 32 | 
             
                      should 'return a external_account' do
         | 
| 33 | 
            -
                        result = ESP::CustomSignature::Result.first
         | 
| 33 | 
            +
                        result = ESP::CustomSignature::Result.first(params: { sorts: 'id' })
         | 
| 34 34 | 
             
                        fail 'Missing result' if result.blank?
         | 
| 35 35 | 
             
                        alert = ESP::CustomSignature::Result::Alert.for_result(result.id).first
         | 
| 36 36 |  | 
| @@ -43,7 +43,7 @@ module ESP::Integration | |
| 43 43 |  | 
| 44 44 | 
             
                    context '#region' do
         | 
| 45 45 | 
             
                      should 'return a region' do
         | 
| 46 | 
            -
                        result = ESP::CustomSignature::Result.first
         | 
| 46 | 
            +
                        result = ESP::CustomSignature::Result.first(params: { sorts: 'id' })
         | 
| 47 47 | 
             
                        fail 'Missing result' if result.blank?
         | 
| 48 48 | 
             
                        alert = ESP::CustomSignature::Result::Alert.for_result(result.id).first
         | 
| 49 49 |  |