esp_sdk 2.5.0 → 2.6.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +8 -0
  5. data/Gemfile.lock +5 -3
  6. data/Guardfile +3 -1
  7. data/esp_sdk.gemspec +2 -1
  8. data/lib/esp/aws_clients.rb +2 -1
  9. data/lib/esp/commands/commands_tasks.rb +2 -1
  10. data/lib/esp/commands/console.rb +4 -0
  11. data/lib/esp/exceptions.rb +1 -0
  12. data/lib/esp/extensions/active_resource/dirty.rb +51 -0
  13. data/lib/esp/extensions/active_resource/formats/json_api_format.rb +5 -3
  14. data/lib/esp/extensions/active_resource/paginated_collection.rb +71 -38
  15. data/lib/esp/extensions/active_resource/validations.rb +4 -2
  16. data/lib/esp/external_account_creator.rb +4 -1
  17. data/lib/esp/resources/alert.rb +53 -42
  18. data/lib/esp/resources/cloud_trail_event.rb +18 -12
  19. data/lib/esp/resources/concerns/stat_totals.rb +70 -67
  20. data/lib/esp/resources/contact_request.rb +17 -14
  21. data/lib/esp/resources/custom_signature/definition.rb +46 -51
  22. data/lib/esp/resources/custom_signature/result/alert.rb +13 -5
  23. data/lib/esp/resources/custom_signature/result.rb +49 -53
  24. data/lib/esp/resources/custom_signature.rb +52 -61
  25. data/lib/esp/resources/dashboard.rb +11 -5
  26. data/lib/esp/resources/external_account.rb +59 -58
  27. data/lib/esp/resources/metadata.rb +21 -11
  28. data/lib/esp/resources/organization.rb +49 -39
  29. data/lib/esp/resources/region.rb +25 -28
  30. data/lib/esp/resources/report.rb +46 -44
  31. data/lib/esp/resources/reports/export/integration.rb +22 -13
  32. data/lib/esp/resources/resource.rb +4 -3
  33. data/lib/esp/resources/scan_interval.rb +19 -13
  34. data/lib/esp/resources/service.rb +17 -11
  35. data/lib/esp/resources/signature.rb +43 -53
  36. data/lib/esp/resources/stat.rb +72 -55
  37. data/lib/esp/resources/stat_custom_signature.rb +73 -65
  38. data/lib/esp/resources/stat_region.rb +76 -65
  39. data/lib/esp/resources/stat_service.rb +76 -65
  40. data/lib/esp/resources/stat_signature.rb +76 -65
  41. data/lib/esp/resources/sub_organization.rb +51 -60
  42. data/lib/esp/resources/suppression/region.rb +35 -30
  43. data/lib/esp/resources/suppression/signature.rb +35 -29
  44. data/lib/esp/resources/suppression/unique_identifier.rb +27 -22
  45. data/lib/esp/resources/suppression.rb +45 -34
  46. data/lib/esp/resources/tag.rb +20 -11
  47. data/lib/esp/resources/team.rb +56 -58
  48. data/lib/esp/resources/user.rb +35 -32
  49. data/lib/esp/version.rb +1 -1
  50. data/lib/esp.rb +39 -16
  51. data/lib/esp_sdk.rb +1 -0
  52. data/test/esp/extensions/active_resource/dirty_test.rb +81 -0
  53. data/test/esp/extensions/active_resource/formats/json_api_format_test.rb +8 -0
  54. data/test/esp/extensions/active_resource/paginated_collection_test.rb +7 -0
  55. data/test/esp/integration/json_api_format_integration_test.rb +5 -2
  56. data/test/esp/integration/organization_integration_test.rb +1 -1
  57. data/test/esp/resources/custom_signature_test.rb +15 -0
  58. data/test/factories/custom_signatures.rb +0 -10
  59. metadata +21 -3
@@ -1,28 +1,33 @@
1
1
  module ESP
