acts_as_votable 0.10.0 → 0.13.0

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 (52) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +44 -0
  3. data/.gitignore +10 -6
  4. data/.rubocop.yml +121 -0
  5. data/.ruby-version +1 -0
  6. data/Appraisals +23 -0
  7. data/Gemfile +3 -14
  8. data/{README.markdown → README.md} +87 -52
  9. data/Rakefile +6 -4
  10. data/acts_as_votable.gemspec +12 -7
  11. data/gemfiles/.bundle/config +2 -0
  12. data/gemfiles/rails_4.gemfile +7 -0
  13. data/gemfiles/rails_5.gemfile +7 -0
  14. data/gemfiles/rails_5_1.gemfile +7 -0
  15. data/gemfiles/rails_5_2.gemfile +7 -0
  16. data/gemfiles/rails_6.gemfile +8 -0
  17. data/gemfiles/rails_6_1.gemfile +8 -0
  18. data/gemfiles/rails_6_rc1.gemfile +8 -0
  19. data/lib/acts_as_votable.rb +9 -9
  20. data/lib/acts_as_votable/cacheable.rb +174 -0
  21. data/lib/acts_as_votable/extenders/controller.rb +3 -4
  22. data/lib/acts_as_votable/extenders/votable.rb +17 -6
  23. data/lib/acts_as_votable/extenders/voter.rb +4 -6
  24. data/lib/acts_as_votable/helpers/words.rb +7 -10
  25. data/lib/acts_as_votable/version.rb +3 -1
  26. data/lib/acts_as_votable/votable.rb +74 -194
  27. data/lib/acts_as_votable/vote.rb +10 -12
  28. data/lib/acts_as_votable/voter.rb +55 -56
  29. data/lib/generators/acts_as_votable/migration/migration_generator.rb +25 -4
  30. data/lib/generators/acts_as_votable/migration/templates/active_record/{migration.rb → migration.erb} +1 -6
  31. data/spec/factories/votable.rb +6 -0
  32. data/spec/factories/votable_cache.rb +6 -0
  33. data/spec/factories/votable_cache_update_attributes.rb +6 -0
  34. data/spec/factories/votable_cache_update_columns.rb +6 -0
  35. data/spec/factories/votable_child_of_sti_not_votable.rb +6 -0
  36. data/spec/factories/votable_child_of_sti_votable.rb +6 -0
  37. data/spec/factories/votable_voter.rb +6 -0
  38. data/spec/factories/vote.rb +6 -0
  39. data/spec/factories/voter.rb +6 -0
  40. data/spec/generators/active_record_generator_spec.rb +13 -0
  41. data/spec/shared_example/votable_model.rb +542 -0
  42. data/spec/shared_example/voter_model.rb +280 -0
  43. data/spec/spec_helper.rb +28 -18
  44. data/spec/support/factory_bot.rb +9 -0
  45. data/spec/votable_spec.rb +10 -9
  46. data/spec/votable_voter_spec.rb +12 -12
  47. data/spec/voter_spec.rb +9 -10
  48. data/spec/words_spec.rb +9 -12
  49. metadata +116 -26
  50. data/.travis.yml +0 -25
  51. data/spec/shared_example/votable_model_spec.rb +0 -421
  52. data/spec/shared_example/voter_model_spec.rb +0 -279
@@ -1,4 +1,6 @@
1
- require 'rails/generators/migration'
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/migration"
2
4
 
3
5
  module ActsAsVotable
4
6
  class MigrationGenerator < Rails::Generators::Base
@@ -11,21 +13,40 @@ module ActsAsVotable
11
13
  end
12
14
 
13
15
  def self.source_root
14
- File.join(File.dirname(__FILE__), 'templates', (orm.to_s unless orm.class.eql?(String)) )
16
+ File.join(File.dirname(__FILE__), "templates", (orm.to_s unless orm.class.eql?(String)))
15
17
  end
16
18
 
