couchbase-orm 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +45 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +3 -2
  5. data/CODEOWNERS +1 -0
  6. data/Gemfile +5 -3
  7. data/README.md +237 -31
  8. data/ci/run_couchbase.sh +22 -0
  9. data/couchbase-orm.gemspec +26 -20
  10. data/lib/couchbase-orm/active_record_compat.rb +92 -0
  11. data/lib/couchbase-orm/associations.rb +119 -0
  12. data/lib/couchbase-orm/base.rb +143 -166
  13. data/lib/couchbase-orm/changeable.rb +512 -0
  14. data/lib/couchbase-orm/connection.rb +28 -8
  15. data/lib/couchbase-orm/encrypt.rb +48 -0
  16. data/lib/couchbase-orm/error.rb +17 -2
  17. data/lib/couchbase-orm/inspectable.rb +37 -0
  18. data/lib/couchbase-orm/json_schema/json_validation_error.rb +13 -0
  19. data/lib/couchbase-orm/json_schema/loader.rb +47 -0
  20. data/lib/couchbase-orm/json_schema/validation.rb +18 -0
  21. data/lib/couchbase-orm/json_schema/validator.rb +45 -0
  22. data/lib/couchbase-orm/json_schema.rb +9 -0
  23. data/lib/couchbase-orm/json_transcoder.rb +27 -0
  24. data/lib/couchbase-orm/locale/en.yml +5 -0
  25. data/lib/couchbase-orm/n1ql.rb +133 -0
  26. data/lib/couchbase-orm/persistence.rb +61 -52
  27. data/lib/couchbase-orm/proxies/bucket_proxy.rb +36 -0
  28. data/lib/couchbase-orm/proxies/collection_proxy.rb +52 -0
  29. data/lib/couchbase-orm/proxies/n1ql_proxy.rb +40 -0
  30. data/lib/couchbase-orm/proxies/results_proxy.rb +23 -0
  31. data/lib/couchbase-orm/railtie.rb +6 -17
  32. data/lib/couchbase-orm/relation.rb +249 -0
  33. data/lib/couchbase-orm/strict_loading.rb +21 -0
  34. data/lib/couchbase-orm/timestamps/created.rb +20 -0
  35. data/lib/couchbase-orm/timestamps/updated.rb +21 -0
  36. data/lib/couchbase-orm/timestamps.rb +15 -0
  37. data/lib/couchbase-orm/types/array.rb +32 -0
  38. data/lib/couchbase-orm/types/date.rb +9 -0
  39. data/lib/couchbase-orm/types/date_time.rb +14 -0
  40. data/lib/couchbase-orm/types/encrypted.rb +17 -0
  41. data/lib/couchbase-orm/types/nested.rb +43 -0
  42. data/lib/couchbase-orm/types/timestamp.rb +18 -0
  43. data/lib/couchbase-orm/types.rb +20 -0
  44. data/lib/couchbase-orm/utilities/enum.rb +13 -1
  45. data/lib/couchbase-orm/utilities/has_many.rb +72 -36
  46. data/lib/couchbase-orm/utilities/ignored_properties.rb +15 -0
  47. data/lib/couchbase-orm/utilities/index.rb +18 -20
  48. data/lib/couchbase-orm/utilities/properties_always_exists_in_document.rb +16 -0
  49. data/lib/couchbase-orm/utilities/query_helper.rb +148 -0
  50. data/lib/couchbase-orm/utils.rb +25 -0
  51. data/lib/couchbase-orm/version.rb +1 -1
  52. data/lib/couchbase-orm/views.rb +38 -41
  53. data/lib/couchbase-orm.rb +44 -9
  54. data/lib/ext/query_n1ql.rb +124 -0
  55. data/lib/rails/generators/couchbase_orm/config/templates/couchbase.yml +3 -2
  56. data/spec/associations_spec.rb +219 -50
  57. data/spec/base_spec.rb +296 -14
  58. data/spec/collection_proxy_spec.rb +29 -0
  59. data/spec/connection_spec.rb +27 -0
  60. data/spec/couchbase-orm/active_record_compat_spec.rb +24 -0
  61. data/spec/couchbase-orm/changeable_spec.rb +16 -0
  62. data/spec/couchbase-orm/json_schema/validation_spec.rb +23 -0
  63. data/spec/couchbase-orm/json_schema/validator_spec.rb +13 -0
  64. data/spec/couchbase-orm/timestamps_spec.rb +85 -0
  65. data/spec/couchbase-orm/timestamps_spec_models.rb +36 -0
  66. data/spec/empty-json-schema/.gitkeep +0 -0
  67. data/spec/enum_spec.rb +34 -0
  68. data/spec/has_many_spec.rb +101 -54
  69. data/spec/index_spec.rb +13 -9
  70. data/spec/json-schema/JsonSchemaBaseTest.json +19 -0
  71. data/spec/json-schema/entity_snakecase.json +20 -0
  72. data/spec/json-schema/loader_spec.rb +42 -0
  73. data/spec/json-schema/specific_path.json +20 -0
  74. data/spec/json_schema_spec.rb +178 -0
  75. data/spec/n1ql_spec.rb +193 -0
  76. data/spec/persistence_spec.rb +49 -9
  77. data/spec/relation_nested_spec.rb +88 -0
  78. data/spec/relation_spec.rb +430 -0
  79. data/spec/support.rb +16 -8
  80. data/spec/type_array_spec.rb +52 -0
  81. data/spec/type_encrypted_spec.rb +114 -0
  82. data/spec/type_nested_spec.rb +191 -0
  83. data/spec/type_spec.rb +317 -0
  84. data/spec/utilities/ignored_properties_spec.rb +20 -0
  85. data/spec/utilities/properties_always_exists_in_document_spec.rb +24 -0
  86. data/spec/views_spec.rb +32 -11
  87. metadata +192 -29
