forest_liana 2.15.4 → 2.15.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/services/forest_liana/resources_getter.rb +10 -2
- data/lib/forest_liana/engine.rb +11 -13
- data/lib/forest_liana/version.rb +1 -1
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/config/routes.rb +3 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/island.rb +5 -0
- data/spec/dummy/app/models/tree.rb +5 -0
- data/spec/dummy/app/models/user.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/forest_liana.rb +2 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/migrate/20190226172951_create_user.rb +9 -0
- data/spec/dummy/db/migrate/20190226173051_create_isle.rb +10 -0
- data/spec/dummy/db/migrate/20190226174951_create_tree.rb +12 -0
- data/spec/dummy/db/schema.rb +42 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +80 -0
- data/spec/dummy/log/test.log +22549 -0
- data/spec/helpers/forest_liana/query_helper_spec.rb +74 -0
- data/spec/rails_helper.rb +61 -0
- data/spec/requests/resources_spec.rb +97 -0
- data/spec/services/forest_liana/apimap_sorter_spec.rb +172 -0
- data/spec/services/forest_liana/ip_whitelist_checker_spec.rb +203 -0
- data/spec/services/forest_liana/schema_adapter_spec.rb +17 -0
- data/spec/spec_helper.rb +99 -0
- data/test/dummy/config/routes.rb +0 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +1213 -0
- data/test/routing/route_test.rb +0 -2
- 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
|