17
19
  def self.orm_has_migration?
18
20
  [:active_record].include? orm
19
21
  end
20
22
 
21
- def self.next_migration_number(path)
23
+ def self.next_migration_number(_path)
22
24
  Time.now.utc.strftime("%Y%m%d%H%M%S")
23
25
  end
24
26
 
25
27
  def create_migration_file
26
28
  if self.class.orm_has_migration?
27
- migration_template 'migration.rb', 'db/migrate/acts_as_votable_migration.rb'
29
+ migration_template "migration.erb", "db/migrate/acts_as_votable_migration.rb", migration_version: migration_version
30
+ end
31
+ end
32
+
33
+
34
+ private
35
+
36
+ def migration_version
37
+ if rails5?
38
+ "[4.2]"
39
+ elsif rails6?
40
+ "[6.0]"
28
41
  end
29
42
  end
43
+
44
+ def rails5?
45
+ Rails.version.start_with? "5"
46
+ end
47
+
48
+ def rails6?
49
+ Rails.version.start_with? "6"
50
+ end
30
51
  end
31
52
  end
@@ -1,4 +1,4 @@
1
- class ActsAsVotableMigration < ActiveRecord::Migration
1
+ class ActsAsVotableMigration < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  create_table :votes do |t|
4
4
 
@@ -12,11 +12,6 @@ class ActsAsVotableMigration < ActiveRecord::Migration
12
12
  t.timestamps
13
13
  end
14
14
 
15
- if ActiveRecord::VERSION::MAJOR < 4
16
- add_index :votes, [:votable_id, :votable_type]
17
- add_index :votes, [:voter_id, :voter_type]
18
- end
19
-
20
15
  add_index :votes, [:voter_id, :voter_type, :vote_scope]
21
16
  add_index :votes, [:votable_id, :votable_type, :vote_scope]
