rating 0.1.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 (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