esp_sdk 2.6.0 → 2.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee71a8ce107cfd0be1c552e60e32ea3637c21eaa
4
- data.tar.gz: f4087d8db9e1affb4f96a1eceae43ba3211673bf
3
+ metadata.gz: 978cdf444e38c28c557b064ded697801588861b4
4
+ data.tar.gz: 002224323463cc5a0e8bd1a3199e578b35f076ba
5
5
  SHA512:
6
- metadata.gz: b3f490d1f67a732b9b85daf1036d69af6b8295238ce9eb255b41f4fd10172106663e7e3bd7c7f45c7d0c12219b1a34bf68690bd0c12285c1cd25198fcf26aacd
7
- data.tar.gz: 9ece944bf4867f36e4df3457e12c739b15d79dd0ebc729d9b5d2d47955e941b6b3e2042ef88a0fd9eec9fc35d77f052c113342bbbd06c346d1549dfcffb89f93
6
+ metadata.gz: 3cc050b808ce01966cb03aaa4919983c6fcc1126f618e463d9dce523d2d4e52eb7e1e48190b4728cefd13668d1f7eb6b8f9e4d379ffeae11d16775bb81a70f34
7
+ data.tar.gz: 424feda1ed42cc94e87203a9fa662a113ebcce8932209212c0048a738ddf23f7ecb1e03cf962ad758ea62dbbe88959a7785ceacd7b7f9a67f8bd9cf93942df2c
data/CHANGELOG.md CHANGED
@@ -1,13 +1,24 @@
1
1
  ## Unreleased
2
+ ### Added
3
+ - Users create/update/destroy support
4
+ - Role all/find support
5
+
6
+ ### Fixed
7
+ - Fix merge error when calling next_page on Stat.latest_for_teams
8
+ - Fix incorrect page parameter on next_page for other endpoints
2
9
 
3
10
  ## 2.6.0 - 2016-10-17
4
- ### Changed
11
+ ### Added
5
12
  - Only send changed attributes to API #39
6
- - API now returns nested included relation data elements correctly. Change test to reflect corrected response. #40
7
- - Calling `next_page` on queries without parameters (e.g. `ESP::ExternalAccount.all`) no longer errors. #35
8
- - Silently ignore `null` entires if encountered in API responses. #69
13
+
14
+ ### Changed
9
15
  - Switch from RDoc to Yard. #37
10
16
 
17
+ ### Fixed
18
+ - API now returns nested included relation data elements correctly. #40
19
+ - Calling `next_page` on queries without parameters (e.g. `ESP::ExternalAccount.all`) no longer errors. #35
20
+ - Silently ignore `null` entires if encountered in API responses. #36
21
+
11
22
  ## 2.5.0 - 2016-07-20
12
23
  ### Added
13
24
  - Add custom signature definitions and results. Code for a custom signature is now created/updated under a definition. Running a definition for an on demand test creates a result record which will have errors and alerts when completed.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- esp_sdk (2.6.0)
4
+ esp_sdk (2.7.0)
5
5
  activeresource (~> 4.0.0)
6
6
  api-auth (~> 2.0.0)
7
7
  rack
@@ -14,8 +14,13 @@ module ESP
14
14
  # Regular ARELlike methods are disabled.
15
15
  #
16
16
  # @return [void]
17
- def self.where(*)
18
- fail ESP::NotImplementedError, 'Regular ARELlike methods are disabled. Use the .recent method.'
17
+ def self.where(attrs)
18
+ # when calling `recent.next_page` it will come into here
19
+ if attrs[:from].to_s.include?('recent')
20
+ super
21
+ else
22
+ fail ESP::NotImplementedError, 'Regular ARELlike methods are disabled. Use the .recent method.'
23
+ end
19
24
  end
20
25
 
21
26
  # Not Implemented. You cannot create or update a Dashboard.
@@ -38,7 +43,7 @@ module ESP
38
43
  # @return [ESP::Dashboard]
39
44
  def self.recent
40
45
  # call find_every directly since find is overridden/not implemented
