policy_machine 0.0.1
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.
- data/CONTRIBUTING.md +35 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +20 -0
- data/README.md +98 -0
- data/lib/generators/policy_machine/policy_machine_generator.rb +13 -0
- data/lib/generators/policy_machine/templates/migration.rb +40 -0
- data/lib/policy_machine.rb +236 -0
- data/lib/policy_machine/association.rb +73 -0
- data/lib/policy_machine/policy_element.rb +269 -0
- data/lib/policy_machine/version.rb +3 -0
- data/lib/policy_machine_storage_adapters/active_record.rb +306 -0
- data/lib/policy_machine_storage_adapters/in_memory.rb +266 -0
- data/lib/policy_machine_storage_adapters/neography.rb +236 -0
- data/lib/policy_machine_storage_adapters/template.rb +169 -0
- data/lib/tasks/policy_machine_tasks.rake +4 -0
- data/policy_machine.gemspec +23 -0
- data/spec/policy_machine/association_spec.rb +61 -0
- data/spec/policy_machine/policy_element_spec.rb +20 -0
- data/spec/policy_machine_spec.rb +7 -0
- data/spec/policy_machine_storage_adapters/active_record_spec.rb +54 -0
- data/spec/policy_machine_storage_adapters/in_memory_spec.rb +13 -0
- data/spec/policy_machine_storage_adapters/neography_spec.rb +42 -0
- data/spec/policy_machine_storage_adapters/template_spec.rb +6 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/neography_helpers.rb +39 -0
- data/spec/support/policy_machine_helpers.rb +22 -0
- data/spec/support/shared_examples_policy_machine_spec.rb +697 -0
- data/spec/support/shared_examples_policy_machine_storage_adapter_spec.rb +278 -0
- data/spec/support/shared_examples_storage_adapter_public_methods.rb +20 -0
- data/spec/support/storage_adapter_helpers.rb +7 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +65 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +42 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/migrate/20131015214828_generate_policy_machine.rb +40 -0
- data/test/dummy/db/migrate/20131021221759_add_color_to_policy_element.rb +5 -0
- data/test/dummy/db/schema.rb +57 -0
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/policy_machine_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +270 -0
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'policy_machine'
|
2
|
+
|
3
|
+
# This class provides a template for creating your own Policy Machine
|
4
|
+
# Storage Adapter. Simply copy this file and implement all public methods.
|
5
|
+
# Ensure correctness using the shared examples in
|
6
|
+
# 'spec/support/shared_examples_policy_machine_storage_adapter_spec.rb'.
|
7
|
+
# Ensure your adapter integrates properly with the policy machine using the shared
|
8
|
+
# examples in 'spec/support/shared_examples_policy_machine_spec.rb'.
|
9
|
+
|
10
|
+
module PolicyMachineStorageAdapter
|
11
|
+
class Template
|
12
|
+
|
13
|
+
##
|
14
|
+
# The following add_* methods store a policy element in the policy machine.
|
15
|
+
# The unique_identifier identifies the element within the policy machine.
|
16
|
+
# The policy_machine_uuid is the uuid of the containing policy machine.
|
17
|
+
# Extra attributes should be persisted as metadata associated with the object.
|
18
|
+
# Each method should return the persisted policy element. Persisted policy
|
19
|
+
# element objects should respond to each extra attribute key as well as the following methods:
|
20
|
+
# * unique_identifier
|
21
|
+
# * policy_machine_uuid
|
22
|
+
# * persisted
|
23
|
+
#
|
24
|
+
def add_user(unique_identifier, policy_machine_uuid, extra_attributes = {})
|
25
|
+
|
26
|
+
end
|
27
|
+
def add_user_attribute(unique_identifier, policy_machine_uuid, extra_attributes = {})
|
28
|
+
|
29
|
+
end
|
30
|
+
def add_object(unique_identifier, policy_machine_uuid, extra_attributes = {})
|
31
|
+
|
32
|
+
end
|
33
|
+
def add_object_attribute(unique_identifier, policy_machine_uuid, extra_attributes = {})
|
34
|
+
|
35
|
+
end
|
36
|
+
def add_operation(unique_identifier, policy_machine_uuid, extra_attributes = {})
|
37
|
+
|
38
|
+
end
|
39
|
+
def add_policy_class(unique_identifier, policy_machine_uuid, extra_attributes = {})
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# The following find_* methods should return an array of persisted
|
45
|
+
# policy elements of the given type (e.g. user or object_attribute) and extra attributes.
|
46
|
+
# If no such persisted policy elements are found, the empty array should
|
47
|
+
# be returned.
|
48
|
+
#
|
49
|
+
def find_all_of_type_user(options = {})
|
50
|
+
|
51
|
+
end
|
52
|
+
def find_all_of_type_user_attribute(options = {})
|
53
|
+
|
54
|
+
end
|
55
|
+
def find_all_of_type_object(options = {})
|
56
|
+
|
57
|
+
end
|
58
|
+
def find_all_of_type_object_attribute(options = {})
|
59
|
+
|
60
|
+
end
|
61
|
+
def find_all_of_type_operation(options = {})
|
62
|
+
|
63
|
+
end
|
64
|
+
def find_all_of_type_policy_class(options = {})
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Assign src to dst in policy machine.
|
70
|
+
# The two policy elements must be persisted policy elements; otherwise the method should raise
|
71
|
+
# an ArgumentError.
|
72
|
+
# Returns true if the assignment occurred, false otherwise.
|
73
|
+
#
|
74
|
+
def assign(src, dst)
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Determine if there is a path from src to dst in the policy machine.
|
80
|
+
# The two policy elements must be persisted policy elements; otherwise the method should raise
|
81
|
+
# an ArgumentError.
|
82
|
+
# Returns true if there is a such a path and false otherwise.
|
83
|
+
# Should return true if src == dst
|
84
|
+
#
|
85
|
+
def connected?(src, dst)
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Disconnect two policy elements in the machine
|
91
|
+
# The two policy elements must be persisted policy elements; otherwise the method should raise
|
92
|
+
# an ArgumentError.
|
93
|
+
# Returns true if unassignment occurred and false otherwise.
|
94
|
+
# Generally, false will be returned if the assignment didn't exist in the PM in the
|
95
|
+
# first place.
|
96
|
+
#
|
97
|
+
def unassign(src, dst)
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Remove a persisted policy element. This should remove its assignments and
|
103
|
+
# associations but must not cascade to any connected policy elements.
|
104
|
+
# Returns true if the delete succeeded.
|
105
|
+
#
|
106
|
+
def delete(element)
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Update the extra_attributes of a persisted policy element.
|
112
|
+
# This should only affect attributes corresponding to the keys passed in.
|
113
|
+
# Returns true if the update succeeded or was redundant.
|
114
|
+
#
|
115
|
+
def update(element, changes_hash)
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Determine if the given node is in the policy machine or not.
|
121
|
+
# Returns true or false accordingly.
|
122
|
+
#
|
123
|
+
def element_in_machine?(pe)
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Add the given association to the policy map. If an association between user_attribute
|
129
|
+
# and object_attribute already exists, then replace it with that given in the arguments.
|
130
|
+
# Returns true if the association was added and false otherwise.
|
131
|
+
#
|
132
|
+
def add_association(user_attribute, operation_set, object_attribute, policy_machine_uuid)
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Return an array of all associations in which the given operation is included.
|
138
|
+
# Each element of the array should itself be an array in which the first element
|
139
|
+
# is the user_attribute member of the association, the second element is a
|
140
|
+
# Ruby Set, each element of which is an operation, the third element is the
|
141
|
+
# object_attribute member of the association.
|
142
|
+
# If no associations are found then the empty array should be returned.
|
143
|
+
#
|
144
|
+
def associations_with(operation)
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Return array of all policy classes which contain the given object_attribute (or object).
|
150
|
+
# Return empty array if no such policy classes found.
|
151
|
+
def policy_classes_for_object_attribute(object_attribute)
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# Return array of all user attributes which contain the given user.
|
157
|
+
# Return empty array if no such user attributes are found.
|
158
|
+
def user_attributes_for_user(user)
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Execute the passed-in block transactionally: any error raised out of the block causes
|
163
|
+
# all the block's changes to be rolled back. Should raise NotImplementedError if the
|
164
|
+
# persistence layer does not support this.
|
165
|
+
def transaction
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "policy_machine"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "Policy Machine!"
|
5
|
+
s.description = "A ruby implementation of the Policy Machine authorization formalism."
|
6
|
+
s.authors = ['Matthew Szenher', 'Aaron Weiner']
|
7
|
+
s.email = s.authors.map{|name|name.sub(/(.).* (.*)/,'\1\2@mdsol.com')}
|
8
|
+
s.homepage = 'https://github.com/mdsol/the_policy_machine'
|
9
|
+
s.files = `git ls-files`.split("\n")
|
10
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
|
13
|
+
s.add_dependency('activesupport')
|
14
|
+
|
15
|
+
s.add_development_dependency('rspec', '~> 2.13.0')
|
16
|
+
s.add_development_dependency('simplecov', '~> 0.7.1')
|
17
|
+
s.add_development_dependency('debugger', '~> 1.6.0')
|
18
|
+
s.add_development_dependency('neography', '~> 1.1')
|
19
|
+
s.add_development_dependency('rails')
|
20
|
+
s.add_development_dependency('mysql2')
|
21
|
+
s.add_development_dependency('database_cleaner')
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PM::Association do
|
4
|
+
|
5
|
+
describe '#create' do
|
6
|
+
before do
|
7
|
+
@policy_machine = PolicyMachine.new
|
8
|
+
@object_attribute = @policy_machine.create_object_attribute('OA name')
|
9
|
+
@operation1 = @policy_machine.create_operation('read')
|
10
|
+
@operation2 = @policy_machine.create_operation('write')
|
11
|
+
@operation_set = Set.new [@operation1, @operation2]
|
12
|
+
@user_attribute = @policy_machine.create_user_attribute('UA name')
|
13
|
+
|
14
|
+
other_pm = PolicyMachine.new
|
15
|
+
@other_oa = other_pm.create_object_attribute('UA other')
|
16
|
+
@other_op = other_pm.create_operation('delete')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'raises when first argument is not a user attribute' do
|
20
|
+
expect{ PM::Association.create(@object_attribute, @operation_set, @object_attribute, @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
21
|
+
to raise_error(ArgumentError, "user_attribute_pe must be a UserAttribute.")
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'raises when first argument is not in given policy machine' do
|
25
|
+
expect{ PM::Association.create(@user_attribute, @operation_set, @object_attribute, "blah", @policy_machine.policy_machine_storage_adapter) }.
|
26
|
+
to raise_error(ArgumentError, "user_attribute_pe must be in policy machine with uuid blah")
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'raises when second argument is not a set' do
|
30
|
+
expect{ PM::Association.create(@user_attribute, 1, @object_attribute, @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
31
|
+
to raise_error(ArgumentError, "operation_set must be a Set of Operations")
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'raises when second argument is empty set' do
|
35
|
+
expect{ PM::Association.create(@user_attribute, Set.new, @object_attribute, @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
36
|
+
to raise_error(ArgumentError, "operation_set must not be empty")
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises when second argument is a set in which at least one element is not a PM::Operation' do
|
40
|
+
expect{ PM::Association.create(@user_attribute, Set.new([@operation1, 1]), @object_attribute, @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
41
|
+
to raise_error(ArgumentError, "expected 1 to be PM::Operation; got Fixnum")
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises when second argument is a set in which at least one element is a PM::Operation which is in a different policy machine' do
|
45
|
+
expect{ PM::Association.create(@user_attribute, Set.new([@other_op]), @object_attribute, @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
46
|
+
to raise_error(ArgumentError, "expected #{@other_op.unique_identifier} to be in Policy Machine with uuid #{@policy_machine.uuid}; got #{@other_op.policy_machine_uuid}")
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises when third argument is not an object attribute' do
|
50
|
+
expect{ PM::Association.create(@user_attribute, @operation_set, "abc", @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
51
|
+
to raise_error(ArgumentError, "object_attribute_pe must be an ObjectAttribute.")
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'raises when third argument is not in given policy machine' do
|
55
|
+
expect{ PM::Association.create(@user_attribute, @operation_set, @other_oa, @policy_machine.uuid, @policy_machine.policy_machine_storage_adapter) }.
|
56
|
+
to raise_error(ArgumentError, "object_attribute_pe must be in policy machine with uuid #{@policy_machine.uuid}")
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PM::PolicyElement do
|
4
|
+
|
5
|
+
before do
|
6
|
+
class GenericPolicyElement < PM::PolicyElement
|
7
|
+
def initialize
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'raises if allowed_assignee_classes is not overridden in subclass' do
|
13
|
+
expect{ GenericPolicyElement.new.send(:allowed_assignee_classes) }.to raise_error("Must override this method in a subclass")
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'behaves normally when an unknown method is called' do
|
17
|
+
expect{ GenericPolicyElement.new.creat }.to raise_error(NoMethodError, /^undefined method `creat' for #<GenericPolicyElement/)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'policy_machine_storage_adapters/active_record'
|
3
|
+
require 'database_cleaner'
|
4
|
+
|
5
|
+
DatabaseCleaner.strategy = :truncation
|
6
|
+
|
7
|
+
describe 'ActiveRecord' do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
Rails.cache.clear
|
11
|
+
DatabaseCleaner.clean
|
12
|
+
end
|
13
|
+
|
14
|
+
describe PolicyMachineStorageAdapter::ActiveRecord do
|
15
|
+
it_behaves_like 'a policy machine storage adapter with required public methods'
|
16
|
+
it_behaves_like 'a policy machine storage adapter'
|
17
|
+
let(:policy_machine_storage_adapter) { described_class.new }
|
18
|
+
|
19
|
+
describe 'find_all_of_type' do
|
20
|
+
|
21
|
+
it 'warns when filtering on an extra attribute' do
|
22
|
+
policy_machine_storage_adapter.should_receive(:warn).once
|
23
|
+
policy_machine_storage_adapter.find_all_of_type_user(foo: 'bar').should be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'an extra attribute column has been added to the database' do
|
27
|
+
|
28
|
+
it 'does not warn' do
|
29
|
+
policy_machine_storage_adapter.should_not_receive(:warn)
|
30
|
+
policy_machine_storage_adapter.find_all_of_type_user(color: 'red').should be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'only returns elements that match the hash' do
|
34
|
+
policy_machine_storage_adapter.add_object('some_uuid1', 'some_policy_machine_uuid1')
|
35
|
+
policy_machine_storage_adapter.add_object('some_uuid2', 'some_policy_machine_uuid1', color: 'red')
|
36
|
+
policy_machine_storage_adapter.add_object('some_uuid3', 'some_policy_machine_uuid1', color: 'blue')
|
37
|
+
policy_machine_storage_adapter.find_all_of_type_object(color: 'red').should be_one
|
38
|
+
policy_machine_storage_adapter.find_all_of_type_object(color: nil).should be_one
|
39
|
+
policy_machine_storage_adapter.find_all_of_type_object(color: 'green').should be_none
|
40
|
+
policy_machine_storage_adapter.find_all_of_type_object(color: 'blue').map(&:color).should eql(['blue'])
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'PolicyMachine integration with PolicyMachineStorageAdapter::ActiveRecord' do
|
50
|
+
it_behaves_like 'a policy machine' do
|
51
|
+
let(:policy_machine) { PolicyMachine.new(:name => 'ActiveRecord PM', :storage_adapter => PolicyMachineStorageAdapter::ActiveRecord) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'policy_machine_storage_adapters/in_memory'
|
3
|
+
|
4
|
+
describe PolicyMachineStorageAdapter::InMemory do
|
5
|
+
it_behaves_like 'a policy machine storage adapter with required public methods'
|
6
|
+
it_behaves_like 'a policy machine storage adapter'
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'PolicyMachine integration with PolicyMachineStorageAdapter::InMemory' do
|
10
|
+
it_behaves_like 'a policy machine' do
|
11
|
+
let(:policy_machine) { PolicyMachine.new(:name => 'in memory PM', :storage_adapter => PolicyMachineStorageAdapter::InMemory) }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'policy_machine_storage_adapters/neography'
|
3
|
+
|
4
|
+
describe 'Neography' do
|
5
|
+
before(:all) do
|
6
|
+
stop_neo4j
|
7
|
+
reset_neo4j
|
8
|
+
start_neo4j
|
9
|
+
end
|
10
|
+
before(:each) do
|
11
|
+
clean_neo4j
|
12
|
+
end
|
13
|
+
after(:all) do
|
14
|
+
stop_neo4j
|
15
|
+
end
|
16
|
+
|
17
|
+
describe PolicyMachineStorageAdapter::Neography do
|
18
|
+
it_behaves_like 'a policy machine storage adapter with required public methods'
|
19
|
+
it_behaves_like 'a policy machine storage adapter'
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'PolicyMachine integration with PolicyMachineStorageAdapter::Neography' do
|
23
|
+
it_behaves_like 'a policy machine' do
|
24
|
+
let(:policy_machine) { PolicyMachine.new(:name => 'neography PM', :storage_adapter => PolicyMachineStorageAdapter::Neography) }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#assign' do
|
28
|
+
# TODO: storage adapters should be made tolerant to exceptions raised by underlying clients.
|
29
|
+
it 'returns false when relationship cannot be created' do
|
30
|
+
::Neography::Relationship.stub(:create).and_return(nil)
|
31
|
+
policy_machine_storage_adapter = PolicyMachineStorageAdapter::Neography.new
|
32
|
+
src = policy_machine_storage_adapter.add_user('some_uuid1', 'some_policy_machine_uuid1')
|
33
|
+
dst = policy_machine_storage_adapter.add_user_attribute('some_uuid2', 'some_policy_machine_uuid1')
|
34
|
+
policy_machine_storage_adapter.assign(src, dst).should be_false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end if neo4j_exists?
|
39
|
+
|
40
|
+
unless neo4j_exists?
|
41
|
+
warn "Integration testing with neo4j requires that neo4j be installed in the gem's root directory"
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative '../test/test_helper.rb'
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start do
|
5
|
+
add_group 'lib', 'lib'
|
6
|
+
add_filter 'spec'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rspec'
|
10
|
+
require 'debugger'
|
11
|
+
|
12
|
+
SPEC_DIR = File.expand_path("..", __FILE__)
|
13
|
+
lib_dir = File.expand_path("../lib", SPEC_DIR)
|
14
|
+
|
15
|
+
$LOAD_PATH.unshift(lib_dir)
|
16
|
+
$LOAD_PATH.uniq!
|
17
|
+
|
18
|
+
require 'policy_machine'
|
19
|
+
|
20
|
+
Dir["./spec/support/**/*.rb"].each {|f| require f}
|
21
|
+
|
22
|
+
RSpec.configure do |config|
|
23
|
+
config.mock_with :rspec
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This file contains helper methods to manage a neo4j db via neography, for testing purposes.
|
2
|
+
|
3
|
+
def neo4j_exists?
|
4
|
+
system('test -d neo4j')
|
5
|
+
end
|
6
|
+
|
7
|
+
def start_neo4j
|
8
|
+
# Start the server
|
9
|
+
# TODO: sometimes the server doesn't start before tests start to run. Fix!
|
10
|
+
# TODO: probably have to make a separate connection for test db so as not to wipe out dev data.
|
11
|
+
puts "STARTING NEO4J SERVER..."
|
12
|
+
%x[neo4j/bin/neo4j start]
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop_neo4j
|
16
|
+
puts "STOPPING NEO4J SERVER..."
|
17
|
+
%x[neo4j/bin/neo4j stop]
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset_neo4j
|
21
|
+
# Reset the database
|
22
|
+
puts "RESETTING NEO4J DB..."
|
23
|
+
FileUtils.rm_rf("neo4j/data/graph.db")
|
24
|
+
FileUtils.mkdir("neo4j/data/graph.db")
|
25
|
+
|
26
|
+
# Remove log files
|
27
|
+
puts "REMOVING NEO4J LOGS..."
|
28
|
+
FileUtils.rm_rf("neo4j/data/log")
|
29
|
+
FileUtils.mkdir("neo4j/data/log")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Clear all nodes except start node. Should be run before each unit test.
|
33
|
+
def clean_neo4j
|
34
|
+
neo_connection.execute_query("START n0=node(0),nx=node(*) MATCH n0-[r0?]-(),nx-[rx?]-() WHERE nx <> n0 DELETE r0,rx,nx")
|
35
|
+
end
|
36
|
+
|
37
|
+
def neo_connection
|
38
|
+
@neo ||= Neography::Rest.new
|
39
|
+
end
|