@@ -2,81 +2,128 @@
2
2
 
3
3
  require File.expand_path("../support", __FILE__)
4
4
 
5
+ shared_examples "has_many example" do |parameter|
6
+ before :all do
7
+ @context = parameter[:context].to_s
8
+ @rating_test_class = Kernel.const_get("Rating#{@context.camelize}Test".classify)
9
+ @object_test_class = Kernel.const_get("Object#{@context.camelize}Test".classify)
10
+ @object_rating_test_class = Kernel.const_get("ObjectRating#{@context.camelize}Test".classify)
11
+
12
+ @rating_test_class.ensure_design_document!
13
+ @object_test_class.ensure_design_document!
14
+ @object_rating_test_class.ensure_design_document!
15
+
16
+ @rating_test_class.delete_all
17
+ @object_test_class.delete_all
18
+ @object_rating_test_class.delete_all
19
+ end
5
20
 
6
- class ObjectRatingTest < CouchbaseOrm::Base
7
- join :object_test, :rating_test
8
- view :all
9
- end
21
+ after :each do
22
+ @rating_test_class.delete_all
23
+ @object_test_class.delete_all
24
+ @object_rating_test_class.delete_all
25
+ end
10
26
 
11
- class RatingTest < CouchbaseOrm::Base
12
- enum rating: [:awesome, :good, :okay, :bad], default: :okay
13
- belongs_to :object_test
27
+ it "should return matching results" do
28
+ first = @object_test_class.create! name: :bob
29
+ second = @object_test_class.create! name: :jane
14
30
 
15
- has_many :object_tests, through: :object_rating_test
16
- view :all
17
- end
31
+ rate = @rating_test_class.create! rating: :awesome, "object_#{@context}_test": first
32
+ @rating_test_class.create! rating: :bad, "object_#{@context}_test": second
33
+ @rating_test_class.create! rating: :good, "object_#{@context}_test": first
18
34
 
19
- class ObjectTest < CouchbaseOrm::Base
20
- attribute :name, type: String
21
- has_many :rating_tests, dependent: :destroy
35
+ expect(rate.try("object_#{@context}_test_id")).to eq(first.id)
36
+ expect(@rating_test_class.respond_to?(:"find_by_object_#{@context}_test_id")).to be(true)
37
+ expect(first.respond_to?(:"rating_#{@context}_tests")).to be(true)
22
38
 