2
2
  class Tag < ESP::Resource
3
3
  # Not Implemented. You cannot create or update a Tag.
4
+ #
5
+ # @return [void]
4
6
  def save
5
7
  fail ESP::NotImplementedError
6
8
  end
7
9
 
8
10
  # Not Implemented. You cannot destroy a Tag.
11
+ #
12
+ # @return [void]
9
13
  def destroy
10
14
  fail ESP::NotImplementedError
11
15
  end
12
16
 
13
17
  # Not Implemented. You cannot search for a Tag.
18
+ #
19
+ # @return [void]
14
20
  def self.where(*)
15
21
  fail ESP::NotImplementedError
16
22
  end
17
23
 
18
24
  # Returns a paginated collection of tags for the given alert_id
19
- # Convenience method to use instead of ::find since an alert_id is required to return tags.
25
+ # Convenience method to use instead of {.find} since an alert_id is required to return tags.
20
26
  #
21
- # ==== Parameter
22
- #
23
- # +alert_id+ | Required | The ID of the alert to list tags for
24
- #
25
- # ==== Example
27
+ # @param alert_id [Integer, Numeric] Required ID of the alert to list tags for.
28
+ # @return [ActiveResource::PaginatedCollection<ESP::Tag>]
29
+ # @raise [ArgumentError] if no +alert_id+ is supplied.
30
+ # @example
26
31
  # alerts = ESP::Tag.for_alert(1194)
27
32
  def self.for_alert(alert_id = nil)
28
33
  fail ArgumentError, "You must supply an alert id." unless alert_id.present?
@@ -32,12 +37,16 @@ module ESP
32
37
 
33
38
  # Find a Tag by id
34
39
  #
35
- # ==== Parameter
36
- #
37
- # +id+ | Required | The ID of the tag to retrieve
40
+ # *call-seq* -> +super.find(id)+
38
41
  #
39
- # :call-seq:
40
- # find(id)
42
+ # @overload find(id)
43
+ # @param id [Integer, Numeric] Required ID of the tag to retrieve.
44
+ # @overload find(scope, options)
45
+ # *call-seq* -> +super.all(options)+
46
+ # @api private
47
+ # @param scope [Object] *Example:* +:all+
48
+ # @param options [Hash] +params: { alert_id: Integer }+
49
+ # @raise [ArgumentError] if no +alert_id+ is supplied.
41
50
  def self.find(*arguments)
42
51
  scope = arguments.slice!(0)
43
52
  options = (arguments.slice!(0) || {}).with_indifferent_access
@@ -1,23 +1,28 @@
1
1
  module ESP
2
2
  class Team < ESP::Resource
3
- ##
4
3
  # The organization this team belongs to.
4
+ #
5
+ # @return [ESP::Organization]
5
6
  belongs_to :organization, class_name: 'ESP::Organization'
6
7
 
7
- ##
8
8
  # The sub organization this team belongs to.
9
+ #
10
+ # @return [ESP::SubOrganization]
9
11
  belongs_to :sub_organization, class_name: 'ESP::SubOrganization'
10
12
 
11
- ##
12
13
  # The collection of external_accounts that belong to the team.
14
+ #
15
+ # @return [ActiveResource::PaginatedCollection<ESP::ExternalAccount>]
13
16
  has_many :external_accounts, class_name: 'ESP::ExternalAccount'
14
17
 
15
- ##
16
18
  # The collection of reports that belong to the team.
19
+ #
20
+ # @return [ActiveResource::PaginatedCollection<ESP::Report>]
17
21
  has_many :reports, class_name: 'ESP::Report'
18
22
 
19
- ##
20
23
  # The collection of custom_signatures that belong to the team.
24
+ #
25
+ # @return [ActiveResource::PaginatedCollection<ESP::CustomSignature>]
21
26
  def custom_signatures
22
27
  CustomSignature.where(teams_id_eq: id)
23
28
  end