22
17
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :votable do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :votable_cache do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :votable_cache_update do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :votable_cache_update_columns do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :child_of_sti_not_votable do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :child_of_sti_votable do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :votable_voter do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :vote, class: ActsAsVotable::Vote do
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :voter do
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "acts_as_votable"
4
+ require "spec_helper"
5
+
6
+ require "rails/generators"
7
+ require "generators/acts_as_votable/migration/migration_generator"
8
+
9
+ module ActsAsVotable
10
+ describe MigrationGenerator do
11
+ pending
12
+ end
13
+ end
@@ -0,0 +1,542 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples "a votable_model" do
4
+ it "should return false when a vote with no voter is saved" do
5
+ expect(votable.vote_by).to be false
6
+ end
7
+
8
+ it "should have one vote when saved" do
9
+ votable.vote_by voter: voter, vote: "yes"
10
+ expect(votable.votes_for.size).to eq(1)
11
+ end
12
+
13
+ it "should have one vote when voted on twice by the same person" do
14
+ votable.vote_by voter: voter, vote: "yes"
15
+ votable.vote_by voter: voter, vote: "no"
16
+ expect(votable.votes_for.size).to eq(1)
17
+ end
18
+
19
+ it "should have two votes_for when voted on twice by the same person with duplicate paramenter" do
20
+ votable.vote_by voter: voter, vote: "yes"
21
+ votable.vote_by voter: voter, vote: "no", duplicate: true
22
+ expect(votable.votes_for.size).to eq(2)
23
+ end
24
+
25
+ it "should have one scoped vote when voting under an scope" do
26
+ votable.vote_by voter: voter, vote: "yes", vote_scope: "rank"
27
+ expect(votable.find_votes_for(vote_scope: "rank").size).to eq(1)
28
+ end
29
+
30
+ it "should have one vote when voted on twice using scope by the same person" do
31
+ votable.vote_by voter: voter, vote: "yes", vote_scope: "rank"
32
+ votable.vote_by voter: voter, vote: "no", vote_scope: "rank"
33
+ expect(votable.find_votes_for(vote_scope: "rank").size).to eq(1)
34
+ end
35
+
36
+ it "should have two votes_for when voting on two different scopes by the same person" do
37
+ votable.vote_by voter: voter, vote: "yes", vote_scope: "weekly_rank"
38
+ votable.vote_by voter: voter, vote: "no", vote_scope: "monthly_rank"
39
+ expect(votable.votes_for.size).to eq(2)
40
+ end
41
+
42
+ it "should be callable with vote_up" do
43
+ votable.vote_up voter
44
+ expect(votable.get_up_votes.first.voter).to eq(voter)
45
+ end
46
+
47
+ it "should be callable with vote_down" do
48
+ votable.vote_down voter
49
+ expect(votable.get_down_votes.first.voter).to eq(voter)
50
+ end
51
+
52
+ it "should have 2 votes_for when voted on once by two different people" do
53
+ votable.vote_by voter: voter
54
+ votable.vote_by voter: voter2
55
+ expect(votable.votes_for.size).to eq(2)
56
+ end
57
+
58
+ it "should have one true vote" do
59
+ votable.vote_by voter: voter
60
+ votable.vote_by voter: voter2, vote: "dislike"
61
+ expect(votable.get_up_votes.size).to eq(1)
62
+ end
63
+
64
+ it "should have 2 false votes_for" do
65
+ votable.vote_by voter: voter, vote: "no"
66
+ votable.vote_by voter: voter2, vote: "dislike"
67
+ expect(votable.get_down_votes.size).to eq(2)
68
+ end
69
+
70
+ it "should have been voted on by voter2" do
71
+ votable.vote_by voter: voter2, vote: true
72
+ expect(votable.find_votes_for.first.voter.id).to be voter2.id
73
+ end
74
+
75
+ it "should count the vote as registered if this is the voters first vote" do
76
+ votable.vote_by voter: voter
77
+ expect(votable.vote_registered?).to be true
78
+ end
79
+
80
+ it "should not count the vote as being registered if that voter has already voted and the vote has not changed" do
81
+ votable.vote_by voter: voter, vote: true
82
+ votable.vote_by voter: voter, vote: "yes"
83
+ expect(votable.vote_registered?).to be false
84
+ end
85
+
86
+ it "should count the vote as registered if the voter has voted and the vote flag has changed" do
87
+ votable.vote_by voter: voter, vote: true
88
+ votable.vote_by voter: voter, vote: "dislike"
89
+ expect(votable.vote_registered?).to be true
90
+ end
91
+
92
+ it "should count the vote as registered if the voter has voted and the vote weight has changed" do
93
+ votable.vote_by voter: voter, vote: true, vote_weight: 1
94
+ votable.vote_by voter: voter, vote: true, vote_weight: 2
95
+ expect(votable.vote_registered?).to be true
96
+ end
97
+
98
+ it "should be voted on by voter" do
99
+ votable.vote_by voter: voter
100
+ expect(votable.voted_on_by?(voter)).to be true
101
+ end
102
+
103
+ it "should be able to unvote a voter" do
104
+ votable.liked_by(voter)
105
+ votable.unliked_by(voter)
106
+ expect(votable.voted_on_by?(voter)).to be false
107
+ end
108
+
109
+ it "should be voted up by a voter" do
110
+ votable.liked_by voter
111
+ expect(votable.voted_up_by?(voter)).to be true
112
+ end
113
+
114
+ it "should be voted down by a voter" do
115
+ votable.disliked_by voter
116
+ expect(votable.voted_down_by?(voter)).to be true
117
+ end
118
+
119
+ it "should unvote a positive vote" do
120
+ votable.vote_by voter: voter
121
+ votable.unvote voter: voter
122
+ expect(votable.find_votes_for.count).to eq(0)
123
+ end
124
+
125
+ it "should set the votable to unregistered after unvoting" do
126
+ votable.vote_by voter: voter
127
+ votable.unvote voter: voter
128
+ expect(votable.vote_registered?).to be false
129
+ end
130
+
131
+ it "should unvote a negative vote" do
132
+ votable.vote_by voter: voter, vote: "no"
133
+ votable.unvote voter: voter
134
+ expect(votable.find_votes_for.count).to eq(0)
135
+ end
136
+
137
+ it "should unvote only the from a single voter" do
138
+ votable.vote_by voter: voter
139
+ votable.vote_by voter: voter2
140
+ votable.unvote voter: voter
141
+ expect(votable.find_votes_for.count).to eq(1)
142
+ end
143
+
144
+ it "should be contained to instances" do
145
+ votable2 = build(:votable, name: "2nd votable")
146
+ votable2.save
147
+
148
+ votable.vote_by voter: voter, vote: false
149
+ votable2.vote_by voter: voter, vote: true
150
+ votable2.vote_by voter: voter, vote: true
151
+
152
+ expect(votable.vote_registered?).to be true
153
+ expect(votable2.vote_registered?).to be false
154
+ end
155
+
156
+ it "should set default vote weight to 1 if not specified" do
157
+ votable.upvote_by voter
158
+ expect(votable.find_votes_for.first.vote_weight).to eq(1)
159
+ end
160
+
161
+ describe "with cached votes_for" do
162
+ let!(:voter) { create(:voter, name: "i can vote!") }
163
+ let!(:votable) { create(:votable, name: "a voting model without a cache") }
164
+ let!(:votable_cache) { create(:votable_cache, name: "voting model with cache") }
165
+
166
+ it "should not update cached votes_for if there are no columns" do
167
+ votable.vote_by voter: voter
168
+ end
169
+
170
+ it "should update cached total votes_for if there is a total column" do
171
+ votable_cache.cached_votes_total = 50
172
+ votable_cache.vote_by voter: voter
173
+ expect(votable_cache.cached_votes_total).to eq(1)
174
+ end
175
+
176
+ describe "with ActiveRecord::StaleObjectError" do
177
+ it "should rollback vote up if cache update fails" do
178
+ votable_cache.cached_votes_total = 50
179
+ expect(votable_cache)
180
+ .to(receive(:update_cached_votes)
181
+ .and_raise(ActiveRecord::StaleObjectError.new(votable_cache, "update")))
182
+
183
+ expect { votable_cache.vote_by voter: voter }.to raise_error ActiveRecord::StaleObjectError
184
+ expect(votable_cache.cached_votes_total).to eq(50)
185
+ expect(votable_cache.voted_on_by?(voter)).to be false
186
+ end
187
+
188
+ it "should rollback unvote if cache update fails" do
189
+ votable_cache.vote_by voter: voter, vote: "true"
190
+
191
+ expect(votable_cache)
192
+ .to(receive(:update_cached_votes)
193
+ .and_raise(ActiveRecord::StaleObjectError.new(votable_cache, "update")))
194
+
195
+ expect { votable_cache.unvote voter: voter }.to raise_error ActiveRecord::StaleObjectError
196
+
197
+ expect(votable_cache.cached_votes_total).to eq(1)
198
+ expect(votable_cache.voted_on_by?(voter)).to be true
199
+ end
200
+ end
201
+
202
+ it "should update cached total votes_for when a vote up is removed" do
203
+ votable_cache.vote_by voter: voter, vote: "true"
204
+ votable_cache.unvote voter: voter
205
+ expect(votable_cache.cached_votes_total).to eq(0)
206
+ end
207
+
208
+ it "should update cached total votes_for when a vote down is removed" do
209
+ votable_cache.vote_by voter: voter, vote: "false"
210
+ votable_cache.unvote voter: voter
211
+ expect(votable_cache.cached_votes_total).to eq(0)
212
+ end
213
+
214
+ it "should update cached score votes_for if there is a score column" do
215
+ votable_cache.cached_votes_score = 50
216
+ votable_cache.vote_by voter: voter
217
+ expect(votable_cache.cached_votes_score).to eq(1)
218
+ votable_cache.vote_by voter: voter2, vote: "false"
219
+ expect(votable_cache.cached_votes_score).to eq(0)
220
+ votable_cache.vote_by voter: voter, vote: "false"
221
+ expect(votable_cache.cached_votes_score).to eq(-2)
222
+ end
223
+
224
+ it "should update cached score votes_for when a vote up is removed" do
225
+ votable_cache.vote_by voter: voter, vote: "true"
226
+ expect(votable_cache.cached_votes_score).to eq(1)
227
+ votable_cache.unvote voter: voter
228
+ expect(votable_cache.cached_votes_score).to eq(0)
229
+ end
230
+
231
+ it "should update cached score votes_for when a vote down is removed" do
232
+ votable_cache.vote_by voter: voter, vote: "false"
233
+ expect(votable_cache.cached_votes_score).to eq(-1)
234
+ votable_cache.unvote voter: voter
235
+ expect(votable_cache.cached_votes_score).to eq(0)
236
+ end
237
+
238
+ it "should update cached weighted total if there is a weighted total column" do
239
+ votable_cache.cached_weighted_total = 50
240
+ votable_cache.vote_by voter: voter
241
+ expect(votable_cache.cached_weighted_total).to eq(1)
242
+ votable_cache.vote_by voter: voter2, vote: "false"
243
+ expect(votable_cache.cached_weighted_total).to eq(2)
244
+ end
245
+
246
+ it "should update cached weighted total votes_for when a vote up is removed" do
247
+ votable_cache.vote_by voter: voter, vote: "true", vote_weight: 3
248
+ expect(votable_cache.cached_weighted_total).to eq(3)
249
+ votable_cache.unvote voter: voter
250
+ expect(votable_cache.cached_weighted_total).to eq(0)
251
+ end
252
+
253
+ it "should update cached weighted total votes_for when a vote down is removed" do
254
+ votable_cache.vote_by voter: voter, vote: "false", vote_weight: 4
255
+ expect(votable_cache.cached_weighted_total).to eq(4)
256
+ votable_cache.unvote voter: voter
257
+ expect(votable_cache.cached_weighted_total).to eq(0)
258
+ end
259
+
260
+ it "should update cached weighted score if there is a weighted score column" do
261
+ votable_cache.cached_weighted_score = 50
262
+ votable_cache.vote_by voter: voter, vote_weight: 3
263
+ expect(votable_cache.cached_weighted_score).to eq(3)
264
+ votable_cache.vote_by voter: voter2, vote: "false", vote_weight: 5
265
+ expect(votable_cache.cached_weighted_score).to eq(-2)
266
+ # voter changes her vote from 3 to 5
267
+ votable_cache.vote_by voter: voter, vote_weight: 5
268
+ expect(votable_cache.cached_weighted_score).to eq(0)
269
+ votable_cache.vote_by voter: voter3, vote_weight: 4
270
+ expect(votable_cache.cached_weighted_score).to eq(4)
271
+ end
272
+
273
+ it "should update cached weighted score votes_for when a vote up is removed" do
274
+ votable_cache.vote_by voter: voter, vote: "true", vote_weight: 3
275
+ expect(votable_cache.cached_weighted_score).to eq(3)
276
+ votable_cache.unvote voter: voter
277
+ expect(votable_cache.cached_weighted_score).to eq(0)
278
+ end
279
+
280
+ it "should update cached weighted score votes_for when a vote down is removed" do
281
+ votable_cache.vote_by voter: voter, vote: "false", vote_weight: 4
282
+ expect(votable_cache.cached_weighted_score).to eq(-4)
283
+ votable_cache.unvote voter: voter
284
+ expect(votable_cache.cached_weighted_score).to eq(0)
285
+ end
286
+
287
+ it "should update cached weighted average if there is a weighted average column" do
288
+ votable_cache.cached_weighted_average = 50.0
289
+ votable_cache.vote_by voter: voter, vote: "true", vote_weight: 5
290
+ expect(votable_cache.cached_weighted_average).to eq(5.0)
291
+ votable_cache.vote_by voter: voter2, vote: "true", vote_weight: 3
292
+ expect(votable_cache.cached_weighted_average).to eq(4.0)
293
+ # voter changes her vote from 5 to 4
294
+ votable_cache.vote_by voter: voter, vote: "true", vote_weight: 4
295
+ expect(votable_cache.cached_weighted_average).to eq(3.5)
296
+ votable_cache.vote_by voter: voter3, vote: "true", vote_weight: 5
297
+ expect(votable_cache.cached_weighted_average).to eq(4.0)
298
+ end
299
+
300
+ it "should update cached weighted average votes_for when a vote up is removed" do
301
+ votable_cache.vote_by voter: voter, vote: "true", vote_weight: 5
302
+ votable_cache.vote_by voter: voter2, vote: "true", vote_weight: 3
303
+ expect(votable_cache.cached_weighted_average).to eq(4)
304
+ votable_cache.unvote voter: voter
305
+ expect(votable_cache.cached_weighted_average).to eq(3)
306
+ end
307
+
308
+ it "should update cached up votes_for if there is an up vote column" do
309
+ votable_cache.cached_votes_up = 50
310
+ votable_cache.vote_by voter: voter
311
+ votable_cache.vote_by voter: voter
312
+ expect(votable_cache.cached_votes_up).to eq(1)
313
+ end
314
+
315
+ it "should update cached down votes_for if there is a down vote column" do
316
+ votable_cache.cached_votes_down = 50
317
+ votable_cache.vote_by voter: voter, vote: "false"
318
+ expect(votable_cache.cached_votes_down).to eq(1)
319
+ end
320
+
321
+ it "should update cached up votes_for when a vote up is removed" do
322
+ votable_cache.vote_by voter: voter, vote: "true"
323
+ votable_cache.unvote voter: voter
324
+ expect(votable_cache.cached_votes_up).to eq(0)
325
+ end
326
+
327
+ it "should update cached down votes_for when a vote down is removed" do
328
+ votable_cache.vote_by voter: voter, vote: "false"
329
+ votable_cache.unvote voter: voter
330
+ expect(votable_cache.cached_votes_down).to eq(0)
331
+ end
332
+
333
+ it "should select from cached total votes_for if there a total column" do
334
+ votable_cache.vote_by voter: voter
335
+ votable_cache.cached_votes_total = 50
336
+ expect(votable_cache.count_votes_total).to eq(50)
337
+ end
338
+
339
+ it "should select from cached up votes_for if there is an up vote column" do
340
+ votable_cache.vote_by voter: voter
341
+ votable_cache.cached_votes_up = 50
342
+ expect(votable_cache.count_votes_up).to eq(50)
343
+ end
344
+
345
+ it "should select from cached down votes_for if there is a down vote column" do
346
+ votable_cache.vote_by voter: voter, vote: "false"
347
+ votable_cache.cached_votes_down = 50
348
+ expect(votable_cache.count_votes_down).to eq(50)
349
+ end
350
+
351
+ it "should select from cached votes score if there is a votes score column" do
352
+ votable_cache.vote_by voter: voter, vote: "false"
353
+ votable_cache.cached_votes_score = 50
354
+ expect(votable_cache.count_votes_score).to eq(50)
355
+ end
356
+
357
+ it "should select from cached weighted total if there is a weighted total column" do
358
+ votable_cache.vote_by voter: voter, vote: "false"
359
+ votable_cache.cached_weighted_total = 50
360
+ expect(votable_cache.weighted_total).to eq(50)
361
+ end
362
+
363
+ it "should select from cached weighted score if there is a weighted score column" do
364
+ votable_cache.vote_by voter: voter, vote: "false"
365
+ votable_cache.cached_weighted_score = 50
366
+ expect(votable_cache.weighted_score).to eq(50)
367
+ end
368
+
369
+ it "should select from cached weighted average if there is a weighted average column" do
370
+ votable_cache.vote_by voter: voter, vote: "false"
371
+ votable_cache.cached_weighted_average = 50
372
+ expect(votable_cache.weighted_average).to eq(50)
373
+ end
374
+
375
+ it "should update cached total votes_for when voting under an scope" do
376
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "rank"
377
+ expect(votable_cache.cached_votes_total).to eq(1)
378
+ end
379
+
380
+ it "should update cached up votes_for when voting under an scope" do
381
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "rank"
382
+ expect(votable_cache.cached_votes_up).to eq(1)
383
+ end
384
+
385
+ it "should update cached total votes_for when a scoped vote down is removed" do
386
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "rank"
387
+ votable_cache.unvote voter: voter, vote_scope: "rank"
388
+ expect(votable_cache.cached_votes_total).to eq(0)
389
+ end
390
+
391
+ it "should update cached up votes_for when a scoped vote down is removed" do
392
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "rank"
393
+ votable_cache.unvote voter: voter, vote_scope: "rank"
394
+ expect(votable_cache.cached_votes_up).to eq(0)
395
+ end
396
+
397
+ it "should update cached down votes_for when downvoting under a scope" do
398
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "rank"
399
+ expect(votable_cache.cached_votes_down).to eq(1)
400
+ end
401
+
402
+ it "should update cached down votes_for when a scoped vote down is removed" do
403
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "rank"
404
+ votable_cache.unvote voter: voter, vote_scope: "rank"
405
+ expect(votable_cache.cached_votes_down).to eq(0)
406
+ end
407
+
408
+ describe "with acts_as_votable_options" do
409
+ describe "cacheable_strategy" do
410
+ let(:updated_at) { 3.days.ago }
411
+
412
+ before { votable_cache.vote_by voter: voter }
413
+
414
+ context "update" do
415
+ let(:votable_cache) { create(:votable_cache_update, name: "voting model with cache", updated_at: updated_at) }
416
+
417
+ it do
418
+ expect(votable_cache.cached_votes_total).to eq(1)
419
+ expect(votable_cache.updated_at.to_i).to_not eq updated_at.to_i
420
+ end
421
+ end
422
+
423
+ context "update_columns" do
424
+ let(:votable_cache) { create(:votable_cache_update_columns, name: "voting model with cache", updated_at: updated_at) }
425
+
426
+ it do
427
+ expect(votable_cache.cached_votes_total).to eq(1)
428
+ expect(votable_cache.updated_at.to_i).to eq updated_at.to_i
429
+ end
430
+ end
431
+ end
432
+ end
433
+ end
434
+
435
+ describe "with scoped cached votes_for" do
436
+
437
+ it "should update cached total votes_for if there is a total column" do
438
+ votable_cache.cached_scoped_test_votes_total = 50
439
+ votable_cache.vote_by voter: voter, vote_scope: "test"
440
+ expect(votable_cache.cached_scoped_test_votes_total).to eq(1)
441
+ end
442
+
443
+ it "should update cached total votes_for when a vote up is removed" do
444
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "test"
445
+ votable_cache.unvote voter: voter, vote_scope: "test"
446
+ expect(votable_cache.cached_scoped_test_votes_total).to eq(0)
447
+ end
448
+
449
+ it "should update cached total votes_for when a vote down is removed" do
450
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "test"
451
+ votable_cache.unvote voter: voter, vote_scope: "test"
452
+ expect(votable_cache.cached_scoped_test_votes_total).to eq(0)
453
+ end
454
+
455
+ it "should update cached score votes_for if there is a score column" do
456
+ votable_cache.cached_scoped_test_votes_score = 50
457
+ votable_cache.vote_by voter: voter, vote_scope: "test"
458
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(1)
459
+ votable_cache.vote_by voter: voter2, vote: "false", vote_scope: "test"
460
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(0)
461
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "test"
462
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(-2)
463
+ end
464
+
465
+ it "should update cached score votes_for when a vote up is removed" do
466
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "test"
467
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(1)
468
+ votable_cache.unvote voter: voter, vote_scope: "test"
469
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(0)
470
+ end
471
+
472
+ it "should update cached score votes_for when a vote down is removed" do
473
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "test"
474
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(-1)
475
+ votable_cache.unvote voter: voter, vote_scope: "test"
476
+ expect(votable_cache.cached_scoped_test_votes_score).to eq(0)
477
+ end
478
+
479
+ it "should update cached up votes_for if there is an up vote column" do
480
+ votable_cache.cached_scoped_test_votes_up = 50
481
+ votable_cache.vote_by voter: voter, vote_scope: "test"
482
+ votable_cache.vote_by voter: voter, vote_scope: "test"
483
+ expect(votable_cache.cached_scoped_test_votes_up).to eq(1)
484
+ end
485
+
486
+ it "should update cached down votes_for if there is a down vote column" do
487
+ votable_cache.cached_scoped_test_votes_down = 50
488
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "test"
489
+ expect(votable_cache.cached_scoped_test_votes_down).to eq(1)
490
+ end
491
+
492
+ it "should update cached up votes_for when a vote up is removed" do
493
+ votable_cache.vote_by voter: voter, vote: "true", vote_scope: "test"
494
+ votable_cache.unvote voter: voter, vote_scope: "test"
495
+ expect(votable_cache.cached_scoped_test_votes_up).to eq(0)
496
+ end
497
+
498
+ it "should update cached down votes_for when a vote down is removed" do
499
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "test"
500
+ votable_cache.unvote voter: voter, vote_scope: "test"
501
+ expect(votable_cache.cached_scoped_test_votes_down).to eq(0)
502
+ end
503
+
504
+ it "should select from cached total votes_for if there a total column" do
505
+ votable_cache.vote_by voter: voter, vote_scope: "test"
506
+ votable_cache.cached_scoped_test_votes_total = 50
507
+ expect(votable_cache.count_votes_total(false, "test")).to eq(50)
508
+ end
509
+
510
+ it "should select from cached up votes_for if there is an up vote column" do
511
+ votable_cache.vote_by voter: voter, vote_scope: "test"
512
+ votable_cache.cached_scoped_test_votes_up = 50
513
+ expect(votable_cache.count_votes_up(false, "test")).to eq(50)
514
+ end
515
+
516
+ it "should select from cached down votes_for if there is a down vote column" do
517
+ votable_cache.vote_by voter: voter, vote: "false", vote_scope: "test"
518
+ votable_cache.cached_scoped_test_votes_down = 50
519
+ expect(votable_cache.count_votes_down(false, "test")).to eq(50)
520
+ end
521
+
522
+ end
523
+
524
+ describe "sti models" do
525
+ let(:child_sti_not_votable) { create(:child_of_sti_not_votable, name: "sti child") }
526
+ let(:child_sti_votable) { create(:child_of_sti_votable, name: "sti child") }
527
+
528
+ it "should be able to vote on a votable child of a non votable sti model" do
529
+ child_sti_not_votable.vote_by voter: voter, vote: "yes"
530
+ expect(child_sti_not_votable.votes_for.size).to eq(1)
531
+ end
532
+
533
+ it "should not be able to vote on a parent non votable" do
534
+ expect(StiNotVotable).not_to be_votable
535
+ end
536
+
537
+ it "should be able to vote on a child when its parent is votable" do
538
+ child_sti_votable.vote_by voter: voter, vote: "yes"
539
+ expect(child_sti_votable.votes_for.size).to eq(1)
540
+ end
541
+ end
542
+ end