41
- find_every from: "#{prefix}dashboard/recent.#{format.extension}"
46
+ where from: "#{prefix}dashboard/recent"
42
47
  end
43
48
  end
44
49
  end
@@ -1,13 +1,13 @@
1
1
  module ESP
2
2
  class Region < ESP::Resource
3
- # Not Implemented. You cannot create or update a CloudTrailEvent.
3
+ # Not Implemented. You cannot create or update a Region.
4
4
  #
5
5
  # @return [void]
6
6
  def save
7
7
  fail ESP::NotImplementedError
8
8
  end
9
9
 
10
- # Not Implemented. You cannot destroy a an CloudTrailEvent.
10
+ # Not Implemented. You cannot destroy a Region.
11
11
  #
12
12
  # @return [void]
13
13
  def destroy
@@ -25,7 +25,7 @@ module ESP
25
25
  def self.where(clauses = {})
26
26
  fail ArgumentError, "expected a clauses Hash, got #{clauses.inspect}" unless clauses.is_a? Hash
27
27
  from = clauses.delete(:from) || "#{prefix}#{name.demodulize.pluralize.underscore}"
28
- clauses = { params: clauses }
28
+ clauses = { params: clauses }.with_indifferent_access
29
29
  arrange_options(clauses)
30
30
  prefix_options, query_options = split_options(clauses)
31
31
  instantiate_collection((format.decode(connection.put("#{from}.json", clauses[:params].to_json).body) || []), query_options, prefix_options).tap do |collection|
@@ -0,0 +1,37 @@
1
+ module ESP
2
+ class Role < ESP::Resource
3
+ # Not Implemented. You cannot create or update a Role.
4
+ #
5
+ # @return [void]
6
+ def save
7
+ fail ESP::NotImplementedError
8
+ end
9
+
10
+ # Not Implemented. You cannot destroy a Role.
11
+ #
12
+ # @return [void]
13
+ def destroy
14
+ fail ESP::NotImplementedError
15
+ end
16
+
17
+ # Not Implemented. You cannot search for a Role.
18
+ #
19
+ # @return [void]
20
+ def self.where(*)
21
+ fail ESP::NotImplementedError
22
+ end
23
+
24
+ # @!method self.find(id)
25
+ # Find a Region by id
26
+ #
27
+ # *call-seq* -> +super.find(id)+
28
+ #
29
+ # @param id [Integer, Numeric, #to_i] Required ID of the region to retrieve.
30
+ # @return [ESP::Region]
31
+
32
+ # @!method self.all
33
+ # Return a paginated list.
34
+ #
35
+ # @return [ActiveResource::PaginatedCollection<ESP::Region>]
36
+ end
37
+ end
@@ -30,8 +30,13 @@ module ESP
30
30
  # Not Implemented. You cannot search for a Stat.
31
31
  #
32
32
  # @return [void]
33
- def self.where(*)
34
- fail ESP::NotImplementedError
33
+ def self.where(attrs)
34
+ # when calling `latest_for_teams.next_page` it will come into here
35
+ if attrs[:from].to_s.include?('latest_for_teams')
36
+ super
37
+ else
38
+ fail ESP::NotImplementedError
39
+ end
35
40
  end
36
41
 
37
42
  # Not Implemented. You cannot search for a Stat.
@@ -82,7 +87,7 @@ module ESP
82
87
  # @return [ActiveResource::PaginatedCollection<ESP::Stat>]
83
88
  def self.latest_for_teams
84
89
  # call find_every directly since find is overriden/not implemented
85
- find_every(from: :latest_for_teams)
90
+ where(from: "#{prefix}stats/latest_for_teams")
86
91
  end
87
92
 
88
93
  # @!group 'total' rollup methods
@@ -5,19 +5,10 @@ module ESP
5
5
  # @return [ESP::Organization]
6
6
  belongs_to :organization, class_name: 'ESP::Organization'
7
7
 
8
- # Not Implemented. You cannot create or update a User.
8
+ # The role assigned to this user.
9
9
  #