23
- view :all
24
- end
39
+ docs = first.try(:"rating_#{@context}_tests").collect(&:rating)
25
40
 
41
+ expect(docs).to match_array([1, 2])
26
42
 
27
- describe CouchbaseOrm::HasMany do
28
- before :all do
29
- RatingTest.ensure_design_document!
30
- ObjectTest.ensure_design_document!
31
- ObjectRatingTest.ensure_design_document!
43
+ first.destroy
44
+ expect { @rating_test_class.find rate.id }.to raise_error(Couchbase::Error::DocumentNotFound)
45
+ expect(@rating_test_class.send(:"#{@context}_all").count).to be(1)
32
46
  end
33
47
 
34
- after :each do
35
- ObjectTest.all.stream { |ob| ob.delete }
36
- RatingTest.all.stream { |ob| ob.delete }
37
- ObjectRatingTest.all.stream { |ob| ob.delete }
48
+ it "should work through a join model" do
49
+ first = @object_test_class.create! name: :bob
50
+ second = @object_test_class.create! name: :jane
51
+
52
+ rate1 = @rating_test_class.create! rating: :awesome, "object_#{@context}_test": first
53
+ _rate2 = @rating_test_class.create! rating: :bad, "object_#{@context}_test": second
54
+ _rate3 = @rating_test_class.create! rating: :good, "object_#{@context}_test": first
55
+
56
+ ort = @object_rating_test_class.create! "object_#{@context}_test": first, "rating_#{@context}_test": rate1
57
+ @object_rating_test_class.create! "object_#{@context}_test": second, "rating_#{@context}_test": rate1
58
+
59
+ expect(ort.try(:"rating_#{@context}_test_id".to_sym)).to eq(rate1.id)
60
+ expect(rate1.respond_to?(:"object_#{@context}_tests")).to be(true)
61
+ docs = rate1.try(:"object_#{@context}_tests").collect(&:name)
62
+
63
+ expect(docs).to match_array(['bob', 'jane'])
38
64
  end
39
65
 
40
- it "should return matching results" do
41
- first = ObjectTest.create! name: :bob
42
- second = ObjectTest.create! name: :jane
66
+ it "should work with new objects not yet saved" do
67
+ existing_object = @object_test_class.create! name: :bob
68
+ expect(existing_object.send(:"rating_#{@context}_tests")).to be_empty
43
69
 
44
- rate = RatingTest.create! rating: :awesome, object_test: first
45
- RatingTest.create! rating: :bad, object_test: second
46
- RatingTest.create! rating: :good, object_test: first
70
+ @rating_test_class.create! rating: :good, "object_#{@context}_test": existing_object
71
+
72
+ new_object = @object_test_class.new name: :jane
73
+ expect(new_object.send(:"rating_#{@context}_tests")).to be_empty
74
+ end
47
75
 
48
- expect(rate.object_test_id).to eq(first.id)
49
- expect(RatingTest.respond_to?(:find_by_object_test_id)).to be(true)
50
- expect(first.respond_to?(:rating_tests)).to be(true)
76
+ end
51
77
 
52
- docs = first.rating_tests.collect { |ob|
53
- ob.rating
54
- }
78
+ describe CouchbaseOrm::HasMany do
79
+ context 'with view' do
80
+ class ObjectRatingViewTest < CouchbaseOrm::Base
81
+ join :object_view_test, :rating_view_test
82
+ view :view_all
83
+ end
55
84
 
56
- expect(docs).to eq([1, 2])
85
+ class RatingViewTest < CouchbaseOrm::Base
86
+ enum rating: [:awesome, :good, :okay, :bad], default: :okay
87
+ belongs_to :object_view_test
57
88
 
58
- first.destroy
59
- expect { RatingTest.find rate.id }.to raise_error(::Libcouchbase::Error::KeyNotFound)
60
- expect(RatingTest.all.count).to be(1)
89
+ has_many :object_view_tests, through: :object_rating_view_test
90
+ view :view_all
91
+ end
92
+
93
+ class ObjectViewTest < CouchbaseOrm::Base
94
+ attribute :name, type: String
95
+ has_many :rating_view_tests, dependent: :destroy
96
+
97
+ view :view_all
98
+ end
99
+
100
+ include_examples("has_many example", context: :view)
61
101
  end
