elasticsearch-persistence 5.1.0 → 6.0.0.pre

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Gemfile +9 -0
  4. data/README.md +164 -323
  5. data/Rakefile +8 -8
  6. data/elasticsearch-persistence.gemspec +4 -5
  7. data/lib/elasticsearch/persistence.rb +2 -110
  8. data/lib/elasticsearch/persistence/repository.rb +212 -53
  9. data/lib/elasticsearch/persistence/repository/dsl.rb +94 -0
  10. data/lib/elasticsearch/persistence/repository/find.rb +27 -10
  11. data/lib/elasticsearch/persistence/repository/response/results.rb +17 -5
  12. data/lib/elasticsearch/persistence/repository/search.rb +15 -4
  13. data/lib/elasticsearch/persistence/repository/serialize.rb +65 -7
  14. data/lib/elasticsearch/persistence/repository/store.rb +38 -44
  15. data/lib/elasticsearch/persistence/version.rb +1 -1
  16. data/spec/repository/find_spec.rb +179 -0
  17. data/spec/repository/response/results_spec.rb +105 -0
  18. data/spec/repository/search_spec.rb +181 -0
  19. data/spec/repository/serialize_spec.rb +53 -0
  20. data/spec/repository/store_spec.rb +327 -0
  21. data/spec/repository_spec.rb +716 -0
  22. data/spec/spec_helper.rb +28 -0
  23. metadata +25 -80
  24. data/lib/elasticsearch/persistence/client.rb +0 -51
  25. data/lib/elasticsearch/persistence/model.rb +0 -153
  26. data/lib/elasticsearch/persistence/model/base.rb +0 -87
  27. data/lib/elasticsearch/persistence/model/errors.rb +0 -8
  28. data/lib/elasticsearch/persistence/model/find.rb +0 -180
  29. data/lib/elasticsearch/persistence/model/rails.rb +0 -47
  30. data/lib/elasticsearch/persistence/model/store.rb +0 -254
  31. data/lib/elasticsearch/persistence/model/utils.rb +0 -0
  32. data/lib/elasticsearch/persistence/repository/class.rb +0 -71
  33. data/lib/elasticsearch/persistence/repository/naming.rb +0 -115
  34. data/lib/rails/generators/elasticsearch/model/model_generator.rb +0 -21
  35. data/lib/rails/generators/elasticsearch/model/templates/model.rb.tt +0 -9
  36. data/lib/rails/generators/elasticsearch_generator.rb +0 -2
  37. data/test/integration/model/model_basic_test.rb +0 -238
  38. data/test/integration/repository/custom_class_test.rb +0 -85
  39. data/test/integration/repository/customized_class_test.rb +0 -82
  40. data/test/integration/repository/default_class_test.rb +0 -116
  41. data/test/integration/repository/virtus_model_test.rb +0 -118
  42. data/test/test_helper.rb +0 -55
  43. data/test/unit/model_base_test.rb +0 -72
  44. data/test/unit/model_find_test.rb +0 -153
  45. data/test/unit/model_gateway_test.rb +0 -101
  46. data/test/unit/model_rails_test.rb +0 -112
  47. data/test/unit/model_store_test.rb +0 -576
  48. data/test/unit/persistence_test.rb +0 -32
  49. data/test/unit/repository_class_test.rb +0 -51
  50. data/test/unit/repository_client_test.rb +0 -32
  51. data/test/unit/repository_find_test.rb +0 -388
  52. data/test/unit/repository_indexing_test.rb +0 -37
  53. data/test/unit/repository_module_test.rb +0 -146
  54. data/test/unit/repository_naming_test.rb +0 -146
  55. data/test/unit/repository_response_results_test.rb +0 -98
  56. data/test/unit/repository_search_test.rb +0 -117
  57. data/test/unit/repository_serialize_test.rb +0 -57
  58. data/test/unit/repository_store_test.rb +0 -303