10
- # @return [void]
11
- def save
12
- fail ESP::NotImplementedError
13
- end
14
-
15
- # Not Implemented. You cannot destroy a User.
16
- #
17
- # @return [void]
18
- def destroy
19
- fail ESP::NotImplementedError
20
- end
10
+ # @return [ESP::Role]
11
+ belongs_to :role, class_name: 'ESP::Role'
21
12
 
22
13
  # The collection of sub organizations that belong to the user.
23
14
  #
@@ -67,9 +58,33 @@ module ESP
67
58
  #
68
59
  # @return [ActiveResource::PaginatedCollection<ESP::User>]
69
60
 
70
- # @!method self.create
71
- # Not Implemented. You cannot create a User.
61
+ # @!method self.create(attributes = {})
62
+ # Create a User.
63
+ # *call-seq* -> +super.create(attributes={})+
64
+ #
65
+ # @param attributes [Hash] Required hash of user attributes.
66
+ # ===== Valid Attributes
67
+ #
68
+ # See {API documentation}[http://api-docs.evident.io?ruby#user-create] for valid arguments
69
+ # @return [ESP::User]
70
+ # @example
71
+ # user = ESP::User.create(first_name: 'John', last_name: 'Doe', email: "test@email.com")
72
+
73
+ # @!method save
74
+ # Create and update a User.
75
+ #
76
+ # ===== Valid Attributes
77
+ #
78
+ # See {API documentation}[http://api-docs.evident.io?ruby#user-create] for valid arguments
79
+ #
80
+ # @return [Boolean]
81
+ # @example
82
+ # user = ESP::User.new(first_name: 'John', last_name: 'Doe', email: "test@email.com")
83
+ # user.save
84
+
85
+ # @!method destroy
86
+ # Delete a User.
72
87
  #
73
- # @return [void]
88
+ # @return [self]
74
89
  end
75
90
  end
data/lib/esp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ESP
2
- VERSION = '2.6.0'.freeze
2
+ VERSION = '2.7.0'.freeze
3
3
  end
data/lib/esp.rb CHANGED
@@ -124,6 +124,7 @@ module ESP
124
124
  autoload :Metadata, File.expand_path(File.dirname(__FILE__) + '/esp/resources/metadata')
125
125
  autoload :Tag, File.expand_path(File.dirname(__FILE__) + '/esp/resources/tag')
126
126
  autoload :Region, File.expand_path(File.dirname(__FILE__) + '/esp/resources/region')
127
+ autoload :Role, File.expand_path(File.dirname(__FILE__) + '/esp/resources/role')
127
128
  autoload :Suppression, File.expand_path(File.dirname(__FILE__) + '/esp/resources/suppression')
128
129
  autoload :Stat, File.expand_path(File.dirname(__FILE__) + '/esp/resources/stat')
129
130
  autoload :StatCustomSignature, File.expand_path(File.dirname(__FILE__) + '/esp/resources/stat_custom_signature')
@@ -9,7 +9,7 @@ module ActiveResource
9
9
  should 'parse nested objects correctly' do
10
10
  json = json(:dashboard)
11
11
  parsed_json = JSON.parse(json)
12
- stub_request(:get, %r{dashboard/recent.json*}).to_return(body: json_list(:dashboard, 1))
12
+ stub_request(:put, %r{dashboard/recent*}).to_return(body: json_list(:dashboard, 1))
13
13
 
14
14
  dashboard = ESP::Dashboard.recent
15
15
 
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ module ESP::Integration
4
+ class RoleTest < ESP::Integration::TestCase
5
+ context ESP::Role do
6
+ context 'live calls' do
7
+ setup do
8
+ @role = ESP::Role.last
9
+ fail "Live DB does not have any roles. Add a role and run tests again." if @role.blank?
10
+ end
11
+
12
+ context '#CRUD' do
13
+ should 'be able to read' do
14
+ assert_not_nil @role
15
+
16
+ role = ESP::Role.find(@role.id)
17
+
18
+ assert_not_nil role
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -41,6 +41,14 @@ module ESP::Integration
41
41
  end
42
42
  end
43
43
 
