forest_liana 2.15.4 → 2.15.5

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/services/forest_liana/resources_getter.rb +10 -2
  3. data/lib/forest_liana/engine.rb +11 -13
  4. data/lib/forest_liana/version.rb +1 -1
  5. data/spec/dummy/README.rdoc +28 -0
  6. data/spec/dummy/Rakefile +6 -0
  7. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  8. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  9. data/spec/dummy/app/config/routes.rb +3 -0
  10. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  11. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  12. data/spec/dummy/app/models/island.rb +5 -0
  13. data/spec/dummy/app/models/tree.rb +5 -0
  14. data/spec/dummy/app/models/user.rb +4 -0
  15. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  16. data/spec/dummy/bin/bundle +3 -0
  17. data/spec/dummy/bin/rails +4 -0
  18. data/spec/dummy/bin/rake +4 -0
  19. data/spec/dummy/bin/setup +29 -0
  20. data/spec/dummy/config.ru +4 -0
  21. data/spec/dummy/config/application.rb +26 -0
  22. data/spec/dummy/config/boot.rb +5 -0
  23. data/spec/dummy/config/database.yml +25 -0
  24. data/spec/dummy/config/environment.rb +5 -0
  25. data/spec/dummy/config/environments/development.rb +41 -0
  26. data/spec/dummy/config/environments/production.rb +79 -0
  27. data/spec/dummy/config/environments/test.rb +42 -0
  28. data/spec/dummy/config/initializers/assets.rb +11 -0
  29. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  30. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  31. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  32. data/spec/dummy/config/initializers/forest_liana.rb +2 -0
  33. data/spec/dummy/config/initializers/inflections.rb +16 -0
  34. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  35. data/spec/dummy/config/initializers/session_store.rb +3 -0
  36. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  37. data/spec/dummy/config/routes.rb +3 -0
  38. data/spec/dummy/config/secrets.yml +22 -0
  39. data/spec/dummy/db/migrate/20190226172951_create_user.rb +9 -0
  40. data/spec/dummy/db/migrate/20190226173051_create_isle.rb +10 -0
  41. data/spec/dummy/db/migrate/20190226174951_create_tree.rb +12 -0
  42. data/spec/dummy/db/schema.rb +42 -0
  43. data/spec/dummy/db/test.sqlite3 +0 -0
  44. data/spec/dummy/log/development.log +80 -0
  45. data/spec/dummy/log/test.log +22549 -0
  46. data/spec/helpers/forest_liana/query_helper_spec.rb +74 -0
  47. data/spec/rails_helper.rb +61 -0
  48. data/spec/requests/resources_spec.rb +97 -0
  49. data/spec/services/forest_liana/apimap_sorter_spec.rb +172 -0
  50. data/spec/services/forest_liana/ip_whitelist_checker_spec.rb +203 -0
  51. data/spec/services/forest_liana/schema_adapter_spec.rb +17 -0
  52. data/spec/spec_helper.rb +99 -0
  53. data/test/dummy/config/routes.rb +0 -1
  54. data/test/dummy/db/test.sqlite3 +0 -0
  55. data/test/dummy/log/test.log +1213 -0
  56. data/test/routing/route_test.rb +0 -2
  57. metadata +98 -2