@@ -28,82 +33,75 @@ module ESP
28
33
  # ESP::Report.find(<id>)
29
34
  # until status is 'complete'.
30
35
  # If not successful, returns a Report object with the errors object populated.
36
+ #
37
+ # @return [ESP::Report]
31
38
  def create_report
32
39
  Report.create_for_team(id)
33
40
  end
34
41
 
35
- # :singleton-method: where
36
- # Return a paginated Team list filtered by search parameters
37
- #
38
- # ==== Parameters
42
+ # @!method self.where(clauses = {})
43
+ # Return a paginated Team list filtered by search parameters
39
44
  #
40
- # +clauses+ | Hash of attributes with appended predicates to search, sort and include.
45
+ # *call-seq* -> +super.where(clauses = {})+
41
46
  #
42
- # ===== Valid Clauses
47
+ # @param clauses [Hash] A hash of attributes with appended predicates to search, sort and include.
48
+ # ===== Valid Clauses
43
49
  #
44
- # See {API documentation}[http://api-docs.evident.io?ruby#team-attributes] for valid arguments
45
- #
46
- # :call-seq:
47
- # where(clauses = {})
50
+ # See {API documentation}[http://api-docs.evident.io?ruby#team-attributes] for valid arguments
51
+ # @return [ActiveResource::PaginatedCollection<ESP::Team>]
48
52
 
49
- ##
50
- # :singleton-method: find
51
- # Find a Team by id
52
- #
53
- # ==== Parameter
53
+ # @!method self.find(id, options = {})
54
+ # Find a Team by id
54
55
  #
55
- # +id+ | Required | The ID of the team to retrieve
56
+ # *call-seq* -> +super.find(id, options = {})+
56
57
  #
57
- # +options+ | Optional | A hash of options
58
+ # @param id [Integer, Numeric, #to_i] Required ID of the team to retrieve.
59
+ # @param options [Hash] Optional hash of options.
60
+ # ===== Valid Options
58
61
  #
59
- # ===== Valid Options
62
+ # +include+ | The list of associated objects to return on the initial request.
60
63
  #
61
- # +include+ | The list of associated objects to return on the initial request.
64
+ # ===== Valid Includable Associations
62
65
  #
63
- # ===== Valid Includable Associations
64
- #
65
- # See {API documentation}[http://api-docs.evident.io?ruby#team-attributes] for valid arguments
66
- #
67
- # :call-seq:
68
- # find(id, options = {})
69
-
70
- # :singleton-method: all
71
- # Return a paginated Team list
66
+ # See {API documentation}[http://api-docs.evident.io?ruby#team-attributes] for valid arguments
67
+ # @return [ESP::Team]
72
68
 
73
- # :singleton-method: create
74
- # Create a Team.
75
- # :call-seq:
76
- # create(attributes={})
77
- #
78
- # ==== Parameter
79
- #
80
- # +attributes+ | Required | A hash of team attributes
69
+ # @!method self.all
70
+ # Return a paginated Team list
81
71
  #
82
- # ===== Valid Attributes
83
- #
84
- # See {API documentation}[http://api-docs.evident.io?ruby#team-create] for valid arguments
72
+ # @return [ActiveResource::PaginatedCollection<ESP::Team>]
73
+
74
+ # @!method self.create(attributes = {})
75
+ # Create a Team.
76
+ # *call-seq* -> +super.create(attributes={})+
85
77
  #
86
- # ==== Example
78
+ # @param attributes [Hash] Required hash of team attributes.
79
+ # ===== Valid Attributes
87
80
  #
88
- # team = ESP::Team.create(name: "Team Name", sub_organization_id: 9)
81
+ # See {API documentation}[http://api-docs.evident.io?ruby#team-create] for valid arguments
82
+ # @return [ESP::Team]
83
+ # @example
84
+ # team = ESP::Team.create(name: "Team Name", sub_organization_id: 9)
89
85
 
