rating 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3 -0
  3. data/LICENSE +21 -0
  4. data/README.md +180 -0
  5. data/lib/generators/rating/install_generator.rb +15 -0
  6. data/lib/generators/rating/templates/db/migrate/create_rating_tables.rb +31 -0
  7. data/lib/rating.rb +10 -0
  8. data/lib/rating/models/rating/extension.rb +46 -0
  9. data/lib/rating/models/rating/rate.rb +41 -0
  10. data/lib/rating/models/rating/rating.rb +96 -0
  11. data/lib/rating/version.rb +5 -0
  12. data/spec/factories/article.rb +7 -0
  13. data/spec/factories/rating/rate.rb +10 -0
  14. data/spec/factories/rating/rating.rb +12 -0
  15. data/spec/factories/user.rb +7 -0
  16. data/spec/models/extension/after_create_spec.rb +19 -0
  17. data/spec/models/extension/order_by_rating_spec.rb +121 -0
  18. data/spec/models/extension/rate_for_spec.rb +14 -0
  19. data/spec/models/extension/rate_spec.rb +14 -0
  20. data/spec/models/extension/rated_question_spec.rb +20 -0
  21. data/spec/models/extension/rated_spec.rb +38 -0
  22. data/spec/models/extension/rates_spec.rb +38 -0
  23. data/spec/models/extension/rating_spec.rb +38 -0
  24. data/spec/models/rate/create_spec.rb +64 -0
  25. data/spec/models/rate/rate_for_spec.rb +20 -0
  26. data/spec/models/rate_spec.rb +26 -0
  27. data/spec/models/rating/averager_data_spec.rb +29 -0
  28. data/spec/models/rating/data_spec.rb +37 -0
  29. data/spec/models/rating/update_rating_spec.rb +28 -0
  30. data/spec/models/rating/values_data_spec.rb +33 -0
  31. data/spec/models/rating_spec.rb +17 -0
  32. data/spec/rails_helper.rb +11 -0
  33. data/spec/support/common.rb +22 -0
  34. data/spec/support/database_cleaner.rb +19 -0
  35. data/spec/support/db/migrate/create_articles_table.rb +9 -0
  36. data/spec/support/db/migrate/create_users_table.rb +9 -0
  37. data/spec/support/factory_bot.rb +9 -0
  38. data/spec/support/html_matchers.rb +7 -0
  39. data/spec/support/migrate.rb +7 -0
  40. data/spec/support/models/article.rb +5 -0
  41. data/spec/support/models/user.rb +5 -0
  42. data/spec/support/shoulda.rb +10 -0
  43. metadata +247 -0
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rating
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :article do
5
+ sequence(:name) { |i| "Name #{i}" }
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :rating_rate, class: Rating::Rate do
5
+ value 100
6
+
7
+ author { create :user }
8
+ resource { create :article }
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :rating_rating, class: Rating::Rating do
5
+ average 100
6
+ estimate 100
7
+ sum 100
8
+ total 1
9
+
10
+ resource { create :article }
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :user do
5
+ sequence(:name) { |i| "Name #{i}" }
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':after_create' do
6
+ context 'when creates object' do
7
+ let!(:user) { create :user }
8
+
9
+ it 'creates a record with zero values just to be easy to make the count' do
10
+ rating = Rating::Rating.find_by(resource: user)
11
+
12
+ expect(rating.average).to eq 0
13
+ expect(rating.estimate).to eq 0
14
+ expect(rating.resource).to eq user
15
+ expect(rating.sum).to eq 0
16
+ expect(rating.total).to eq 0
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':order_by_rating' do
6
+ let!(:user_1) { create :user }
7
+ let!(:user_2) { create :user }
8
+
9
+ let!(:article_1) { create :article }
10
+ let!(:article_2) { create :article }
11
+ let!(:article_3) { create :article }
12
+
13
+ before do
14
+ create :rating_rate, author: user_1, resource: article_1, value: 100
15
+ create :rating_rate, author: user_1, resource: article_2, value: 11
16
+ create :rating_rate, author: user_1, resource: article_3, value: 10
17
+ create :rating_rate, author: user_2, resource: article_1, value: 1
18
+ end
19
+
20
+ context 'with default filters' do
21
+ it 'sorts by :estimate :desc' do
22
+ expect(Article.order_by_rating).to eq [
23
+ article_1,
24
+ article_2,
25
+ article_3
26
+ ]
27
+ end
28
+ end
29
+
30
+ context 'filtering by :average' do
31
+ context 'as asc' do
32
+ it 'works' do
33
+ expect(Article.order_by_rating(:average, :asc)).to eq [
34
+ article_3,
35
+ article_2,
36
+ article_1
37
+ ]
38
+ end
39
+ end
40
+
41
+ context 'as desc' do
42
+ it 'works' do
43
+ expect(Article.order_by_rating(:average, :desc)).to eq [
44
+ article_1,
45
+ article_2,
46
+ article_3
47
+ ]
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'filtering by :estimate' do
53
+ context 'as asc' do
54
+ it 'works' do
55
+ expect(Article.order_by_rating(:estimate, :asc)).to eq [
56
+ article_3,
57
+ article_2,
58
+ article_1
59
+ ]
60
+ end
61
+ end
62
+
63
+ context 'as desc' do
64
+ it 'works' do
65
+ expect(Article.order_by_rating(:estimate, :desc)).to eq [
66
+ article_1,
67
+ article_2,
68
+ article_3
69
+ ]
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'filtering by :sum' do
75
+ context 'as asc' do
76
+ it 'works' do
77
+ expect(Article.order_by_rating(:sum, :asc)).to eq [
78
+ article_3,
79
+ article_2,
80
+ article_1
81
+ ]
82
+ end
83
+ end
84
+
85
+ context 'as desc' do
86
+ it 'works' do
87
+ expect(Article.order_by_rating(:sum, :desc)).to eq [
88
+ article_1,
89
+ article_2,
90
+ article_3
91
+ ]
92
+ end
93
+ end
94
+
95
+ context 'filtering by :total' do
96
+ context 'as asc' do
97
+ it 'works' do
98
+ result = Article.order_by_rating(:total, :asc)
99
+
100
+ expect(result[0..1]).to match_array [article_2, article_3]
101
+ expect(result.last).to eq article_1
102
+ end
103
+ end
104
+
105
+ context 'as desc' do
106
+ it 'works' do
107
+ result = Article.order_by_rating(:total, :desc)
108
+
109
+ expect(result.first).to eq article_1
110
+ expect(result[1..2]).to match_array [article_2, article_3]
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ context 'with other resource' do
117
+ it 'works' do
118
+ expect(User.order_by_rating(:total, :desc)).to match_array [user_1, user_2]
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':rate_for' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ it 'delegates to rate object' do
10
+ expect(Rating::Rate).to receive(:rate_for).with author: user, resource: article
11
+
12
+ user.rate_for article
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':rate' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ it 'delegates to rate object' do
10
+ expect(Rating::Rate).to receive(:create).with author: user, resource: article, value: 3
11
+
12
+ user.rate article, 3
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':rated?' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ context 'when has no rate for the given resource' do
10
+ before { allow(user).to receive(:rate_for).with(article) { nil } }
11
+
12
+ specify { expect(user.rated?(article)).to eq false }
13
+ end
14
+
15
+ context 'when has rate for the given resource' do
16
+ before { allow(user).to receive(:rate_for).with(article) { double } }
17
+
18
+ specify { expect(user.rated?(article)).to eq true }
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':rated' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ before { user.rate article, 3 }
10
+
11
+ it 'returns rates made by the caller' do
12
+ expect(user.rated).to eq [Rating::Rate.find_by(resource: article)]
13
+ end
14
+
15
+ context 'when destroy author' do
16
+ before do
17
+ expect(Rating::Rate.where(author: user).count).to eq 1
18
+
19
+ user.destroy!
20
+ end
21
+
22
+ it 'destroys rates of this author' do
23
+ expect(Rating::Rate.where(author: user).count).to eq 0
24
+ end
25
+ end
26
+
27
+ context 'when destroy resource rated by author' do
28
+ before do
29
+ expect(Rating::Rate.where(resource: article).count).to eq 1
30
+
31
+ article.destroy!
32
+ end
33
+
34
+ it 'destroys rates for that resource' do
35
+ expect(Rating::Rate.where(resource: article).count).to eq 0
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':rates' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ before { user.rate article, 3 }
10
+
11
+ it 'returns rates record' do
12
+ expect(article.rates).to eq [Rating::Rate.last]
13
+ end
14
+
15
+ context 'when destroy author' do
16
+ before do
17
+ expect(Rating::Rate.where(resource: article).count).to eq 1
18
+
19
+ user.destroy!
20
+ end
21
+
22
+ it 'destroys rates of that resource' do
23
+ expect(Rating::Rate.where(resource: article).count).to eq 0
24
+ end
25
+ end
26
+
27
+ context 'when destroy resource' do
28
+ before do
29
+ expect(Rating::Rate.where(resource: article).count).to eq 1
30
+
31
+ article.destroy!
32
+ end
33
+
34
+ it 'destroys rates of that resource' do
35
+ expect(Rating::Rate.where(resource: article).count).to eq 0
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, ':rating' do
6
+ let!(:user_1) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ before { user_1.rate article, 1 }
10
+
11
+ it 'returns rating record' do
12
+ expect(article.rating).to eq Rating::Rating.last
13
+ end
14
+
15
+ context 'when destroy author' do
16
+ let!(:user_2) { create :user }
17
+
18
+ before { user_2.rate article, 2 }
19
+
20
+ it 'does not destroy resource rating' do
21
+ expect(Rating::Rating.where(resource: article).count).to eq 1
22
+
23
+ user_1.destroy!
24
+
25
+ expect(Rating::Rating.where(resource: article).count).to eq 1
26
+ end
27
+ end
28
+
29
+ context 'when destroy resource' do
30
+ it 'destroys resource rating too' do
31
+ expect(Rating::Rating.where(resource: article).count).to eq 1
32
+
33
+ article.destroy!
34
+
35
+ expect(Rating::Rating.where(resource: article).count).to eq 0
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Rate, ':create' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ before { create :rating_rate, author: user, resource: article, value: 3 }
10
+
11
+ context 'when rate does not exist yet' do
12
+ it 'creates a rate entry' do
13
+ rate = described_class.last
14
+
15
+ expect(rate.author).to eq user
16
+ expect(rate.resource).to eq article
17
+ expect(rate.value).to eq 3
18
+ end
19
+
20
+ it 'creates a rating entry' do
21
+ rating = Rating::Rating.last
22
+
23
+ expect(rating.average).to eq 3
24
+ expect(rating.estimate).to eq 3
25
+ expect(rating.resource).to eq article
26
+ expect(rating.sum).to eq 3
27
+ expect(rating.total).to eq 1
28
+ end
29
+ end
30
+
31
+ context 'when rate already exists' do
32
+ let!(:user_2) { create :user }
33
+
34
+ before { create :rating_rate, author: user_2, resource: article, value: 4 }
35
+
36
+ it 'creates one more rate entry' do
37
+ rates = described_class.where(author: [user, user_2]).order('created_at asc')
38
+
39
+ expect(rates.size).to eq 2
40
+
41
+ rate = rates[0]
42
+
43
+ expect(rate.author).to eq user
44
+ expect(rate.resource).to eq article
45
+ expect(rate.value).to eq 3
46
+
47
+ rate = rates[1]
48
+
49
+ expect(rate.author).to eq user_2
50
+ expect(rate.resource).to eq article
51
+ expect(rate.value).to eq 4
52
+ end
53
+
54
+ it 'updates the unique rating entry' do
55
+ rating = Rating::Rating.find_by(resource: article)
56
+
57
+ expect(rating.average).to eq 3.5
58
+ expect(rating.estimate).to eq 3.5
59
+ expect(rating.resource).to eq article
60
+ expect(rating.sum).to eq 7
61
+ expect(rating.total).to eq 2
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Rate, ':rate_for' do
6
+ let!(:user) { create :user }
7
+ let!(:article) { create :article }
8
+
9
+ context 'when rate does not exist' do
10
+ specify { expect(described_class.rate_for(author: user, resource: article)).to eq nil }
11
+ end
12
+
13
+ context 'when rate does not exist' do
14
+ before { described_class.create author: user, resource: article, value: 3 }
15
+
16
+ it 'returns the record' do
17
+ expect(described_class.rate_for(author: user, resource: article)).to eq described_class.last
18
+ end
19
+ end
20
+ end