@@ -0,0 +1,74 @@
1
+ module ForestLiana
2
+ describe QueryHelper do
3
+ before(:all) do
4
+ Tree.connection
5
+ User.connection
6
+ Island.connection
7
+ end
8
+
9
+ describe 'get_one_associations' do
10
+ context 'on a model having 2 hasMany associations' do
11
+ it 'should not return any one-one associations' do
12
+ associations = QueryHelper.get_one_associations(User)
13
+ expect(associations.length).to eq(0)
14
+ end
15
+ end
16
+
17
+ context 'on a model having 3 belongsTo associations' do
18
+ it 'should return the one-one associations' do
19
+ associations = QueryHelper.get_one_associations(Tree)
20
+ expect(associations.length).to eq(3)
21
+ expect(associations.first.name).to eq(:owner)
22
+ expect(associations.first.klass).to eq(User)
23
+ expect(associations.second.name).to eq(:cutter)
24
+ expect(associations.second.klass).to eq(User)
25
+ expect(associations.third.name).to eq(:island)
26
+ expect(associations.third.klass).to eq(Island)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'get_one_association_names_symbol' do
32
+ it 'should return the one-one associations names as symbols' do
33
+ expect(QueryHelper.get_one_association_names_symbol(Tree)).to eq([:owner, :cutter, :island])
34
+ end
35
+ end
36
+
37
+ describe 'get_one_association_names_string' do
38
+ it 'should return the one-one associations names as strings' do
39
+ expect(QueryHelper.get_one_association_names_string(Tree)).to eq(['owner', 'cutter', 'island'])
40
+ end
41
+ end
42
+
43
+ describe 'get_tables_associated_to_relations_name' do
44
+ context 'on a model having 2 hasMany associations' do
45
+ it 'should return an empty hash' do
46
+ tables_associated_to_relations_name =
47
+ QueryHelper.get_tables_associated_to_relations_name(User)
48
+ expect(tables_associated_to_relations_name.keys.length).to eq(0)
49
+ end
50
+ end
51
+
52
+ context 'on a model having 2 belongsTo associations' do
53
+ tables_associated_to_relations_name =
54
+ QueryHelper.get_tables_associated_to_relations_name(Tree)
55
+
56
+ it 'should return the one-one associations' do
57
+ expect(tables_associated_to_relations_name.keys.length).to eq(2)
58
+ end
59
+
60
+ it 'should return relationships having a name different than the targeted model' do
61
+ expect(tables_associated_to_relations_name['users'].length).to eq(2)
62
+ expect(tables_associated_to_relations_name['users'].first).to eq(:owner)
63
+ expect(tables_associated_to_relations_name['users'].second).to eq(:cutter)
64
+ end
65
+
66
+ it 'should return relationships on models having a custom table name' do
67
+ expect(tables_associated_to_relations_name['isle'].length).to eq(1)
68
+ expect(tables_associated_to_relations_name['isle'].first).to eq(:island)
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,61 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ require 'spec_helper'
3
+ ENV['RAILS_ENV'] ||= 'test'
4
+ require File.expand_path('../dummy/config/environment', __FILE__)
5
+ # Prevent database truncation if the environment is production
6
+ abort("The Rails environment is running in production mode!") if Rails.env.production?
7
+ require 'rspec/rails'
8
+ # Add additional requires below this line. Rails is not loaded until this point!
9
+
10
+ # Requires supporting ruby files with custom matchers and macros, etc, in
11
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
12
+ # run as spec files by default. This means that files in spec/support that end
13
+ # in _spec.rb will both be required and run as specs, causing the specs to be
14
+ # run twice. It is recommended that you do not name files matching this glob to
15
+ # end with _spec.rb. You can configure this pattern with the --pattern
16
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
17
+ #
18
+ # The following line is provided for convenience purposes. It has the downside
19
+ # of increasing the boot-up time by auto-requiring all files in the support
20
+ # directory. Alternatively, in the individual `*_spec.rb` files, manually
21
+ # require only the support files necessary.
22
+ #
23
+ # Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
24
+
25
+ # Checks for pending migrations and applies them before tests are run.
26
+ # If you are not using ActiveRecord, you can remove these lines.
27
+ begin
28
+ ActiveRecord::Migration.maintain_test_schema!
29
+ rescue ActiveRecord::PendingMigrationError => e
30
+ puts e.to_s.strip
31
+ exit 1
32
+ end
33
+ RSpec.configure do |config|
34
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
35
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
36
+
37
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
38
+ # examples within a transaction, remove the following line or assign false
39
+ # instead of true.
40
+ config.use_transactional_fixtures = true
41
+
42
+ # RSpec Rails can automatically mix in different behaviours to your tests
43
+ # based on their file location, for example enabling you to call `get` and
44
+ # `post` in specs under `spec/controllers`.
45
+ #
46
+ # You can disable this behaviour by removing the line below, and instead
47
+ # explicitly tag your specs with their type, e.g.:
48
+ #
49
+ # RSpec.describe UsersController, :type => :controller do
50
+ # # ...
51
+ # end
52
+ #
53
+ # The different available types are documented in the features, such as in
54
+ # https://relishapp.com/rspec/rspec-rails/docs
55
+ config.infer_spec_type_from_file_location!
56
+
57
+ # Filter lines from Rails gems in backtraces.
58
+ config.filter_rails_from_backtrace!
59
+ # arbitrary gems may also be filtered via:
60
+ # config.filter_gems_from_backtrace("gem name")
61
+ end
@@ -0,0 +1,97 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'Requesting Tree resources', :type => :request do
4
+ before(:each) do
5
+ user = User.create(name: 'Michel')
6
+ tree = Tree.create(name: 'Lemon Tree', owner: user, cutter: user)
7
+ end
8
+
9
+ after(:each) do
10
+ User.destroy_all
11
+ Tree.destroy_all
12
+ end
13
+
14
+ before(:each) do
15
+ allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }
16
+ allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
17
+ allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
18
+
19
+ allow_any_instance_of(ForestLiana::PermissionsChecker).to receive(:is_authorized?) { true }
20
+ end
21
+
22
+ headers = {
23
+ 'Accept' => 'application/json',
24
+ 'Content-Type' => 'application/json',
25
+ 'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxODQ5ODc4ODYzIiwiZGF0YSI6eyJpZCI6IjM4IiwidHlwZSI6InVzZXJzIiwiZGF0YSI6eyJlbWFpbCI6Im1pY2hhZWwua2Vsc29AdGhhdDcwLnNob3ciLCJmaXJzdF9uYW1lIjoiTWljaGFlbCIsImxhc3RfbmFtZSI6IktlbHNvIiwidGVhbXMiOiJPcGVyYXRpb25zIn0sInJlbGF0aW9uc2hpcHMiOnsicmVuZGVyaW5ncyI6eyJkYXRhIjpbeyJ0eXBlIjoicmVuZGVyaW5ncyIsImlkIjoxNn1dfX19fQ.U4Mxi0tq0Ce7y5FRXP47McNPRPhUx37LznQ5E3mJIp4'
26
+ }
27
+
28
+ describe 'index' do
29
+ describe 'without any filter' do
30
+ params = {
31
+ fields: { 'Tree' => 'id,name' },
32
+ page: { 'number' => '1', 'size' => '10' },
33
+ searchExtended: '0',
34
+ sort: '-id',
35
+ timezone: 'Europe/Paris'
36
+ }
37
+
38
+ it 'should respond 200' do
39
+ get '/forest/Tree', params, headers
40
+ expect(response.status).to eq(200)
41
+ end
42
+
43
+ it 'should respond the tree data' do
44
+ get '/forest/Tree', params, headers
45
+ expect(JSON.parse(response.body)).to eq({
46
+ "data" => [{
47
+ "type" => "Tree",
48
+ "id" => "1",
49
+ "attributes" => {
50
+ "id" => 1,
51
+ "name" => "Lemon Tree"
52
+ },
53
+ "links" => {
54
+ "self" => "/forest/tree/1"
55
+ }
56
+ }],
57
+ "included" => []
58
+ })
59
+ end
60
+ end
61
+
62
+ describe 'with a filter on an association that is not a displayed column' do
63
+ params = {
64
+ fields: { 'Tree' => 'id,name' },
65
+ filterType: 'and',
66
+ filter: { 'owner:id' => '$present' },
67
+ page: { 'number' => '1', 'size' => '10' },
68
+ searchExtended: '0',
69
+ sort: '-id',
70
+ timezone: 'Europe/Paris'
71
+ }
72
+
73
+ it 'should respond 200' do
74
+ get '/forest/Tree', params, headers
75
+ expect(response.status).to eq(200)
76
+ end
77
+
78
+ it 'should respond the tree data' do
79
+ get '/forest/Tree', params, headers
80
+ expect(JSON.parse(response.body)).to eq({
81
+ "data" => [{
82
+ "type" => "Tree",
83
+ "id" => "1",
84
+ "attributes" => {
85
+ "id" => 1,
86
+ "name" => "Lemon Tree"
87
+ },
88
+ "links" => {
89
+ "self" => "/forest/tree/1"
90
+ }
91
+ }],
92
+ "included" => []
93
+ })
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,172 @@
1
+ module ForestLiana
2
+ describe ApimapSorter do
3
+ describe 'apimap reordering' do
4
+ context 'on a disordered apimap' do
5
+ apimap = {
6
+ 'meta': {
7
+ 'orm_version': '4.34.9',
8
+ 'liana_version': '1.5.24',
9
+ 'database_type': 'postgresql',
10
+ liana: 'forest-rails',
11
+ },
12
+ 'data': [{
13
+ id: 'users',
14
+ type: 'collections',
15
+ attributes: {
16
+ fields: [
17
+ { field: 'id', type: 'Number' },
18
+ { field: 'name', type: 'String' },
19
+ { field: 'firstName', type: 'String' },
20
+ { field: 'lastName', type: 'String' },
21
+ { field: 'email', type: 'String' },
22
+ { field: 'url', type: 'String' },
23
+ { field: 'createdAt', type: 'Date' },
24
+ { field: 'updatedAt', type: 'Date' },
25
+ ],
26
+ name: 'users',
27
+ }
28
+ }, {
29
+ id: 'guests',
30
+ type: 'collections',
31
+ attributes: {
32
+ fields: [
33
+ { field: 'id', type: 'Number' },
34
+ { field: 'email', type: 'String' },
35
+ { field: 'createdAt', type: 'Date' },
36
+ { field: 'updatedAt', type: 'Date' },
37
+ ],
38
+ name: 'guests',
39
+ }
40
+ }, {
41
+ type: 'collections',
42
+ id: 'animals',
43
+ attributes: {
44
+ fields: [
45
+ { 'is-sortable': false, field: 'id', 'is-filterable': false, type: 'Number' },
46
+ { type: 'Date', field: 'createdAt' },
47
+ { field: 'updatedAt', type: 'Date' },
48
+ ],
49
+ name: 'animals',
50
+ integration: 'close.io',
51
+ 'is-virtual': true,
52
+ }
53
+ }],
54
+ 'included': [{
55
+ id: 'users.Women',
56
+ type: 'segments',
57
+ attributes: {
58
+ name: 'Women'
59
+ }
60
+ }, {
61
+ id: 'users.import',
62
+ type: 'actions',
63
+ links: {
64
+ self: '/actions'
65
+ },
66
+ attributes: {
67
+ name: 'import',
68
+ fields: [{
69
+ isRequired: true,
70
+ type: 'Boolean',
71
+ field: 'Save',
72
+ description: 'save the import file if true.',
73
+ defaultValue: 'true'
74
+ }, {
75
+ type: 'File',
76
+ field: 'File'
77
+ }],
78
+ 'http-method': nil
79
+ }
80
+ }, {
81
+ attributes: {
82
+ name: 'Men'
83
+ },
84
+ id: 'users.Men',
85
+ type: 'segments'
86
+ }, {
87
+ id: 'animals.ban',
88
+ type: 'actions',
89
+ links: {
90
+ self: '/actions'
91
+ },
92
+ attributes: {
93
+ name: 'import',
94
+ global: true,
95
+ download: nil,
96
+ endpoint: nil,
97
+ redirect: nil,
98
+ 'http-method': nil
99
+ }
100
+ }]
101
+ }
102
+
103
+ apimap = ActiveSupport::JSON.encode(apimap)
104
+ apimap = ActiveSupport::JSON.decode(apimap)
105
+ apimap_sorted = ApimapSorter.new(apimap).perform
106
+
107
+ it 'should sort the apimap sections' do
108
+ expect(apimap_sorted.keys).to eq(['data', 'included', 'meta'])
109
+ end
110
+
111
+ it 'should sort the data collections' do
112
+ expect(apimap_sorted['data'].map { |collection| collection['id'] }).to eq(
113
+ ['animals', 'guests', 'users'])
114
+ end
115
+
116
+ it 'should sort the data collection values' do
117
+ expect(apimap_sorted['data'][0].keys).to eq(['type', 'id', 'attributes'])
118
+ expect(apimap_sorted['data'][1].keys).to eq(['type', 'id', 'attributes'])
119
+ expect(apimap_sorted['data'][2].keys).to eq(['type', 'id', 'attributes'])
120
+ end
121
+
122
+ it 'should sort the data collections attributes values' do
123
+ expect(apimap_sorted['data'][0]['attributes'].keys).to eq(['name', 'integration', 'is-virtual', 'fields'])
124
+ expect(apimap_sorted['data'][1]['attributes'].keys).to eq(['name', 'fields'])
125
+ expect(apimap_sorted['data'][2]['attributes'].keys).to eq(['name', 'fields'])
126
+ end
127
+
128
+ it 'should sort the data collections attributes fields by name' do
129
+ expect(apimap_sorted['data'][0]['attributes']['fields'].map { |field| field['field'] }).to eq(['createdAt', 'id', 'updatedAt'])
130
+ expect(apimap_sorted['data'][1]['attributes']['fields'].map { |field| field['field'] }).to eq(['createdAt', 'email', 'id', 'updatedAt'])
131
+ expect(apimap_sorted['data'][2]['attributes']['fields'].map { |field| field['field'] }).to eq(['createdAt', 'email', 'firstName', 'id', 'lastName', 'name', 'updatedAt', 'url'])
132
+ end
133
+
134
+ it 'should sort the data collections attributes fields values' do
135
+ expect(apimap_sorted['data'][0]['attributes']['fields'][1].keys).to eq(['field', 'type', 'is-filterable', 'is-sortable'])
136
+ end
137
+
138
+ it 'should sort the included actions and segments objects' do
139
+ expect(apimap_sorted['included'].map { |object| object['id'] }).to eq(
140
+ ['animals.ban', 'users.import', 'users.Men', 'users.Women'])
141
+ end
142
+
143
+ it 'should sort the included actions and segments objects values' do
144
+ expect(apimap_sorted['included'][0].keys).to eq(['type', 'id', 'attributes', 'links'])
145
+ expect(apimap_sorted['included'][1].keys).to eq(['type', 'id', 'attributes', 'links'])
146
+ expect(apimap_sorted['included'][2].keys).to eq(['type', 'id', 'attributes'])
147
+ expect(apimap_sorted['included'][3].keys).to eq(['type', 'id', 'attributes'])
148
+ end
149
+
150
+ it 'should sort the included actions and segments objects attributes values' do
151
+ expect(apimap_sorted['included'][0]['attributes'].keys).to eq(['name', 'download', 'endpoint', 'global', 'http-method', 'redirect'])
152
+ expect(apimap_sorted['included'][1]['attributes'].keys).to eq(['name', 'http-method', 'fields'])
153
+ expect(apimap_sorted['included'][2]['attributes'].keys).to eq(['name'])
154
+ expect(apimap_sorted['included'][3]['attributes'].keys).to eq(['name'])
155
+ end
156
+
157
+ it 'should sort the included action attributes fields by name' do
158
+ expect(apimap_sorted['included'][1]['attributes']['fields'].map { |field| field['field'] }).to eq(['File', 'Save'])
159
+ end
160
+
161
+ it 'should sort the included action fields values' do
162
+ expect(apimap_sorted['included'][1]['attributes']['fields'][1].keys).to eq(['field', 'type', 'defaultValue', 'description', 'isRequired'])
163
+ end
164
+
165
+ it 'should sort the meta values' do
166
+ expect(apimap_sorted['meta'].keys).to eq(
167
+ ['database_type', 'liana', 'liana_version', 'orm_version'])
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,203 @@
1
+ module ForestLiana
2
+ describe IpWhitelistChecker do
3
+ describe 'Check is_ip_matches_rule function' do
4
+ describe 'with IP "90.88.0.1" and "90.88.0.2"' do
5
+ it 'should return false' do
6
+ rule = {
7
+ 'type' => 0,
8
+ 'ip' => '90.88.0.1',
9
+ }
10
+
11
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.0.2', rule)
12
+
13
+ expect(is_matching).to eq(false)
14
+ end
15
+ end
16
+
17
+ describe 'with IP "::1" and "aaaa"' do
18
+ it 'should raise an "ArgumentError" exception with "Unknown IP Address aaaa" message' do
19
+ rule = {
20
+ 'type' => 0,
21
+ 'ip' => '::1',
22
+ }
23
+
24
+ expect {
25
+ IpWhitelistChecker.is_ip_matches_rule('aaaa', rule)
26
+ }.to raise_error(ArgumentError, 'Unknown IP Address aaaa')
27
+ end
28
+ end
29
+
30
+ describe 'with IP "90.88.0.1" and "::1"' do
31
+ it 'should return false' do
32
+ rule = {
33
+ 'type' => 0,
34
+ 'ip' => '90.88.0.1',
35
+ }
36
+
37
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('::1', rule)
38
+
39
+ expect(is_matching).to eq(false)
40
+ end
41
+ end
42
+
43
+ describe 'with IP "::1" and "::1"' do
44
+ it 'should return true' do
45
+ rule = {
46
+ 'type' => 0,
47
+ 'ip' => '::1',
48
+ }
49
+
50
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('::1', rule)
51
+
52
+ expect(is_matching).to eq(true)
53
+ end
54
+ end
55
+
56
+ describe 'with IP "90.88.0.1" and "90.88.0.1"' do
57
+ it 'should return true' do
58
+ rule = {
59
+ 'type' => 0,
60
+ 'ip' => '90.88.0.1',
61
+ }
62
+
63
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.0.1', rule)
64
+
65
+ expect(is_matching).to eq(true)
66
+ end
67
+ end
68
+
69
+ describe 'with IP "90.88.0.0" and "90.88.0.0"' do
70
+ it 'should return true' do
71
+ rule = {
72
+ 'type' => 0,
73
+ 'ip' => '90.88.0.0',
74
+ }
75
+
76
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.0.0', rule)
77
+
78
+ expect(is_matching).to eq(true)
79
+ end
80
+ end
81
+
82
+ describe 'with IP "127.0.0.1" and "::1"' do
83
+ it 'should return true' do
84
+ rule = {
85
+ 'type' => 0,
86
+ 'ip' => '127.0.0.1',
87
+ }
88
+
89
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('::1', rule)
90
+
91
+ expect(is_matching).to eq(true)
92
+ end
93
+ end
94
+
95
+ describe 'with range "90.88.0.0 - 90.88.255.255' do
96
+ rule = {
97
+ 'type' => 1,
98
+ 'ip_minimum' => '90.88.0.0',
99
+ 'ip_maximum' => '90.88.255.255',
100
+ }
101
+
102
+ describe 'with IP "90.89.0.1"' do
103
+ it 'should return false' do
104
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.89.0.1', rule)
105
+
106
+ expect(is_matching).to eq(false)
107
+ end
108
+ end
109
+
110
+ describe 'with IP "::ffff:90.89.0.1"' do
111
+ it 'should return false' do
112
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('::ffff:90.89.0.1', rule)
113
+
114
+ expect(is_matching).to eq(false)
115
+ end
116
+ end
117
+
118
+ describe 'with IP "90.88.118.79"' do
119
+ it 'should return false' do
120
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.118.79', rule)
121
+
122
+ expect(is_matching).to eq(true)
123
+ end
124
+ end
125
+ end
126
+
127
+ describe 'with range "90.88.0.1 - 90.88.255.255" and IP "90.88.118.79"' do
128
+ it 'should return true' do
129
+ rule = {
130
+ 'type' => 1,
131
+ 'ip_minimum' => '90.88.0.1',
132
+ 'ip_maximum' => '90.88.255.255',
133
+ }
134
+
135
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.118.79', rule)
136
+
137
+ expect(is_matching).to eq(true)
138
+ end
139
+ end
140
+
141
+ describe 'with range "90.88.0.1 - 90.88.254.254" and IP "90.88.118.79"' do
142
+ it 'should return true' do
143
+ rule = {
144
+ 'type' => 1,
145
+ 'ip_minimum' => '90.88.0.1',
146
+ 'ip_maximum' => '90.88.254.254',
147
+ }
148
+
149
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.118.79', rule)
150
+
151
+ expect(is_matching).to eq(true)
152
+ end
153
+ end
154
+
155
+ describe 'with subnet "90.88.0.0/24"' do
156
+ rule = {
157
+ 'type' => 2,
158
+ 'range' => '90.88.0.0/24',
159
+ }
160
+
161
+ describe 'with IP "90.88.0.1"' do
162
+ it 'should return true' do
163
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.0.1', rule)
164
+
165
+ expect(is_matching).to eq(true)
166
+ end
167
+ end
168
+
169
+ describe 'with IP "90.88.0.0"' do
170
+ it 'should return true' do
171
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.0.0', rule)
172
+
173
+ expect(is_matching).to eq(true)
174
+ end
175
+ end
176
+
177
+ describe 'with IP "90.88.0.254"' do
178
+ it 'should return true' do
179
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.0.254', rule)
180
+
181
+ expect(is_matching).to eq(true)
182
+ end
183
+ end
184
+
185
+ describe 'with IP "90.88.1.1"' do
186
+ it 'should return true' do
187
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('90.88.1.1', rule)
188
+
189
+ expect(is_matching).to eq(false)
190
+ end
191
+ end
192
+
193
+ describe 'with IP "::1"' do
194
+ it 'should return true' do
195
+ is_matching = IpWhitelistChecker.is_ip_matches_rule('::1', rule)
196
+
197
+ expect(is_matching).to eq(false)
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end