90
- # :method: save
91
- # Create and update a Team.
86
+ # @!method save
87
+ # Create and update a Team.
92
88
  #
93
- # ===== Valid Attributes when updating
89
+ # ===== Valid Attributes when updating
94
90
  #
95
- # +name+ | Required | The new name of the team
91
+ # +name+ | Required | The new name of the team
96
92
  #
97
- # ===== Valid Attributes when creating
93
+ # ===== Valid Attributes when creating
98
94
  #
99
- # See {API documentation}[http://api-docs.evident.io?ruby#team-create] for valid arguments
95
+ # See {API documentation}[http://api-docs.evident.io?ruby#team-create] for valid arguments
100
96
  #
101
- # ==== Example
102
- #
103
- # team = ESP::Team.new(name: "Team Name", sub_organization_id: 9)
104
- # team.save
97
+ # @return [Boolean]
98
+ # @example
99
+ # team = ESP::Team.new(name: "Team Name", sub_organization_id: 9)
100
+ # team.save
105
101
 
106
- # :method: destroy
107
- # Delete a Team.
102
+ # @!method destroy
103
+ # Delete a Team.
104
+ #
105
+ # @return [self]
108
106
  end
109
107
  end
@@ -1,72 +1,75 @@
1
1
  module ESP
2
2
  class User < ESP::Resource
3
- ##
4
3
  # The organization this user belongs to.
4
+ #
5
+ # @return [ESP::Organization]
5
6
  belongs_to :organization, class_name: 'ESP::Organization'
6
7
 
7
8
  # Not Implemented. You cannot create or update a User.
9
+ #
10
+ # @return [void]
8
11
  def save
9
12
  fail ESP::NotImplementedError
10
13
  end
11
14
 
12
15
  # Not Implemented. You cannot destroy a User.
16
+ #
17
+ # @return [void]
13
18
  def destroy
14
19
  fail ESP::NotImplementedError
15
20
  end
16
21
 
17
- ##
18
22
  # The collection of sub organizations that belong to the user.
23
+ #
24
+ # @return [ActiveResource::PaginatedCollection<ESP::SubOrganization>]
19
25
  def sub_organizations
20
26
  return attributes['sub_organizations'] if attributes['sub_organizations'].present?
21
27
  SubOrganization.where(id_in: sub_organization_ids)
22
28
  end
23
29
 
24
- ##
25
30
  # The collection of teams that belong to the user.
31
+ #
32
+ # @return [ActiveResource::PaginatedCollection<ESP::Team>]
26
33
  def teams
27
34
  return attributes['teams'] if attributes['teams'].present?
28
35
  Team.where(id_in: team_ids)
29
36
  end
30
37
 
31
- # :singleton-method: where
32
- # Return a paginated User list filtered by search parameters
33
- #
34
- # ==== Parameters
38
+ # @!method self.where(clauses = {})
39
+ # Return a paginated User list filtered by search parameters
35
40
  #
36
- # +clauses+ | Hash of attributes with appended predicates to search, sort and include.
41
+ # *call-seq* -> +super.where(clauses = {})+
37
42
  #
38
- # ===== Valid Clauses
43
+ # @param clauses [Hash] A hash of attributes with appended predicates to search, sort and include.
44
+ # ===== Valid Clauses
39
45
  #
40
- # See {API documentation}[http://api-docs.evident.io?ruby#user-attributes] for valid arguments
41
- #
42
- # :call-seq:
43
- # where(clauses = {})
46
+ # See {API documentation}[http://api-docs.evident.io?ruby#user-attributes] for valid arguments
47
+ # @return [ActiveResource::PaginatedCollection<ESP::User>]
44
48
 
45
- ##
46
- # :singleton-method: find
47
- # Find a User by id
48
- #
49
- # ==== Parameter
50
- #
51
- # +id+ | Required | The ID of the user to retrieve
49
+ # @!method self.find(id, options = {})
50
+ # Find a User by id
52
51
  #
