acts_as_votable 0.10.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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