44
+ context '#role' do
45
+ should 'return an role' do
46
+ role = @user.role
47
+
48
+ assert_equal @user.role_id, role.id
49
+ end
50
+ end
51
+
44
52
  context '.where' do
45
53
  should 'return user objects' do
46
54
  users = ESP::User.where(id_eq: @user.id)
@@ -48,6 +56,31 @@ module ESP::Integration
48
56
  assert_equal ESP::User, users.resource_class
49
57
  end
50
58
  end
59
+
60
+ context '#CRUD' do
61
+ should 'be able to create, update and destroy' do
62
+ user = ESP::User.new(first_name: 'Bob', last_name: 'Belcher', email: 'burgerboss@gmail.com', organization_id: 1)
63
+
64
+ assert_predicate user, :new?
65
+
66
+ user.save
67
+
68
+ refute_predicate user, :new?
69
+
70
+ user.first_name = 'Gene'
71
+ user.save
72
+
73
+ assert_nothing_raised do
74
+ ESP::User.find(user.id)
75
+ end
76
+
77
+ user.destroy
78
+
79
+ assert_raises ActiveResource::ResourceNotFound do
80
+ ESP::User.find(user.id)
81
+ end
82
+ end
83
+ end
51
84
  end
52
85
  end
53
86
  end
@@ -47,13 +47,26 @@ module ESP
47
47
 
48
48
  context '.recent' do
49
49
  should 'call the api and return an array of dashboard objects' do
50
- stubbed_dashboard = stub_request(:get, %r{dashboard/recent.json*}).to_return(body: json_list(:dashboard, 2))
50
+ stubbed_dashboard = stub_request(:put, %r{dashboard/recent*}).to_return(body: json_list(:dashboard, 2))
51
51
 
52
52
  dashboard = ESP::Dashboard.recent
53
53
 
54
54
  assert_requested(stubbed_dashboard)
55
55
  assert_equal ESP::Dashboard, dashboard.resource_class
56
56
  end
57
+
58
+ context 'next_page' do
59
+ should 'request page 2 when multiple dashboards' do
60
+ stub_dashboard = stub_request(:put, %r{dashboard/recent*}).with(body: {}.to_json).to_return(body: json_list(:dashboard, 25))
61
+ stub_dashboard2 = stub_request(:put, %r{dashboard/recent*}).with(body: { filter: {}, page: { number: '2', size: '20' } }.to_json).to_return(body: json_list(:stat, 2))
62
+
63
+ dashboard = ESP::Dashboard.recent
64
+ dashboard.next_page
65
+
66
+ assert_requested(stub_dashboard)
67
+ assert_requested(stub_dashboard2)
68
+ end
69
+ end
57
70
  end
58
71
  end
59
72
  end
@@ -149,6 +149,17 @@ module ESP
149
149
 
150
150
  assert_equal '/api/v2/teams.json', teams.from
151
151
  end
152
+
153
+ should 'request next_page with page parameters' do
154
+ get_request = stub_request(:get, /teams.json*/).to_return(body: json_list(:team, 25))
155
+ next_page_request = stub_request(:put, /teams.json*/).with(body: { filter: {}, page: { number: '2', size: '20' } }.to_json).to_return(body: json_list(:team, 25))
156
+
157
+ teams = ESP::Team.all
158
+ teams.next_page
159
+
160
+ assert_requested(get_request)
161
+ assert_requested(next_page_request)
162
+ end
152
163
  end
153
164
 