53
- # +options+ | Optional | A hash of options
52
+ # *call-seq* -> +super.find(id, options = {})+
54
53
  #
55
- # ===== Valid Options
54
+ # @param id [Integer, Numeric, #to_i] Required ID of the user to retrieve.
55
+ # @param options [Hash] Optional hash of options.
56
+ # ===== Valid Options
56
57
  #
57
- # +include+ | The list of associated objects to return on the initial request.
58
+ # +include+ | The list of associated objects to return on the initial request.
58
59
  #
59
- # ===== Valid Includable Associations
60
+ # ===== Valid Includable Associations
60
61
  #
61
- # See {API documentation}[http://api-docs.evident.io?ruby#user-attributes] for valid arguments
62
- #
63
- # :call-seq:
64
- # find(id, options = {})
62
+ # See {API documentation}[http://api-docs.evident.io?ruby#user-attributes] for valid arguments
63
+ # @return [ESP::User]
65
64
 
66
- # :singleton-method: all
67
- # Return a paginated User list
65
+ # @!method self.all
66
+ # Return a paginated User list
67
+ #
68
+ # @return [ActiveResource::PaginatedCollection<ESP::User>]
68
69
 
69
- # :singleton-method: create
70
- # Not Implemented. You cannot create a User.
70
+ # @!method self.create
71
+ # Not Implemented. You cannot create a User.
72
+ #
73
+ # @return [void]
71
74
  end
72
75
  end
data/lib/esp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ESP
2
- VERSION = '2.5.0'.freeze
2
+ VERSION = '2.6.0'.freeze
3
3
  end
data/lib/esp.rb CHANGED
@@ -1,71 +1,92 @@
1
1
  module ESP
2
2
  # Manually set the access_key_id you created from https://esp.evident.io/settings/api_keys.
3
3
  #
4
- # You can optionally set the `ESP_ACCESS_KEY_ID` environment variable.
4
+ # You can optionally set the +ESP_ACCESS_KEY_ID+ environment variable.
5
+ #
6
+ # @param access_key_id [String] Your access key ID.
7
+ # @return [void]
5
8
  def self.access_key_id=(access_key_id)
6
9
  @access_key_id = access_key_id
7
10
  ESP::Resource.hmac_access_id = access_key_id
8
11
  end
9
12
 
10
- # Reads the `ESP_ACCESS_KEY_ID` environment variable if ::access_key_id was not set manually.
13
+ # Reads the +ESP_ACCESS_KEY_ID+ environment variable if {.access_key_id=} was not set manually.
14
+ #
15
+ # Returns nil if no key or environment variable has been set.
16
+ #
17
+ # @return [String, nil]
11
18
  def self.access_key_id
12
19
  @access_key_id || ENV['ESP_ACCESS_KEY_ID']
13
20
  end
14
21
 
15
22
  # Manually set the secret_access_key you created from https://esp.evident.io/settings/api_keys.
16
23
  #
17
- # You can optionally set the `ESP_SECRET_ACCESS_KEY` environment variable.
24
+ # You can optionally set the +ESP_SECRET_ACCESS_KEY+ environment variable.
25
+ #
26
+ # @param secret_access_key [String] Your secret access key.
27
+ # @return [void]
18
28
  def self.secret_access_key=(secret_access_key)
19
29
  @secret_access_key = secret_access_key
20
30
  ESP::Resource.hmac_secret_key = secret_access_key
21
31
  end
22
32
 
23
- # Reads the `ESP_SECRET_ACCESS_KEY` environment variable if ::secret_access_key was not set manually.
33
+ # Reads the +ESP_SECRET_ACCESS_KEY+ environment variable if {.secret_access_key=} was not set manually.
34
+ #
35
+ # Returns nil if no key or environment variable has been set.
36
+ #
37
+ # @return [String, nil]
24
38
  def self.secret_access_key