@@ -1,72 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'elasticsearch/persistence/model'
4
- require 'elasticsearch/persistence/model/rails'
5
-
6
- class Elasticsearch::Persistence::ModelBaseTest < Test::Unit::TestCase
7
- context "The model" do
8
- setup do
9
- class DummyBaseModel
10
- include Elasticsearch::Persistence::Model
11
-
12
- attribute :name, String
13
- end
14
- end
15
-
16
- should "respond to id, _id, _index, _type and _version" do
17
- model = DummyBaseModel.new
18
-
19
- [:id, :_id, :_index, :_type, :_version].each { |method| assert_respond_to model, method }
20
- end
21
-
22
- should "set the ID from attributes during initialization" do
23
- model = DummyBaseModel.new id: 1
24
- assert_equal 1, model.id
25
-
26
- model = DummyBaseModel.new 'id' => 2
27
- assert_equal 2, model.id
28
- end
29
-
30
- should "set the ID using setter method" do
31
- model = DummyBaseModel.new id: 1
32
- assert_equal 1, model.id
33
-
34
- model.id = 2
35
- assert_equal 2, model.id
36
- end
37
-
38
- should "have ID in attributes" do
39
- model = DummyBaseModel.new id: 1, name: 'Test'
40
- assert_equal 1, model.attributes[:id]
41
- end
42
-
43
- should "have the customized inspect method" do
44
- model = DummyBaseModel.new name: 'Test'
45
- assert_match /name\: "Test"/, model.inspect
46
- end
47
-
48
- context "with custom document_type" do
49
- setup do
50
- @model = DummyBaseModel
51
- @gateway = mock()
52
- @mapping = mock()
53
- @model.stubs(:gateway).returns(@gateway)
54
- @gateway.stubs(:mapping).returns(@mapping)
55
- @document_type = 'dummybase'
56
- end
57
-
58
- should "forward the argument to mapping" do
59
- @gateway.expects(:document_type).with(@document_type).once
60
- @mapping.expects(:type=).with(@document_type).once
61
- @model.document_type @document_type
62
- end
63
-
64
- should "return the value from the gateway" do
65
- @gateway.expects(:document_type).once.returns(@document_type)
66
- @mapping.expects(:type=).never
67
- returned_type = @model.document_type
68
- assert_equal @document_type, returned_type
69
- end
70
- end
71
- end
72
- end
@@ -1,153 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'active_model'
4
- require 'virtus'
5
-
6
- require 'elasticsearch/persistence/model/errors'
7
- require 'elasticsearch/persistence/model/find'
8
-
9
- class Elasticsearch::Persistence::ModelFindTest < Test::Unit::TestCase
10
- context "The model find module," do
11
-
12
- class DummyFindModel
13
- include ActiveModel::Naming
14
- include ActiveModel::Conversion
15
- include ActiveModel::Serialization
16
- include ActiveModel::Serializers::JSON
17
- include ActiveModel::Validations
18
-
19
- include Virtus.model
20
-
21
- extend Elasticsearch::Persistence::Model::Find::ClassMethods
22
-
23
- extend ActiveModel::Callbacks
24
- define_model_callbacks :create, :save, :update, :destroy
25
- define_model_callbacks :find, :touch, only: :after
26
-
27
- attribute :title, String
28
- attribute :count, Integer, default: 0
29
- attribute :created_at, DateTime, default: lambda { |o,a| Time.now.utc }
30
- attribute :updated_at, DateTime, default: lambda { |o,a| Time.now.utc }
31
- end
32
-
33
- setup do
34
- @gateway = stub(client: stub(), index_name: 'foo', document_type: 'bar')
35
- DummyFindModel.stubs(:gateway).returns(@gateway)
36
-
37
- DummyFindModel.stubs(:index_name).returns('foo')
38
- DummyFindModel.stubs(:document_type).returns('bar')
39
-
40
- @response = MultiJson.load <<-JSON
41
- {
42
- "took": 14,
43
- "timed_out": false,
44
- "_shards": {
45
- "total": 5,
46
- "successful": 5,
47
- "failed": 0
48
- },
49
- "hits": {
50
- "total": 1,
51
- "max_score": 1.0,
52
- "hits": [
53
- {
54
- "_index": "dummy",
55
- "_type": "dummy",
56
- "_id": "abc123",
57
- "_score": 1.0,
58
- "_source": {
59
- "name": "TEST"
60
- }
61
- }
62
- ]
63
- }
64
- }
65
- JSON
66
- end
67
-
68
- should "find all records" do
69
- DummyFindModel
70
- .stubs(:search)
71
- .with({ query: { match_all: {} }, size: 10_000 }, {})
72
- .returns(@response)
73
-
74
- DummyFindModel.all
75
- end
76
-
77
- should "pass options when finding all records" do
78
- DummyFindModel
79
- .expects(:search)
80
- .with({ query: { match: { title: 'test' } }, size: 10_000 }, { routing: 'abc123' })
81
- .returns(@response)
82
-
83
- DummyFindModel.all( { query: { match: { title: 'test' } } }, { routing: 'abc123' } )
84
- end
85
-
86
- context "finding via scroll" do
87
- setup do
88
- @gateway
89
- .expects(:deserialize)
90
- .returns('_source' => {'foo' => 'bar'})
91
- .at_least_once
92
-
93
- # 1. Initial batch of documents and the scroll_id
94
- @gateway.client
95
- .expects(:search)
96
- .with do |arguments|
97
- assert_equal 'foo', arguments[:index]
98
- assert_equal 'bar', arguments[:type]
99
- true
100
- end
101
- .returns(MultiJson.load('{"_scroll_id":"abc123==", "hits":{"hits":[{"_source":{"foo":"bar_1"}}]}}'))
102
-
103
- # 2. Second batch of documents and the scroll_id
104
- # 3. Last, empty batch of documents
105
- @gateway.client
106
- .expects(:scroll)
107
- .twice
108
- .returns(MultiJson.load('{"_scroll_id":"abc456==", "hits":{"hits":[{"_source":{"foo":"bar_2"}}]}}'))
109
- .then
110
- .returns(MultiJson.load('{"_scroll_id":"abc789==", "hits":{"hits":[]}}'))
111
- end
112
-
113
- should "find all records in batches" do
114
- @doc = nil
115
- result = DummyFindModel.find_in_batches { |batch| @doc = batch.first['_source']['foo'] }
116
-
117
- assert_equal 'abc789==', result
118
- assert_equal 'bar', @doc
119
- end
120
-
121
- should "return an Enumerator for find in batches" do
122
- @doc = nil
123
- assert_nothing_raised do
124
- e = DummyFindModel.find_in_batches
125
- assert_instance_of Enumerator, e
126
-
127
- e.each { |batch| @doc = batch.first['_source']['foo'] }
128
- assert_equal 'bar', @doc
129
- end
130
- end
131
-
132
- should "find each" do
133
- @doc = nil
134
- result = DummyFindModel.find_each { |doc| @doc = doc['_source']['foo'] }
135
-
136
- assert_equal 'abc789==', result
137
- assert_equal 'bar', @doc
138
- end
139
-
140
- should "return an Enumerator for find each" do
141
- @doc = nil
142
- assert_nothing_raised do
143
- e = DummyFindModel.find_each
144
- assert_instance_of Enumerator, e
145
-
146
- e.each { |doc| @doc = doc['_source']['foo'] }
147
- assert_equal 'bar', @doc
148
- end
149
- end
150
- end
151
-
152
- end
153
- end
@@ -1,101 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'elasticsearch/persistence/model'
4
- require 'elasticsearch/persistence/model/rails'
5
-
6
- class Elasticsearch::Persistence::ModelGatewayTest < Test::Unit::TestCase
7
- context "The model gateway" do
8
- setup do
9
- class DummyGatewayModel
10
- include Elasticsearch::Persistence::Model
11
- end
12
- end
13
-
14
- teardown do
15
- Elasticsearch::Persistence::ModelGatewayTest.__send__ :remove_const, :DummyGatewayModel \
16
- rescue NameError; nil
17
- end
18
-
19
- should "be accessible" do
20
- assert_instance_of Elasticsearch::Persistence::Repository::Class, DummyGatewayModel.gateway
21
-
22
- $a = 0
23
- DummyGatewayModel.gateway { $a += 1 }
24
- assert_equal 1, $a
25
-
26
- @b = 0
27
- def run!; DummyGatewayModel.gateway { |g| @b += 1 }; end
28
- run!
29
- assert_equal 1, @b
30
-
31
- assert_equal DummyGatewayModel, DummyGatewayModel.gateway.klass
32
- end
33
-
34
- should "define common attributes" do
35
- d = DummyGatewayModel.new
36
-
37
- assert_respond_to d, :updated_at
38
- assert_respond_to d, :created_at
39
- end
40
-
41
- should "allow to configure settings" do
42
- DummyGatewayModel.settings(number_of_shards: 1)
43
-
44
- assert_equal 1, DummyGatewayModel.settings.to_hash[:number_of_shards]
45
- end
46
-
47
- should "allow to configure mappings" do
48
- DummyGatewayModel.mapping { indexes :name, analyzer: 'snowball' }
49
-
50
- assert_equal 'snowball',
51
- DummyGatewayModel.mapping.to_hash[:dummy_gateway_model][:properties][:name][:analyzer]
52
- end
53
-
54
- should "configure the mapping via attribute" do
55
- DummyGatewayModel.attribute :name, String, mapping: { analyzer: 'snowball' }
56
-
57
- assert_respond_to DummyGatewayModel, :name
58
- assert_equal 'snowball',
59
- DummyGatewayModel.mapping.to_hash[:dummy_gateway_model][:properties][:name][:analyzer]
60
- end
61
-
62
- should "configure the mapping via an attribute block" do
63
- DummyGatewayModel.attribute :name, String do
64
- indexes :name, analyzer: 'custom'
65
- end
66
-
67
- assert_respond_to DummyGatewayModel, :name
68
- assert_equal 'custom',
69
- DummyGatewayModel.mapping.to_hash[:dummy_gateway_model][:properties][:name][:analyzer]
70
- end
71
-
72
- should "properly look up types for classes" do
73
- assert_equal 'text', Elasticsearch::Persistence::Model::Utils::lookup_type(String)
74
- assert_equal 'integer', Elasticsearch::Persistence::Model::Utils::lookup_type(Integer)
75
- assert_equal 'float', Elasticsearch::Persistence::Model::Utils::lookup_type(Float)
76
- assert_equal 'date', Elasticsearch::Persistence::Model::Utils::lookup_type(Date)
77
- assert_equal 'boolean', Elasticsearch::Persistence::Model::Utils::lookup_type(Virtus::Attribute::Boolean)
78
- end
79
-
80
- should "remove IDs from hash when serializing" do
81
- assert_equal( {foo: 'bar'}, DummyGatewayModel.gateway.serialize(id: '123', foo: 'bar') )
82
- end
83
-
84
- should "set IDs from hash when deserializing" do
85
- assert_equal 'abc123', DummyGatewayModel.gateway.deserialize('_id' => 'abc123', '_source' => {}).id
86
- end
87
-
88
- should "set @persisted variable from hash when deserializing" do
89
- assert DummyGatewayModel.gateway.deserialize('_id' => 'abc123', '_source' => {}).instance_variable_get(:@persisted)
90
- end
91
-
92
- should "allow accessing the raw _source" do
93
- assert_equal 'bar', DummyGatewayModel.gateway.deserialize('_source' => { 'foo' => 'bar' })._source['foo']
94
- end
95
-
96
- should "allow to access the raw hit from results as Hashie::Mash" do
97
- assert_equal 0.42, DummyGatewayModel.gateway.deserialize('_score' => 0.42, '_source' => {}).hit._score
98
- end
99
-
100
- end
101
- end
@@ -1,112 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'elasticsearch/persistence/model'
4
- require 'elasticsearch/persistence/model/rails'
5
-
6
- require 'rails'
7
- require 'action_controller/railtie'
8
- require 'action_view/railtie'
9
-
10
- class ::MyRailsModel
11
- include Elasticsearch::Persistence::Model
12
- include Elasticsearch::Persistence::Model::Rails
13
-
14
- attribute :name, String, mapping: { analyzer: 'english' }
15
- attribute :published_at, DateTime
16
- attribute :published_on, Date
17
- end
18
-
19
- class Application < Rails::Application
20
- config.eager_load = false
21
- config.root = File.dirname(File.expand_path('../../../tmp', __FILE__))
22
- config.logger = Logger.new($stderr)
23
-
24
- routes.append do
25
- resources :my_rails_models
26
- end
27
- end
28
-
29
- class ApplicationController < ActionController::Base
30
- include Application.routes.url_helpers
31
- include ActionController::UrlFor
32
- end
33
- ApplicationController.default_url_options = { host: 'localhost' }
34
- ApplicationController._routes.append { resources :my_rails_models }
35
-
36
- class MyRailsModelController < ApplicationController; end
37
-
38
- Application.initialize!
39
-
40
- class Elasticsearch::Persistence::ModelRailsTest < Test::Unit::TestCase
41
- context "The model in a Rails application" do
42
-
43
- should "generate proper URLs and paths" do
44
- model = MyRailsModel.new name: 'Test'
45
- model.stubs(:id).returns(1)
46
- model.stubs(:persisted?).returns(true)
47
-
48
- controller = MyRailsModelController.new
49
- controller.request = ActionDispatch::Request.new({})
50
-
51
- assert_equal 'http://localhost/my_rails_models/1', controller.url_for(model)
52
- assert_equal '/my_rails_models/1/edit', controller.edit_my_rails_model_path(model)
53
- end
54
-
55
- should "generate a link" do
56
- class MyView; include ActionView::Helpers::UrlHelper; end
57
-
58
- model = MyRailsModel.new name: 'Test'
59
- view = MyView.new
60
- view.expects(:url_for).with(model).returns('foo/bar')
61
-
62
- assert_equal '<a href="foo/bar">Show</a>', view.link_to('Show', model)
63
- end
64
-
65
- should "parse DateTime from Rails forms" do
66
- params = { "published_at(1i)"=>"2014",
67
- "published_at(2i)"=>"1",
68
- "published_at(3i)"=>"1",
69
- "published_at(4i)"=>"12",
70
- "published_at(5i)"=>"00"
71
- }
72
-
73
- assert_equal '2014-1-1- 12:00:',
74
- Elasticsearch::Persistence::Model::Rails.__convert_rails_dates(params)['published_at']
75
-
76
- m = MyRailsModel.new params
77
- assert_equal "2014-01-01T12:00:00+00:00", m.published_at.iso8601
78
- end
79
-
80
- should "parse Date from Rails forms" do
81
- params = { "published_on(1i)"=>"2014",
82
- "published_on(2i)"=>"1",
83
- "published_on(3i)"=>"1"
84
- }
85
-
86
- assert_equal '2014-1-1-',
87
- Elasticsearch::Persistence::Model::Rails.__convert_rails_dates(params)['published_on']
88
-
89
-
90
- m = MyRailsModel.new params
91
- assert_equal "2014-01-01", m.published_on.iso8601
92
- end
93
-
94
- context "when updating," do
95
- should "pass the options to gateway" do
96
- model = MyRailsModel.new name: 'Test'
97
- model.stubs(:persisted?).returns(true)
98
-
99
- model.class.gateway
100
- .expects(:update)
101
- .with do |object, options|
102
- assert_equal 'ABC', options[:routing]
103
- true
104
- end
105
- .returns({'_id' => 'abc123'})
106
-
107
- assert model.update( { title: 'UPDATED' }, { routing: 'ABC' } )
108
- end
109
- end
110
-
111
- end
112
- end
@@ -1,576 +0,0 @@
1
- require 'test_helper'
2
-
3
- require 'active_model'
4
- require 'virtus'
5
-
6
- require 'elasticsearch/persistence/model/base'
7
- require 'elasticsearch/persistence/model/errors'
8
- require 'elasticsearch/persistence/model/store'
9
-
10
- class Elasticsearch::Persistence::ModelStoreTest < Test::Unit::TestCase
11
- context "The model store module," do
12
-
13
- class DummyStoreModel
14
- include ActiveModel::Naming
15
- include ActiveModel::Conversion
16
- include ActiveModel::Serialization
17
- include ActiveModel::Serializers::JSON
18
- include ActiveModel::Validations
19
-
20
- include Virtus.model
21
-
22
- include Elasticsearch::Persistence::Model::Base::InstanceMethods
23
- extend Elasticsearch::Persistence::Model::Store::ClassMethods
24
- include Elasticsearch::Persistence::Model::Store::InstanceMethods
25
-
26
- extend ActiveModel::Callbacks
27
- define_model_callbacks :create, :save, :update, :destroy
28
- define_model_callbacks :find, :touch, only: :after
29
-
30
- attribute :title, String
31
- attribute :count, Integer, default: 0
32
- attribute :created_at, DateTime, default: lambda { |o,a| Time.now.utc }
33
- attribute :updated_at, DateTime, default: lambda { |o,a| Time.now.utc }
34
- end
35
-
36
- setup do
37
- @shoulda_subject = DummyStoreModel.new title: 'Test'
38
- @gateway = stub
39
- DummyStoreModel.stubs(:gateway).returns(@gateway)
40
- end
41
-
42
- teardown do
43
- Elasticsearch::Persistence::ModelStoreTest.__send__ :remove_const, :DummyStoreModelWithCallback \
44
- rescue NameError; nil
45
- end
46
-
47
- should "be new_record" do
48
- assert subject.new_record?
49
- end
50
-
51
- context "when creating," do
52
- should "save the object and return it" do
53
- DummyStoreModel.any_instance.expects(:save).returns({'_id' => 'X'})
54
-
55
- assert_instance_of DummyStoreModel, DummyStoreModel.create(title: 'Test')
56
- end
57
-
58
- should "execute the callbacks" do
59
- DummyStoreModelWithCallback = Class.new(DummyStoreModel)
60
- @gateway.expects(:save).returns({'_id' => 'X'})
61
-
62
- DummyStoreModelWithCallback.after_create { $stderr.puts "CREATED" }
63
- DummyStoreModelWithCallback.after_save { $stderr.puts "SAVED" }
64
-
65
- $stderr.expects(:puts).with('CREATED')
66
- $stderr.expects(:puts).with('SAVED')
67
-
68
- DummyStoreModelWithCallback.create name: 'test'
69
- end
70
- end
71
-
72
- context "when saving," do
73
- should "save the model" do
74
- @gateway
75
- .expects(:save)
76
- .with do |object, options|
77
- assert_equal subject, object
78
- assert_equal nil, options[:id]
79
- true
80
- end
81
- .returns({'_id' => 'abc123'})
82
-
83
- assert subject.save
84
- end
85
-
86
- should "save the model and set the ID" do
87
- @gateway
88
- .expects(:save)
89
- .returns({'_id' => 'abc123'})
90
-
91
- assert_nil subject.id
92
-
93
- subject.save
94
- assert_equal 'abc123', subject.id
95
- end
96
-
97
- should "save the model and update the timestamp" do
98
- now = Time.parse('2014-01-01T00:00:00Z')
99
- Time.expects(:now).returns(now).at_least_once
100
- @gateway
101
- .expects(:save)
102
- .returns({'_id' => 'abc123'})
103
-
104
- subject.save
105
- assert_equal Time.parse('2014-01-01T00:00:00Z'), subject.updated_at
106
- end
107
-
108
- should "not save an invalid model" do
109
- @gateway
110
- .expects(:save)
111
- .never
112
-
113
- subject.instance_eval do
114
- def valid?; false; end;
115
- end
116
-
117
- assert ! subject.save
118
- assert ! subject.persisted?
119
- end
120
-
121
- should "skip the validation with the :validate option" do
122
- @gateway
123
- .expects(:save)
124
- .with do |object, options|
125
- assert_equal subject, object
126
- assert_equal nil, options[:id]
127
- true
128
- end
129
- .returns({'_id' => 'abc123'})
130
-
131
- subject.instance_eval do
132
- def valid?; false; end;
133
- end
134
-
135
- assert subject.save validate: false
136
- assert subject.persisted?
137
- end
138
-
139
- should "pass the options to gateway" do
140
- @gateway
141
- .expects(:save)
142
- .with do |object, options|
143
- assert_equal 'ABC', options[:routing]
144
- true
145
- end
146
- .returns({'_id' => 'abc123'})
147
-
148
- assert subject.save routing: 'ABC'
149
- end
150
-
151
- should "return the response" do
152
- @gateway
153
- .expects(:save)
154
- .returns('FOOBAR')
155
-
156
- assert_equal 'FOOBAR', subject.save
157
- end
158
-
159
- should "execute the callbacks" do
160
- @gateway.expects(:save).returns({'_id' => 'abc'})
161
- DummyStoreModelWithCallback = Class.new(DummyStoreModel)
162
-
163
- DummyStoreModelWithCallback.after_save { $stderr.puts "SAVED" }
164
-
165
- $stderr.expects(:puts).with('SAVED')
166
- d = DummyStoreModelWithCallback.new name: 'Test'
167
- d.save
168
- end
169
-
170
- should "save the model to its own index" do
171
- @gateway.expects(:save)
172
- .with do |model, options|
173
- assert_equal 'my_custom_index', options[:index]
174
- assert_equal 'my_custom_type', options[:type]
175
- true
176
- end
177
- .returns({'_id' => 'abc'})
178
-
179
- d = DummyStoreModel.new name: 'Test'
180
- d.instance_variable_set(:@_index, 'my_custom_index')
181
- d.instance_variable_set(:@_type, 'my_custom_type')
182
- d.save
183
- end
184
-
185
- should "set the meta attributes from response" do
186
- @gateway.expects(:save)
187
- .with do |model, options|
188
- assert_equal 'my_custom_index', options[:index]
189
- assert_equal 'my_custom_type', options[:type]
190
- true
191
- end
192
- .returns({'_id' => 'abc', '_index' => 'foo', '_type' => 'bar', '_version' => '100'})
193
-
194
- d = DummyStoreModel.new name: 'Test'
195
- d.instance_variable_set(:@_index, 'my_custom_index')
196
- d.instance_variable_set(:@_type, 'my_custom_type')
197
- d.save
198
-
199
- assert_equal 'foo', d._index
200
- assert_equal 'bar', d._type
201
- assert_equal '100', d._version
202
- end
203
- end
204
-
205
- context "when destroying," do
206
- should "remove the model from Elasticsearch" do
207
- subject.expects(:persisted?).returns(true)
208
- subject.expects(:id).returns('abc123')
209
- subject.expects(:freeze).returns(subject)
210
-
211
- @gateway
212
- .expects(:delete)
213
- .with('abc123', {})
214
- .returns({'_id' => 'abc123', 'version' => 2})
215
-
216
- assert subject.destroy
217
- assert subject.destroyed?
218
- end
219
-
220
- should "pass the options to gateway" do
221
- subject.expects(:persisted?).returns(true)
222
- subject.expects(:freeze).returns(subject)
223
-
224
- @gateway
225
- .expects(:delete)
226
- .with do |object, options|
227
- assert_equal 'ABC', options[:routing]
228
- true
229
- end
230
- .returns({'_id' => 'abc123'})
231
-
232
- assert subject.destroy routing: 'ABC'
233
- end
234
-
235
- should "return the response" do
236
- subject.expects(:persisted?).returns(true)
237
- subject.expects(:freeze).returns(subject)
238
-
239
- @gateway
240
- .expects(:delete)
241
- .returns('FOOBAR')
242
-
243
- assert_equal 'FOOBAR', subject.destroy
244
- end
245
-
246
- should "execute the callbacks" do
247
- @gateway.expects(:delete).returns({'_id' => 'abc'})
248
- DummyStoreModelWithCallback = Class.new(DummyStoreModel)
249
-
250
- DummyStoreModelWithCallback.after_destroy { $stderr.puts "DELETED" }
251
-
252
- $stderr.expects(:puts).with('DELETED')
253
- d = DummyStoreModelWithCallback.new name: 'Test'
254
- d.expects(:persisted?).returns(true)
255
- d.expects(:freeze).returns(d)
256
-
257
- d.destroy
258
- end
259
-
260
- should "remove the model from its own index" do
261
- @gateway.expects(:delete)
262
- .with do |model, options|
263
- assert_equal 'my_custom_index', options[:index]
264
- assert_equal 'my_custom_type', options[:type]
265
- true
266
- end
267
- .returns({'_id' => 'abc'})
268
-
269
- d = DummyStoreModel.new name: 'Test'
270
- d.instance_variable_set(:@_index, 'my_custom_index')
271
- d.instance_variable_set(:@_type, 'my_custom_type')
272
- d.expects(:persisted?).returns(true)
273
- d.expects(:freeze).returns(d)
274
-
275
- d.destroy
276
- end
277
- end
278
-
279
- context "when updating," do
280
- should "update the document with partial attributes" do
281
- subject.expects(:persisted?).returns(true)
282
- subject.expects(:id).returns('abc123').at_least_once
283
-
284
- @gateway
285
- .expects(:update)
286
- .with do |id, options|
287
- assert_equal 'abc123', id
288
- assert_equal 'UPDATED', options[:doc][:title]
289
- true
290
- end
291
- .returns({'_id' => 'abc123', 'version' => 2})
292
-
293
- assert subject.update title: 'UPDATED'
294
-
295
- assert_equal 'UPDATED', subject.title
296
- end
297
-
298
- should "allow to update the document with a custom script" do
299
- subject.expects(:persisted?).returns(true)
300
- subject.expects(:id).returns('abc123').at_least_once
301
-
302
- @gateway
303
- .expects(:update)
304
- .with do |id, options|
305
- assert_equal 'abc123', id
306
- assert_equal 'EXEC', options[:script]
307
- true
308
- end
309
- .returns({'_id' => 'abc123', 'version' => 2})
310
-
311
- assert subject.update( {}, { script: 'EXEC' } )
312
- end
313
-
314
- should "not update an invalid model" do
315
- @gateway
316
- .expects(:update)
317
- .never
318
-
319
- subject.instance_eval do
320
- def valid?; false; end;
321
- end
322
-
323
- assert ! subject.update(title: 'INVALID')
324
- end
325
-
326
- should "skip the validation with the :validate option" do
327
- subject.expects(:persisted?).returns(true).at_least_once
328
- subject.expects(:id).returns('abc123').at_least_once
329
-
330
- @gateway
331
- .expects(:update)
332
- .with do |object, options|
333
- assert_equal 'abc123', object
334
- assert_equal nil, options[:id]
335
- assert_equal 'INVALID', options[:doc][:title]
336
- true
337
- end
338
- .returns({'_id' => 'abc123'})
339
-
340
- subject.instance_eval do
341
- def valid?; false; end;
342
- end
343
-
344
- assert subject.update( { title: 'INVALID' }, { validate: false } )
345
- assert subject.persisted?
346
- end
347
-
348
- should "pass the options to gateway" do
349
- subject.expects(:persisted?).returns(true)
350
-
351
- @gateway
352
- .expects(:update)
353
- .with do |object, options|
354
- assert_equal 'ABC', options[:routing]
355
- true
356
- end
357
- .returns({'_id' => 'abc123'})
358
-
359
- assert subject.update( { title: 'UPDATED' }, { routing: 'ABC' } )
360
- end
361
-
362
- should "return the response" do
363
- subject.expects(:persisted?).returns(true)
364
-
365
- @gateway
366
- .expects(:update)
367
- .returns('FOOBAR')
368
-
369
- assert_equal 'FOOBAR', subject.update
370
- end
371
-
372
- should "execute the callbacks" do
373
- @gateway.expects(:update).returns({'_id' => 'abc'})
374
- DummyStoreModelWithCallback = Class.new(DummyStoreModel)
375
-
376
- DummyStoreModelWithCallback.after_update { $stderr.puts "UPDATED" }
377
-
378
- $stderr.expects(:puts).with('UPDATED')
379
- d = DummyStoreModelWithCallback.new name: 'Test'
380
- d.expects(:persisted?).returns(true)
381
- d.update name: 'Update'
382
- end
383
-
384
- should "update the model in its own index" do
385
- @gateway.expects(:update)
386
- .with do |model, options|
387
- assert_equal 'my_custom_index', options[:index]
388
- assert_equal 'my_custom_type', options[:type]
389
- true
390
- end
391
- .returns({'_id' => 'abc'})
392
-
393
- d = DummyStoreModel.new name: 'Test'
394
- d.instance_variable_set(:@_index, 'my_custom_index')
395
- d.instance_variable_set(:@_type, 'my_custom_type')
396
- d.expects(:persisted?).returns(true)
397
-
398
- d.update name: 'Update'
399
- end
400
-
401
- should "set the meta attributes from response" do
402
- @gateway.expects(:update)
403
- .with do |model, options|
404
- assert_equal 'my_custom_index', options[:index]
405
- assert_equal 'my_custom_type', options[:type]
406
- true
407
- end
408
- .returns({'_id' => 'abc', '_index' => 'foo', '_type' => 'bar', '_version' => '100'})
409
-
410
- d = DummyStoreModel.new name: 'Test'
411
- d.instance_variable_set(:@_index, 'my_custom_index')
412
- d.instance_variable_set(:@_type, 'my_custom_type')
413
- d.expects(:persisted?).returns(true)
414
-
415
- d.update name: 'Update'
416
-
417
- assert_equal 'foo', d._index
418
- assert_equal 'bar', d._type
419
- assert_equal '100', d._version
420
- end
421
- end
422
-
423
- context "when incrementing," do
424
- should "increment the attribute" do
425
- subject.expects(:persisted?).returns(true)
426
-
427
- @gateway
428
- .expects(:update)
429
- .with do |id, options|
430
- assert_equal 'ctx._source.count += 1', options[:script]
431
- true
432
- end
433
- .returns({'_id' => 'abc123', 'version' => 2})
434
-
435
- assert subject.increment :count
436
-
437
- assert_equal 1, subject.count
438
- end
439
-
440
- should "set the meta attributes from response" do
441
- subject.expects(:persisted?).returns(true)
442
-
443
- @gateway.expects(:update)
444
- .with do |model, options|
445
- assert_equal 'my_custom_index', options[:index]
446
- assert_equal 'my_custom_type', options[:type]
447
- true
448
- end
449
- .returns({'_id' => 'abc', '_index' => 'foo', '_type' => 'bar', '_version' => '100'})
450
-
451
- subject.instance_variable_set(:@_index, 'my_custom_index')
452
- subject.instance_variable_set(:@_type, 'my_custom_type')
453
-
454
- subject.increment :count
455
-
456
- assert_equal 'foo', subject._index
457
- assert_equal 'bar', subject._type
458
- assert_equal '100', subject._version
459
- end
460
- end
461
-
462
- context "when decrement," do
463
- should "decrement the attribute" do
464
- subject.expects(:persisted?).returns(true)
465
-
466
- @gateway
467
- .expects(:update)
468
- .with do |id, options|
469
- assert_equal 'ctx._source.count = ctx._source.count - 1', options[:script]
470
- true
471
- end
472
- .returns({'_id' => 'abc123', 'version' => 2})
473
-
474
- assert subject.decrement :count
475
-
476
- assert_equal -1, subject.count
477
- end
478
-
479
- should "set the meta attributes from response" do
480
- subject.expects(:persisted?).returns(true)
481
-
482
- @gateway.expects(:update)
483
- .with do |model, options|
484
- assert_equal 'my_custom_index', options[:index]
485
- assert_equal 'my_custom_type', options[:type]
486
- true
487
- end
488
- .returns({'_id' => 'abc', '_index' => 'foo', '_type' => 'bar', '_version' => '100'})
489
-
490
- subject.instance_variable_set(:@_index, 'my_custom_index')
491
- subject.instance_variable_set(:@_type, 'my_custom_type')
492
-
493
- subject.decrement :count
494
-
495
- assert_equal 'foo', subject._index
496
- assert_equal 'bar', subject._type
497
- assert_equal '100', subject._version
498
- end
499
- end
500
-
501
- context "when touching," do
502
- should "raise exception when touching not existing attribute" do
503
- subject.expects(:persisted?).returns(true)
504
- assert_raise(ArgumentError) { subject.touch :foobar }
505
- end
506
-
507
- should "update updated_at by default" do
508
- subject.expects(:persisted?).returns(true)
509
- now = Time.parse('2014-01-01T00:00:00Z')
510
- Time.expects(:now).returns(now).at_least_once
511
-
512
- @gateway
513
- .expects(:update)
514
- .with do |id, options|
515
- assert_equal '2014-01-01T00:00:00Z', options[:doc][:updated_at]
516
- true
517
- end
518
- .returns({'_id' => 'abc123', 'version' => 2})
519
-
520
- subject.touch
521
- assert_equal Time.parse('2014-01-01T00:00:00Z'), subject.updated_at
522
- end
523
-
524
- should "update a custom attribute by default" do
525
- subject.expects(:persisted?).returns(true)
526
- now = Time.parse('2014-01-01T00:00:00Z')
527
- Time.expects(:now).returns(now).at_least_once
528
-
529
- @gateway
530
- .expects(:update)
531
- .with do |id, options|
532
- assert_equal '2014-01-01T00:00:00Z', options[:doc][:created_at]
533
- true
534
- end
535
- .returns({'_id' => 'abc123', 'version' => 2})
536
-
537
- subject.touch :created_at
538
- assert_equal Time.parse('2014-01-01T00:00:00Z'), subject.created_at
539
- end
540
-
541
- should "execute the callbacks" do
542
- @gateway.expects(:update).returns({'_id' => 'abc'})
543
- DummyStoreModelWithCallback = Class.new(DummyStoreModel)
544
-
545
- DummyStoreModelWithCallback.after_touch { $stderr.puts "TOUCHED" }
546
-
547
- $stderr.expects(:puts).with('TOUCHED')
548
- d = DummyStoreModelWithCallback.new name: 'Test'
549
- d.expects(:persisted?).returns(true)
550
- d.touch
551
- end
552
-
553
- should "set the meta attributes from response" do
554
- subject.expects(:persisted?).returns(true)
555
-
556
- @gateway.expects(:update)
557
- .with do |model, options|
558
- assert_equal 'my_custom_index', options[:index]
559
- assert_equal 'my_custom_type', options[:type]
560
- true
561
- end
562
- .returns({'_id' => 'abc', '_index' => 'foo', '_type' => 'bar', '_version' => '100'})
563
-
564
- subject.instance_variable_set(:@_index, 'my_custom_index')
565
- subject.instance_variable_set(:@_type, 'my_custom_type')
566
-
567
- subject.touch
568
-
569
- assert_equal 'foo', subject._index
570
- assert_equal 'bar', subject._type
571
- assert_equal '100', subject._version
572
- end
573
- end
574
-
575
- end
576
- end