62
102
 
63
- it "should work through a join model" do
64
- first = ObjectTest.create! name: :bob
65
- second = ObjectTest.create! name: :jane
103
+ context 'with n1ql' do
104
+ class ObjectRatingN1qlTest < CouchbaseOrm::Base
105
+ join :object_n1ql_test, :rating_n1ql_test
106
+
107
+ n1ql :n1ql_all
108
+ end
109
+
110
+ class RatingN1qlTest < CouchbaseOrm::Base
111
+ enum rating: [:awesome, :good, :okay, :bad], default: :okay
112
+ belongs_to :object_n1ql_test
113
+
114
+ has_many :object_n1ql_tests, through: :object_rating_n1ql_test, type: :n1ql
115
+
116
+ n1ql :n1ql_all
117
+ end
66
118
 
67
- rate1 = RatingTest.create! rating: :awesome, object_test: first
68
- rate2 = RatingTest.create! rating: :bad, object_test: second
69
- rate3 = RatingTest.create! rating: :good, object_test: first
119
+ class ObjectN1qlTest < CouchbaseOrm::Base
120
+ attribute :name, type: String
70
121
 
71
- ort = ObjectRatingTest.create! object_test: first, rating_test: rate1
72
- ObjectRatingTest.create! object_test: second, rating_test: rate1
122
+ has_many :rating_n1ql_tests, dependent: :destroy, type: :n1ql
73
123
 
74
- expect(ort.rating_test_id).to eq(rate1.id)
75
- expect(rate1.respond_to?(:object_tests)).to be(true)
76
- docs = rate1.object_tests.collect { |ob|
77
- ob.name
78
- }
124
+ n1ql :n1ql_all
125
+ end
79
126
 
80
- expect(docs).to eq(['bob', 'jane'])
127
+ include_examples("has_many example", context: :n1ql)
81
128
  end
82
129
  end
data/spec/index_spec.rb CHANGED
@@ -16,15 +16,15 @@ class NoUniqueIndexTest < CouchbaseOrm::Base
16
16
  index :email, presence: false
17
17
  end
18
18
 
19
- class EnumTest < CouchbaseOrm::Base
19
+ class IndexEnumTest < CouchbaseOrm::Base
20
20
  enum visibility: [:group, :authority, :public], default: :authority
21
+ enum color: [:red, :green, :blue]
21
22
  end
22
23
 
23
24
 
24
25
  describe CouchbaseOrm::Index do
25
26
  after :each do
26
- IndexTest.bucket.delete('index_testemail-joe@aca.com')
27
- IndexTest.bucket.delete('index_testemail-')
27
+ IndexTest.all.map(&:destroy)
28
28
  end
29
29
 
30
30
  it "should prevent models being created if they should have unique keys" do
@@ -69,7 +69,7 @@ describe CouchbaseOrm::Index do
69
69
 
70
70
  it "should work with nil values" do
71
71
  joe = IndexTest.create!
72
- expect(IndexTest.find_by_email(nil)).to eq(nil)
72
+ expect(IndexTest.find_by_email(nil)).to eq(joe)
73
73
 
74
74
  joe.email = 'joe@aca.com'
75
75
  joe.save!
@@ -78,31 +78,35 @@ describe CouchbaseOrm::Index do
78
78
  joe.email = nil
79
79
  joe.save!
80
80
  expect(IndexTest.find_by_email('joe@aca.com')).to eq(nil)
81
- expect(IndexTest.find_by_email(nil)).to eq(nil)
81
+ expect(IndexTest.find_by_email(nil)).to eq(joe)
82
82
 
83
83
  joe.destroy
84
84
  end
85
85
 
86
86
  it "should work with enumerators" do
87
87
  # Test symbol
88
- enum = EnumTest.create!(visibility: :public)
88
+ enum = IndexEnumTest.create!(visibility: :public)
89
89
  expect(enum.visibility).to eq(3)