25
39
  @secret_access_key || ENV['ESP_SECRET_ACCESS_KEY']
26
40
  end
27
41
 
28
42
  PATH = '/api/v2'.freeze
29
43
 
44
+ # @private
30
45
  HOST = { development: "http://localhost:3000".freeze,
31
46
  test: "http://localhost:3000".freeze,
32
- production: "https://api.evident.io".freeze }.freeze # :nodoc:
47
+ production: "https://api.evident.io".freeze }.freeze
33
48
 
34
49
  # Users of the Evident.io marketplace appliance application will need to set the host for their instance.
35
50
  #
36
- # ==== Attribute
37
- #
38
- # * +host+ - The host for the installed appliance instance.
51
+ # @param host [String] The host for the installed appliance instance.
52
+ # @return [void]
39
53
  def self.host=(host)
40
54
  @host = host
41
55
  ESP::Resource.site = site
42
56
  end
43
57
 
44
58
  # The site the SDK will hit.
59
+ #
60
+ # @return [String]
45
61
  def self.site
46
62
  "#{(@host || HOST[ESP.env.to_sym] || ENV['ESP_HOST'])}#{PATH}"
47
63
  end
48
64
 
49
65
  # Manually set an http_proxy
50
66
  #
51
- # You can optionally set the `HTTP_PROXY` environment variable.
52
- #
53
- # ==== Attribute
67
+ # You can optionally set the +HTTP_PROXY+ environment variable.
54
68
  #
55
- # * +http_proxy+ - The URI of the http proxy
69
+ # @param proxy [String] The URI of the http proxy
70
+ # @return [void]
56
71
  def self.http_proxy=(proxy)
57
72
  @http_proxy = proxy
58
73
  ESP::Resource.proxy = http_proxy
59
74
  end
60
75
 
61
- # Reads the `HTTP_PROXY` environment variable if ::http_proxy was not set manually.
76
+ # Reads the +HTTP_PROXY+ environment variable if {.http_proxy=} was not set manually.
77
+ #
78
+ # Returns nil if no proxy or environment variable has been set.
79
+ #
80
+ # @return [String, nil]
62
81
  def self.http_proxy
63
82
  @http_proxy || ENV['http_proxy']
64
83
  end
65
84
 
66
- # For use in a Rails initializer to set the ::access_key_id, ::secret_access_key and ::site.
85
+ # For use in a Rails initializer to set the {.access_key_id=}, {.secret_access_key=} and {.site}.
67
86
  #
68
- # ==== Example
87
+ # @yield [self]
88
+ # @return [void]
89
+ # @example
69
90
  #
70
91
  # ESP.configure do |config|
71
92
  # config.access_key_id = <your key>
@@ -77,7 +98,9 @@ module ESP
77
98
  yield self
78
99
  end
79
100
 
80
- # Default environment is production which will set ::site to "https://api.evident.io/api/v2".
101
+ # Default environment is production which will set {.site} to "https://api.evident.io/api/v2".
102
+ #
103
+ # @return [String]
81
104
  def self.env
82
105
  @env ||= ActiveSupport::StringInquirer.new(ENV['ESP_ENV'] || ENV['RAILS_ENV'] || 'production')
83
106
  end
data/lib/esp_sdk.rb CHANGED
@@ -3,6 +3,7 @@ require 'active_resource'
3
3
  require 'api_auth'
4
4
  require_relative 'esp/extensions/active_resource/paginated_collection'
5
5
  require_relative 'esp/extensions/active_resource/validations'
6
+ require_relative 'esp/extensions/active_resource/dirty'
6
7
  require_relative 'esp/extensions/active_resource/formats/json_api_format'
7
8
  require_relative 'esp/version'
8
9
  require_relative 'esp/exceptions'