154
165
  context '.where' do
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ module ESP
4
+ class RoleTest < ActiveSupport::TestCase
5
+ context ESP::Role do
6
+ context '#create' do
7
+ should 'not be implemented' do
8
+ assert_raises ESP::NotImplementedError do
9
+ ESP::Role.create(name: 'test')
10
+ end
11
+ end
12
+ end
13
+
14
+ context '#update' do
15
+ should 'not be implemented' do
16
+ role = build(:role)
17
+ assert_raises ESP::NotImplementedError do
18
+ role.save
19
+ end
20
+ end
21
+ end
22
+
23
+ context '#destroy' do
24
+ should 'not be implemented' do
25
+ role = build(:role)
26
+ assert_raises ESP::NotImplementedError do
27
+ role.destroy
28
+ end
29
+ end
30
+ end
31
+
32
+ context '.find' do
33
+ should 'call the show api and return a role if searching by id' do
34
+ stub_role = stub_request(:get, %r{roles/5.json*}).to_return(body: json(:role))
35
+
36
+ role = ESP::Role.find(5)
37
+
38
+ assert_requested(stub_role)
39
+ assert_equal ESP::Role, role.class
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -122,13 +122,26 @@ module ESP
122
122
 
123
123
  context '.latest_for_teams' do
124
124
  should 'call the api and return a collection of stats' do
125
- stub_stat = stub_request(:get, %r{stats/latest_for_teams.json*}).to_return(body: json_list(:stat, 2))
125
+ stub_stat = stub_request(:put, %r{stats/latest_for_teams*}).to_return(body: json_list(:stat, 2))
126
126
 
127
127
  stats = ESP::Stat.latest_for_teams
128
128
 
129
129
  assert_requested(stub_stat)
130
130
  assert_equal ESP::Stat, stats.resource_class
131
131
  end
132
+
133
+ context 'next_page' do
134
+ should 'request page 2 when multiple stats' do
135
+ stub_stat = stub_request(:put, %r{stats/latest_for_teams*}).with(body: {}.to_json).to_return(body: json_list(:stat, 25))
136
+ stub_stat2 = stub_request(:put, %r{stats/latest_for_teams*}).with(body: { filter: {}, page: { number: '2', size: '20' } }.to_json).to_return(body: json_list(:stat, 2))
137
+
138
+ stats = ESP::Stat.latest_for_teams
139
+ stats.next_page
140
+
141
+ assert_requested(stub_stat)
142
+ assert_requested(stub_stat2)
143
+ end
144
+ end
132
145
  end
133
146
  end
134
147
  end
@@ -6,25 +6,25 @@ module ESP
6
6
  context '#create' do
7
7
  should 'not be implemented' do
8
8
  assert_raises ESP::NotImplementedError do
9
- ESP::User.create(name: 'test')
9
+ ESP::Suppression.create(reason: 'test')
10
10
  end
11
11
  end
12
12
  end
13
13
 
14
14
  context '#update' do
15
15
  should 'not be implemented' do
16
- u = build(:user)
16
+ s = build(:suppression)
17
17
  assert_raises ESP::NotImplementedError do
18
- u.save
18
+ s.save
19
19
  end
20
20
  end
21
21
  end
22
22
 
23
23
  context '#destroy' do
24
24
  should 'not be implemented' do
25
- u = build(:user)
25
+ s = build(:suppression)
26
26
  assert_raises ESP::NotImplementedError do
27
- u.destroy
27
+ s.destroy
28
28
  end
29
29
  end
30
30
  end
@@ -3,32 +3,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
3
3
  module ESP
4
4
  class UserTest < ActiveSupport::TestCase
5
5
  context ESP::User do
6
- context '#create' do
7
- should 'not be implemented' do
8
- assert_raises ESP::NotImplementedError do
9
- ESP::User.create(name: 'test')
10
- end
11
- end
12
- end
13
-
14
- context '#update' do
15
- should 'not be implemented' do
16
- u = build(:user)
17
- assert_raises ESP::NotImplementedError do
18
- u.save
19
- end
20
- end
21
- end
22
-
23
- context '#destroy' do
24
- should 'not be implemented' do
25
- u = build(:user)
26
- assert_raises ESP::NotImplementedError do
27
- u.destroy
28
- end
29
- end
30
- end
31
-
32
6
  context '#organization' do
33
7
  should 'call the api' do
34
8
  u = build(:user, organization_id: 1)
@@ -91,6 +65,17 @@ module ESP
91
65
  assert_not_requested(:put, /teams.json*/)
92
66
  end
93
67
  end