90
90
  enum.destroy
91
91
 
92
92
  # Test number
93
- enum = EnumTest.create!(visibility: 2)
93
+ enum = IndexEnumTest.create!(visibility: 2)
94
94
  expect(enum.visibility).to eq(2)
95
95
  enum.destroy
96
96
 
97
97
  # Test default
98
- enum = EnumTest.create!
98
+ enum = IndexEnumTest.create!
99
99
  expect(enum.visibility).to eq(2)
100
100
  enum.destroy
101
+
102
+ # Test default default
103
+ enum = IndexEnumTest.create!
104
+ expect(enum.color).to eq(1)
101
105
  end
102
106
 
103
107
  it "should not overwrite index's that do not belong to the current model" do
104
108
  joe = NoUniqueIndexTest.create!
105
- expect(NoUniqueIndexTest.find_by_email(nil)).to eq(nil)
109
+ expect(NoUniqueIndexTest.find_by_email(nil)).to eq(joe)
106
110
 
107
111
  joe.email = 'joe@aca.com'
108
112
  joe.save!
@@ -0,0 +1,19 @@
1
+ {
2
+ "type": "object",
3
+ "required": [
4
+ "name"
5
+ ],
6
+ "properties": {
7
+ "id": {
8
+ "type": "string"
9
+ },
10
+ "numb": {
11
+ "type": "integer",
12
+ "format": "uint32",
13
+ "minimum": 3.0
14
+ },
15
+ "name": {
16
+ "type": "string"
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "type": "object",
3
+ "required": [
4
+ "value"
5
+ ],
6
+ "properties": {
7
+ "value": {
8
+ "$ref": "#/definitions/ValueType"
9
+ }
10
+ },
11
+ "definitions": {
12
+ "ValueType": {
13
+ "type": "string",
14
+ "enum": [
15
+ "value_one",
16
+ "value_two"
17
+ ]
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../../support', __FILE__)
2
+ require 'couchbase-orm/json_schema/loader'
3
+
4
+ RSpec.describe CouchbaseOrm::JsonSchema::Loader do
5
+ let(:loader) { described_class.send(:new, "#{Dir.pwd}/spec/json-schema") }
6
+
7
+ describe '#extract_type' do
8
+ it 'returns the type from the entity' do
9
+ entity = { type: 'entity_snakecase' }
10
+ expect(loader.extract_type(entity)).to eq('entity_snakecase')
11
+
12
+ expect(loader.get_json_schema!(entity)).not_to be_nil
13
+ end
14
+ end
15
+
16
+ describe '#get_json_schema' do
17
+ context 'when schemas are present and document type exists' do
18
+ let(:schemas) { { 'user' => { 'properties' => { 'name' => { 'type' => 'string' } } } } }
19
+
20
+ before do
21
+ allow(loader).to receive(:schemas).and_return(schemas)
22
+ end
23
+
24
+ it 'returns the schema for the given document type' do
25
+ entity = { type: 'user' }
26
+ expect(loader.get_json_schema!(entity)).to eq(schemas['user'])
27
+ end
28
+
29
+ it 'raise error if no schema found for the document type' do
30
+ entity = { type: 'post' }
31
+ expect { loader.get_json_schema!(entity) }.to raise_error(CouchbaseOrm::JsonSchema::Loader::Error, /Schema not found for post in .*\/json-schema/)
32
+ end
33
+ end
34
+
35
+ context 'when schemas are not present or document type is missing' do
36
+ it 'returns nil' do
37
+ entity = { type: 'user' }
38
+ expect { loader.get_json_schema!(entity) }.to raise_error(CouchbaseOrm::JsonSchema::Loader::Error, /Schema not found for user in .*\/json-schema/)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,20 @@
1
+ {
2
+ "type": "object",
3
+ "required": [
4
+ "foo"
5
+ ],
6
+ "properties": {
7
+ "foo": {
8
+ "$ref": "#/definitions/ValueType"
9
+ }
10
+ },
11
+ "definitions": {
12
+ "ValueType": {
13
+ "type": "string",
14
+ "enum": [
15
+ "foo_one",
16
+ "foo_two"
17
+ ]
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true, encoding: ASCII-8BIT
2
+
3
+ require File.expand_path("../support", __FILE__)
4
+
5
+ class JsonSchemaBaseTest < CouchbaseOrm::Base
6
+ attribute :name, :string
7
+ attribute :numb, :integer
8
+
9
+ design_document('JsonSchemaBaseTest')
10
+ validate_json_schema
11
+ end
12
+
13
+ class UnknownTest < CouchbaseOrm::Base
14
+ attribute :test, :boolean
15
+ validate_json_schema
16
+ end
17
+
18
+ class EntitySnakecase < CouchbaseOrm::Base
19
+ attribute :value, :string
20
+ validate_json_schema
21
+ end
22
+
23
+ describe CouchbaseOrm::JsonSchema::Loader do
24
+
25
+ after(:each) do
26
+ reset_schemas
27
+ end
28
+
29
+ context "with validation enabled on model" do
30
+
31
+ it "With no existing dir " do
32
+ load_schemas("../dontexist")
33
+ expect { CouchbaseOrm::JsonSchema::Loader.instance.get_json_schema!({ :type => "Unknown" }) }.to raise_error CouchbaseOrm::JsonSchema::Loader::Error, /Schema not found for Unknown in .*\/dontexist/
34
+ end
35
+
36
+ it "Without existing json " do
37
+ load_schemas("../empty-json-schema")
38
+ expect { CouchbaseOrm::JsonSchema::Loader.instance.get_json_schema!({ :type => "Unknown" }) }.to raise_error CouchbaseOrm::JsonSchema::Loader::Error, /Schema not found for Unknown in .*\/empty-json-schema/
39
+ end
40
+
41
+ it "with schema " do
42
+ load_schemas("../json-schema")
43
+ expect(CouchbaseOrm::JsonSchema::Loader.instance.get_json_schema!({ :type => "JsonSchemaBaseTest" })).to include('"name"')
44
+ expect { CouchbaseOrm::JsonSchema::Loader.instance.get_json_schema!({ :type => "Unknown" }) }.to raise_error CouchbaseOrm::JsonSchema::Loader::Error, /Schema not found for Unknown in .*\/json-schema/
45
+ end
46
+ end
47
+
48
+ describe CouchbaseOrm::JsonSchema::Validator do
49
+ after(:each) do
50
+ reset_schemas
51
+ end
52
+
53
+ it "creation ok" do
54
+ load_schemas("../json-schema")
55
+ base = EntitySnakecase.create!(value: "value_one")
56
+ base.delete
57
+ end
58
+
59
+ it "creation ko" do
60
+ load_schemas("../json-schema")
61
+ expect { EntitySnakecase.create!(value: "value_1") }.to raise_error CouchbaseOrm::JsonSchema::JsonValidationError
62
+ end
63
+
64
+ it "update ok" do
65
+ load_schemas("../json-schema")
66
+ base = EntitySnakecase.create!(value: "value_one")
67
+ base.value = "value_two"
68
+ base.save
69
+ base.delete
70
+ end
71
+
72
+ it "update ko" do
73
+ load_schemas("../json-schema")
74
+ base = EntitySnakecase.create!(value: "value_one")
75
+ base.value = "value_2"
76
+ expect { base.save }.to raise_error CouchbaseOrm::JsonSchema::JsonValidationError
77
+ base.delete
78
+ end
79
+
80
+ it "creation ok with design_document" do
81
+ load_schemas("../json-schema")
82
+ base = JsonSchemaBaseTest.create!(name: "dsdsd", numb: 3)
83
+ base.delete
84
+ end
85
+
86
+ it "creation ko with design_document" do
87
+ load_schemas("../json-schema")
88
+ expect { JsonSchemaBaseTest.create!(name: "dsdsd", numb: 2) }.to raise_error CouchbaseOrm::JsonSchema::JsonValidationError
89
+ end
90
+
91
+ it "update ok with design_document" do
92
+ load_schemas("../json-schema")
93
+ base = JsonSchemaBaseTest.create!(name: "dsdsd", numb: 3)
94
+ base.numb = 4
95
+ base.save
96
+ base.delete
97
+ end
98
+
99
+ it "update ok with design_document" do
100
+ load_schemas("../json-schema")
101
+ base = JsonSchemaBaseTest.create!(name: "dsdsd", numb: 3)
102
+ base.numb = 2
103
+ expect { base.save }.to raise_error CouchbaseOrm::JsonSchema::JsonValidationError
104
+ base.delete
105
+ end
106
+
107
+ it 'prevent saving with entity not define in schema files and raise' do
108
+ load_schemas("../json-schema")
109
+ expect { UnknownTest.create!(test: true) }.to raise_error CouchbaseOrm::JsonSchema::Loader::Error, /Schema not found for unknown_test in .*\/json-schema/
110
+ end
111
+
112
+ it 'prevent updating with entity not define in schema files and raise' do
113
+ load_schemas("../json-schema")
114
+ base = JsonSchemaBaseTest.create!(name: 'Juju', numb: 3)
115
+ reset_schemas
116
+ base.name = 'Pierre'
117
+ expect { base.save }.to raise_error CouchbaseOrm::JsonSchema::Loader::Error, "Schema not found for JsonSchemaBaseTest in db/cborm_schemas/JsonSchemaBaseTest.json"
118
+ base.delete
119
+ end
120
+ end
121
+
122
+ context "with validation disabled on model" do
123
+ let!(:original_config) { EntitySnakecase.instance_variable_get(:@json_validation_config) }
124
+ before do
125
+ EntitySnakecase.instance_variable_set(:@json_validation_config, {enabled: false})
126
+ end
127
+ after do
128
+ EntitySnakecase.instance_variable_set(:@json_validation_config, original_config)
129
+ end
130
+ it "does not validate schema (even if scehma exists and is not valid)" do
131
+ load_schemas("../json-schema")
132
+ base = EntitySnakecase.create!(value: "value_one")
133
+ base.value = "value_2"
134
+ expect { base.save }.not_to raise_error CouchbaseOrm::JsonSchema::JsonValidationError
135
+ base.delete
136
+ end
137
+
138
+ end
139
+
140
+ context "with logger mode on model" do
141
+ before do
142
+ EntitySnakecase.instance_variable_set(:@json_validation_config, {enabled: true, mode: :logger})
143
+ end
144
+ it "does not raise error but log it" do
145
+ load_schemas("../json-schema")
146
+ base = EntitySnakecase.create!(value: "value_one")
147
+ base.value = "value_2"
148
+ expect(CouchbaseOrm.logger).to receive(:error)
149
+ base.save
150
+ base.delete
151
+ end
152
+ end
153
+
154
+ context "when schema_path is set on model" do
155
+ let!(:original_config) { EntitySnakecase.instance_variable_get(:@json_validation_config) }
156
+ before do
157
+ EntitySnakecase.instance_variable_set(:@json_validation_config, {enabled: true, mode: :strict, schema_path: 'spec/json-schema/specific_path.json'})
158
+ end
159
+ after do
160
+ EntitySnakecase.instance_variable_set(:@json_validation_config, original_config)
161
+ end
162
+ it "loads schema from the specified path" do
163
+ expect { EntitySnakecase.create!(value: "value_one") }.to raise_error CouchbaseOrm::JsonSchema::JsonValidationError, /did not contain a required property of 'foo' in schema/
164
+ end
165
+ end
166
+ end
167
+
168
+
169
+ # TODO : extract following helpers methods elsewhere
170
+
171
+ def load_schemas(file_relative_path)
172
+ CouchbaseOrm::JsonSchema::Loader.instance.send(:instance_variable_set, :@schemas_directory, File.expand_path(file_relative_path, __FILE__))
173
+ end
174
+
175
+ def reset_schemas
176
+ CouchbaseOrm::JsonSchema::Loader.instance.send(:instance_variable_set, :@schemas_directory, CouchbaseOrm::JsonSchema::Loader::JSON_SCHEMAS_PATH)
177
+ CouchbaseOrm::JsonSchema::Loader.instance.instance_variable_get(:@schemas).clear
178
+ end