@@ -0,0 +1,81 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+
3
+ module ActiveResource
4
+ class DirtyTest < ActiveSupport::TestCase
5
+ context Dirty do
6
+ context 'changed_attributes' do
7
+ context 'for new record' do
8
+ context '#create' do
9
+ should 'pass all attributes to API and reset changed_attributes' do
10
+ stub_request(:post, /custom_signatures.json/).to_return(body: json(:custom_signature, name: 'abc', description: '123'))
11
+ custom_signature = ESP::CustomSignature.create(name: 'abc', description: '123')
12
+
13
+ assert_requested :post, /custom_signatures.json/ do |request|
14
+ json = JSON.parse(request.body)
15
+ json['data']['attributes']['name'] == 'abc' &&
16
+ json['data']['attributes']['description'] == '123'
17
+ end
18
+ assert_equal({}, custom_signature.changed_attributes)
19
+ end
20
+ end
21
+
22
+ context 'save' do
23
+ should 'pass all attributes to API and reset changed_attributes' do
24
+ custom_signature = ESP::CustomSignature.new
25
+ custom_signature.name = 'abc'
26
+ custom_signature.description = '123'
27
+ stub_request(:post, /custom_signatures\.json/).to_return(body: json(:custom_signature, name: 'abc', description: '123'))
28
+
29
+ custom_signature.save
30
+
31
+ assert_requested :post, /custom_signatures.json/ do |request|
32
+ json = JSON.parse(request.body)
33
+ json['data']['attributes']['name'] == 'abc' &&
34
+ json['data']['attributes']['description'] == '123'
35
+ end
36
+ assert_equal({}, custom_signature.changed_attributes)
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'for record from api' do
42
+ context 'save' do
43
+ should 'pass only changed attributes to API and reset changed_attributes' do
44
+ stub_request(:get, %r{custom_signatures/1.json}).to_return(body: json(:custom_signature, name: 'abc', description: '123'))
45
+ custom_signature = ESP::CustomSignature.find(1)
46
+ custom_signature.name = 'def'
47
+ custom_signature.description = '123'
48
+ stub_request(:put, %r{custom_signatures/#{custom_signature.id}.json}).to_return(body: custom_signature.to_json)
49
+
50
+ custom_signature.save
51
+
52
+ assert_requested :put, %r{custom_signatures/#{custom_signature.id}.json} do |request|
53
+ json = JSON.parse(request.body)
54
+ json['data']['attributes']['name'] == 'def' &&
55
+ json['data']['attributes'].exclude?(:description)
56
+ end
57
+ assert_equal({}, custom_signature.changed_attributes)
58
+ end
59
+ end
60
+
61
+ context 'update_attributes' do
62
+ should 'pass only changed attributes to API and reset changed_attributes' do
63
+ stub_request(:get, %r{custom_signatures/1.json}).to_return(body: json(:custom_signature, name: 'abc', description: '123'))
64
+ custom_signature = ESP::CustomSignature.find(1)
65
+ stub_request(:put, %r{custom_signatures/#{custom_signature.id}.json}).to_return(body: custom_signature.to_json)
66
+
67
+ custom_signature.update_attributes(name: 'def', description: '123')
68
+
69
+ assert_requested :put, %r{custom_signatures/#{custom_signature.id}.json} do |request|
70
+ json = JSON.parse(request.body)
71
+ json['data']['attributes']['name'] == 'def' &&
72
+ json['data']['attributes'].exclude?(:description)
73
+ end
74
+ assert_equal({}, custom_signature.changed_attributes)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -49,6 +49,14 @@ module ActiveResource
49
49
  # nested objects too
50
50
  assert_equal parsed_json['included'].detect { |e| e['type'] == 'external_accounts' }['relationships']['organization']['data']['id'], alert.external_account.organization_id
51
51
  end
52
+
53
+ should 'not error with included nulls' do
54
+ manufactured_hash = JSON.parse(json_list(:alert, 1))
55
+ manufactured_hash['included'] << nil
56
+ stub_request(:put, %r{reports/1/alerts.json*}).to_return(body: manufactured_hash.to_json)
57
+
58
+ ESP::Alert.where(report_id: 1).first
59
+ end
52
60
  end
53
61
  end
54
62
  end
@@ -119,6 +119,13 @@ module ActiveResource
119
119
  assert_predicate req.uri.query, :blank? # It will only be called once to get the first page
120
120
  end
121
121
  end
122
+
123
+ should 'not error if no initial params were supplied' do
124
+ stub_request(:get, /reports.json*/).to_return(body: json_list(:report, 3, page: { number: 1, size: 2 }))
125
+ stub_request(:put, /reports.json*/).to_return(body: json_list(:report, 3, page: { number: 2, size: 2 }))
126
+ reports = ESP::Report.all
127
+ reports.next_page
128
+ end
122
129
  end
123
130
 
124
131
  context '#first_page!' do
@@ -11,12 +11,15 @@ module ESP::Integration
11
11
 
12
12
  assert_not_nil alert.attributes['external_account']
13
13
  assert_equal alert.external_account_id, alert.external_account.id
14
- assert_not_nil alert.external_account.attributes['organization']
15
- assert_equal alert.external_account.organization_id, alert.external_account.organization.id
14
+
15
+ assert_nil alert.attributes['team']
16
16
  assert_not_nil alert.external_account.attributes['team']
17
17
  assert_equal alert.external_account.team_id, alert.external_account.team.id
18
+
19
+ assert_nil alert.attributes['organization']
18
20
  assert_not_nil alert.external_account.team.attributes['organization']
19
21
  assert_equal alert.external_account.team.organization_id, alert.external_account.team.organization.id
22
+
20
23
  assert_not_nil alert.attributes['region']
21
24
  assert_equal alert.region_id, alert.region.id
22
25
  if alert.signature.present?
@@ -67,7 +67,7 @@ module ESP::Integration
67
67
 
68
68
  context '#CRUD' do
69
69
  should 'be able to update' do
70
- @organization.name = @organization.name
70
+ @organization.name = "New Name"
71
71
  @organization.save
72
72
 
73
73
  assert_nothing_raised do
@@ -41,6 +41,21 @@ module ESP
41
41
  end
42
42
  end
43
43
 
44
+ context 'save' do
45
+ should 'should not send team_ids param if not changed' do
46
+ stub_request(:get, %r{custom_signatures/1.json}).to_return(body: json(:custom_signature))
47
+ custom_signature = ESP::CustomSignature.find(1)
48
+ stub_request(:put, %r{custom_signatures/#{custom_signature.id}.json})
49
+
50
+ custom_signature.save
51
+
52
+ assert_requested :put, %r{custom_signatures/#{custom_signature.id}.json} do |request|
53
+ json = JSON.parse(request.body)
54
+ json['data']['attributes'].exclude?('team_ids')
55
+ end
56
+ end
57
+ end
58
+
44
59
  context '#suppress' do
45
60
  should 'call the api' do
46
61
  stub_request(:post, %r{suppressions/signatures.json*}).to_return(body: json(:suppression_signature))
@@ -11,25 +11,15 @@ FactoryGirl.define do
11
11
  name "Test"
12
12
  resolution "Test resolution"
13
13
  risk_level "Medium"
14
- signature "Some javascript"
15
- language "javascript"
16
14
  updated_at nil
17
15
  relationships do
18
16
  {
19
17
  organization: {
20
- data: {
21
- type: "organizations",
22
- id: "1003"
23
- },
24
18
  links: {
25
19
  related: "http://test.host/api/v2/organizations/1003.json"
26
20
  }
27
21
  },
28
22
  teams: {
29
- data: {
30
- type: "teams",
31
- id: "1003"
32
- },
33
23
  links: {
34
24
  related: "http://test.host/api/v2/teams?filter%5Bcustom_signatures_id_eq%5D=#{id}"
35
25
  }