68
+
69
+ context '#role' do
70
+ should 'call the api' do
71
+ u = build(:user, role_id: 1)
72
+ stub_role = stub_request(:get, %r{roles/#{u.role_id}.json*}).to_return(body: json(:role))
73
+
74
+ u.role
75
+
76
+ assert_requested(stub_role)
77
+ end
78
+ end
94
79
  end
95
80
  end
96
81
  end
@@ -0,0 +1,9 @@
1
+ FactoryGirl.define do
2
+ factory :role, class: 'ESP::Role' do
3
+ skip_create
4
+
5
+ sequence(:id) { |n| n }
6
+ type "roles"
7
+ name "customer"
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: esp_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evident.io
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-17 00:00:00.000000000 Z
11
+ date: 2016-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -357,6 +357,7 @@ files:
357
357
  - lib/esp/resources/report.rb
358
358
  - lib/esp/resources/reports/export/integration.rb
359
359
  - lib/esp/resources/resource.rb
360
+ - lib/esp/resources/role.rb
360
361
  - lib/esp/resources/scan_interval.rb
361
362
  - lib/esp/resources/service.rb
362
363
  - lib/esp/resources/signature.rb
@@ -400,6 +401,7 @@ files:
400
401
  - test/esp/integration/report_export_integration_integration_test.rb
401
402
  - test/esp/integration/report_integration_test.rb
402
403
  - test/esp/integration/resource_integration_test.rb
404
+ - test/esp/integration/role_integration_test.rb
403
405
  - test/esp/integration/scan_interval_integration_test.rb
404
406
  - test/esp/integration/service_integration_test.rb
405
407
  - test/esp/integration/signature_integration_test.rb
@@ -432,6 +434,7 @@ files:
432
434
  - test/esp/resources/report_test.rb
433
435
  - test/esp/resources/reports/export/integration_test.rb
434
436
  - test/esp/resources/resource_test.rb
437
+ - test/esp/resources/role_test.rb
435
438
  - test/esp/resources/scan_interval_test.rb
436
439
  - test/esp/resources/service_test.rb
437
440
  - test/esp/resources/signature_test.rb
@@ -463,6 +466,7 @@ files:
463
466
  - test/factories/organizations.rb
464
467
  - test/factories/regions.rb
465
468
  - test/factories/reports.rb
469
+ - test/factories/roles.rb
466
470
  - test/factories/scan_intervals.rb
467
471
  - test/factories/services.rb
468
472
  - test/factories/signatures.rb
@@ -502,7 +506,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
502
506
  version: '0'
503
507
  requirements: []
504
508
  rubyforge_project:
505
- rubygems_version: 2.0.14.1
509
+ rubygems_version: 2.4.8
506
510
  signing_key:
507
511
  specification_version: 4
508
512
  summary: SDK for interacting with the ESP API.
@@ -530,6 +534,7 @@ test_files:
530
534
  - test/esp/integration/report_export_integration_integration_test.rb
531
535
  - test/esp/integration/report_integration_test.rb
532
536
  - test/esp/integration/resource_integration_test.rb
537
+ - test/esp/integration/role_integration_test.rb
533
538
  - test/esp/integration/scan_interval_integration_test.rb
534
539
  - test/esp/integration/service_integration_test.rb
535
540
  - test/esp/integration/signature_integration_test.rb
@@ -562,6 +567,7 @@ test_files:
562
567
  - test/esp/resources/report_test.rb
563
568
  - test/esp/resources/reports/export/integration_test.rb
564
569
  - test/esp/resources/resource_test.rb
570
+ - test/esp/resources/role_test.rb
565
571
  - test/esp/resources/scan_interval_test.rb
566
572
  - test/esp/resources/service_test.rb
567
573
  - test/esp/resources/signature_test.rb
@@ -593,6 +599,7 @@ test_files:
593
599
  - test/factories/organizations.rb
594
600
  - test/factories/regions.rb
595
601
  - test/factories/reports.rb
602
+ - test/factories/roles.rb
596
603
  - test/factories/scan_intervals.rb
597
604
  - test/factories/services.rb
598
605
  - test/factories/signatures.rb