rating 0.1.0 → 0.2.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +111 -5
  4. data/lib/generators/rating/install_generator.rb +7 -3
  5. data/lib/generators/rating/templates/db/migrate/create_rating_tables.rb +10 -6
  6. data/lib/rating/models/rating/extension.rb +32 -13
  7. data/lib/rating/models/rating/rate.rb +9 -8
  8. data/lib/rating/models/rating/rating.rb +34 -17
  9. data/lib/rating/version.rb +1 -1
  10. data/spec/factories/article.rb +1 -1
  11. data/spec/factories/author.rb +7 -0
  12. data/spec/factories/category.rb +7 -0
  13. data/spec/factories/user.rb +1 -1
  14. data/spec/models/extension/after_create_spec.rb +16 -7
  15. data/spec/models/extension/order_by_rating_spec.rb +75 -0
  16. data/spec/models/extension/rate_for_spec.rb +15 -3
  17. data/spec/models/extension/rate_spec.rb +15 -3
  18. data/spec/models/extension/rated_question_spec.rb +24 -6
  19. data/spec/models/extension/rated_records_spec.rb +26 -0
  20. data/spec/models/extension/rated_spec.rb +33 -13
  21. data/spec/models/extension/rates_records_spec.rb +26 -0
  22. data/spec/models/extension/rates_spec.rb +33 -17
  23. data/spec/models/extension/rating_records_spec.rb +28 -0
  24. data/spec/models/extension/rating_spec.rb +31 -15
  25. data/spec/models/rate/create_spec.rb +104 -37
  26. data/spec/models/rate/rate_for_spec.rb +26 -6
  27. data/spec/models/rate_spec.rb +2 -1
  28. data/spec/models/rating/averager_data_spec.rb +24 -5
  29. data/spec/models/rating/data_spec.rb +38 -11
  30. data/spec/models/rating/update_rating_spec.rb +24 -6
  31. data/spec/models/rating/values_data_spec.rb +31 -8
  32. data/spec/models/rating_spec.rb +1 -0
  33. data/spec/support/db/migrate/create_authors_table.rb +9 -0
  34. data/spec/support/db/migrate/create_category_spec.rb +9 -0
  35. data/spec/support/migrate.rb +3 -1
  36. data/spec/support/models/author.rb +5 -0
  37. data/spec/support/models/category.rb +4 -0
  38. metadata +22 -20
  39. data/spec/support/html_matchers.rb +0 -7
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe Rating::Extension, '.rating' do
6
+ let!(:category) { create :category }
7
+
8
+ let!(:user_1) { create :user }
9
+ let!(:user_2) { create :user }
10
+
11
+ let!(:article_1) { create :article }
12
+ let!(:article_2) { create :article }
13
+ let!(:article_3) { create :article }
14
+
15
+ before do
16
+ create :rating_rate, author: user_1, resource: article_1, value: 100
17
+ create :rating_rate, author: user_1, resource: article_2, value: 11
18
+ create :rating_rate, author: user_1, resource: article_3, value: 10
19
+ create :rating_rate, author: user_2, resource: article_1, value: 1
20
+
21
+ create :rating_rate, author: user_1, resource: article_1, scopeable: category, value: 1
22
+ create :rating_rate, author: user_2, resource: article_1, scopeable: category, value: 2
23
+ end
24
+
25
+ it 'returns all rating of this resource' do
26
+ expect(article_1.rating_records).to match_array Rating::Rating.where(resource: article_1)
27
+ end
28
+ end
@@ -2,37 +2,53 @@
2
2
 
3
3
  require 'rails_helper'
4
4
 
5
- RSpec.describe Rating::Extension, ':rating' do
6
- let!(:user_1) { create :user }
7
- let!(:article) { create :article }
5
+ RSpec.describe Rating::Extension, '.rating' do
6
+ let!(:category) { create :category }
8
7
 
9
- before { user_1.rate article, 1 }
8
+ let!(:user_1) { create :user }
9
+ let!(:user_2) { create :user }
10
10
 
11
- it 'returns rating record' do
12
- expect(article.rating).to eq Rating::Rating.last
13
- end
11
+ let!(:article_1) { create :article }
12
+ let!(:article_2) { create :article }
13
+ let!(:article_3) { create :article }
14
14
 
15
- context 'when destroy author' do
16
- let!(:user_2) { create :user }
15
+ let!(:rate_1) { create :rating_rate, author: user_1, resource: article_1, value: 100 }
16
+ let!(:rate_2) { create :rating_rate, author: user_1, resource: article_2, value: 11 }
17
+ let!(:rate_3) { create :rating_rate, author: user_1, resource: article_3, value: 10 }
18
+ let!(:rate_4) { create :rating_rate, author: user_2, resource: article_1, value: 1 }
19
+
20
+ let!(:rate_5) { create :rating_rate, author: user_1, resource: article_1, scopeable: category, value: 1 }
21
+ let!(:rate_6) { create :rating_rate, author: user_2, resource: article_1, scopeable: category, value: 2 }
17
22
 
18
- before { user_2.rate article, 2 }
23
+ context 'with no scope' do
24
+ it 'returns rating record' do
25
+ expect(article_1.rating).to eq Rating::Rating.find_by(resource: article_1, scopeable: nil)
26
+ end
27
+ end
19
28
 
29
+ context 'with scope' do
30
+ it 'returns scoped rating record' do
31
+ expect(article_1.rating(scope: category)).to eq Rating::Rating.find_by(resource: article_1, scopeable: category)
32
+ end
33
+ end
34
+
35
+ context 'when destroy author' do
20
36
  it 'does not destroy resource rating' do
21
- expect(Rating::Rating.where(resource: article).count).to eq 1
37
+ expect(Rating::Rating.where(resource: article_1).count).to eq 2
22
38
 
23
39
  user_1.destroy!
24
40
 
25
- expect(Rating::Rating.where(resource: article).count).to eq 1
41
+ expect(Rating::Rating.where(resource: article_1).count).to eq 2
26
42
  end
27
43
  end
28
44
 
29
45
  context 'when destroy resource' do
30
46
  it 'destroys resource rating too' do
31
- expect(Rating::Rating.where(resource: article).count).to eq 1
47
+ expect(Rating::Rating.where(resource: article_1).count).to eq 2
32
48
 
33
- article.destroy!
49
+ article_1.destroy!
34
50
 
35
- expect(Rating::Rating.where(resource: article).count).to eq 0
51
+ expect(Rating::Rating.where(resource: article_1).count).to eq 0
36
52
  end
37
53
  end
38
54
  end
@@ -6,59 +6,126 @@ RSpec.describe Rating::Rate, ':create' do
6
6
  let!(:user) { create :user }
7
7
  let!(:article) { create :article }
8
8
 
9
- before { create :rating_rate, author: user, resource: article, value: 3 }
9
+ context 'with no scopeable' do
10
+ before { create :rating_rate, author: user, resource: article, value: 3 }
11
+
12
+ context 'when rate does not exist yet' do
13
+ it 'creates a rate entry' do
14
+ rate = described_class.last
15
+
16
+ expect(rate.author).to eq user
17
+ expect(rate.resource).to eq article
18
+ expect(rate.value).to eq 3
19
+ end
20
+
21
+ it 'creates a rating entry' do
22
+ rating = Rating::Rating.last
23
+
24
+ expect(rating.average).to eq 3
25
+ expect(rating.estimate).to eq 3
26
+ expect(rating.resource).to eq article
27
+ expect(rating.sum).to eq 3
28
+ expect(rating.total).to eq 1
29
+ end
30
+ end
10
31
 
11
- context 'when rate does not exist yet' do
12
- it 'creates a rate entry' do
13
- rate = described_class.last
32
+ context 'when rate already exists' do
33
+ let!(:user_2) { create :user }
14
34
 
15
- expect(rate.author).to eq user
16
- expect(rate.resource).to eq article
17
- expect(rate.value).to eq 3
18
- end
35
+ before { create :rating_rate, author: user_2, resource: article, value: 4 }
36
+
37
+ it 'creates one more rate entry' do
38
+ rates = described_class.where(author: [user, user_2]).order('created_at asc')
39
+
40
+ expect(rates.size).to eq 2
41
+
42
+ rate = rates[0]
43
+
44
+ expect(rate.author).to eq user
45
+ expect(rate.resource).to eq article
46
+ expect(rate.value).to eq 3
47
+
48
+ rate = rates[1]
49
+
50
+ expect(rate.author).to eq user_2
51
+ expect(rate.resource).to eq article
52
+ expect(rate.value).to eq 4
53
+ end
19
54
 
20
- it 'creates a rating entry' do
21
- rating = Rating::Rating.last
55
+ it 'updates the unique rating entry' do
56
+ rating = Rating::Rating.find_by(resource: article)
22
57
 
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
58
+ expect(rating.average).to eq 3.5
59
+ expect(rating.estimate).to eq 3.5
60
+ expect(rating.resource).to eq article
61
+ expect(rating.sum).to eq 7
62
+ expect(rating.total).to eq 2
63
+ end
28
64
  end
29
65
  end
30
66
 
31
- context 'when rate already exists' do
32
- let!(:user_2) { create :user }
67
+ context 'with scopeable' do
68
+ let!(:category) { create :category }
33
69
 
34
- before { create :rating_rate, author: user_2, resource: article, value: 4 }
70
+ before { create :rating_rate, author: user, resource: article, scopeable: category, value: 3 }
35
71
 
36
- it 'creates one more rate entry' do
37
- rates = described_class.where(author: [user, user_2]).order('created_at asc')
72
+ context 'when rate does not exist yet' do
73
+ it 'creates a rate entry' do
74
+ rate = described_class.last
38
75
 
39
- expect(rates.size).to eq 2
76
+ expect(rate.author).to eq user
77
+ expect(rate.resource).to eq article
78
+ expect(rate.scopeable).to eq category
79
+ expect(rate.value).to eq 3
80
+ end
40
81
 
41
- rate = rates[0]
82
+ it 'creates a rating entry' do
83
+ rating = Rating::Rating.last
42
84
 
43
- expect(rate.author).to eq user
44
- expect(rate.resource).to eq article
45
- expect(rate.value).to eq 3
85
+ expect(rating.average).to eq 3
86
+ expect(rating.estimate).to eq 3
87
+ expect(rating.resource).to eq article
88
+ expect(rating.scopeable).to eq category
89
+ expect(rating.sum).to eq 3
90
+ expect(rating.total).to eq 1
91
+ end
92
+ end
46
93
 
47
- rate = rates[1]
94
+ context 'when rate already exists' do
95
+ let!(:user_2) { create :user }
48
96
 
49
- expect(rate.author).to eq user_2
50
- expect(rate.resource).to eq article
51
- expect(rate.value).to eq 4
52
- end
97
+ before { create :rating_rate, author: user_2, resource: article, scopeable: category, value: 4 }
98
+
99
+ it 'creates one more rate entry' do
100
+ rates = described_class.where(author: [user, user_2]).order('created_at asc')
101
+
102
+ expect(rates.size).to eq 2
103
+
104
+ rate = rates[0]
105
+
106
+ expect(rate.author).to eq user
107
+ expect(rate.resource).to eq article
108
+ expect(rate.scopeable).to eq category
109
+ expect(rate.value).to eq 3
110
+
111
+ rate = rates[1]
112
+
113
+ expect(rate.author).to eq user_2
114
+ expect(rate.resource).to eq article
115
+ expect(rate.scopeable).to eq category
116
+ expect(rate.value).to eq 4
117
+ end
53
118
 
54
- it 'updates the unique rating entry' do
55
- rating = Rating::Rating.find_by(resource: article)
119
+ it 'updates the unique rating entry' do
120
+ rating = Rating::Rating.find_by(resource: article, scopeable: category)
56
121
 
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
122
+ expect(rating.average).to eq 3.5
123
+ expect(rating.estimate).to eq 3.5
124
+ expect(rating.resource).to eq article
125
+ expect(rating.scopeable).to eq category
126
+ expect(rating.sum).to eq 7
127
+ expect(rating.total).to eq 2
128
+ end
62
129
  end
63
130
  end
64
131
  end
@@ -6,15 +6,35 @@ RSpec.describe Rating::Rate, ':rate_for' do
6
6
  let!(:user) { create :user }
7
7
  let!(:article) { create :article }
8
8
 
9
- context 'when rate does not exist' do
10
- specify { expect(described_class.rate_for(author: user, resource: article)).to eq nil }
9
+ context 'with no scopeable' do
10
+ context 'when rate does not exist' do
11
+ specify { expect(described_class.rate_for(author: user, resource: article)).to eq nil }
12
+ end
13
+
14
+ context 'when rate does not exist' do
15
+ before { described_class.create author: user, resource: article, value: 3 }
16
+
17
+ it 'returns the record' do
18
+ expect(described_class.rate_for(author: user, resource: article)).to eq described_class.last
19
+ end
20
+ end
11
21
  end
12
22
 
13
- context 'when rate does not exist' do
14
- before { described_class.create author: user, resource: article, value: 3 }
23
+ context 'with scopeable' do
24
+ let!(:category) { create :category }
25
+
26
+ context 'when rate does not exist' do
27
+ specify { expect(described_class.rate_for(author: user, resource: article, scopeable: category)).to eq nil }
28
+ end
29
+
30
+ context 'when rate does not exist' do
31
+ before { described_class.create author: user, resource: article, scopeable: category, value: 3 }
32
+
33
+ it 'returns the record' do
34
+ query = described_class.rate_for(author: user, resource: article, scopeable: category)
15
35
 
16
- it 'returns the record' do
17
- expect(described_class.rate_for(author: user, resource: article)).to eq described_class.last
36
+ expect(query).to eq described_class.last
37
+ end
18
38
  end
19
39
  end
20
40
  end
@@ -9,6 +9,7 @@ RSpec.describe Rating::Rate do
9
9
 
10
10
  it { is_expected.to belong_to :author }
11
11
  it { is_expected.to belong_to :resource }
12
+ it { is_expected.to belong_to :scopeable }
12
13
 
13
14
  it { is_expected.to validate_presence_of :author }
14
15
  it { is_expected.to validate_presence_of :resource }
@@ -20,7 +21,7 @@ RSpec.describe Rating::Rate do
20
21
 
21
22
  specify do
22
23
  expect(object).to validate_uniqueness_of(:author_id)
23
- .scoped_to(%i[author_type resource_id resource_type])
24
+ .scoped_to(%i[author_type resource_id resource_type scopeable_id scopeable_type])
24
25
  .case_insensitive
25
26
  end
26
27
  end
@@ -3,7 +3,7 @@
3
3
  require 'rails_helper'
4
4
 
5
5
  RSpec.describe Rating::Rating, ':averager_data' do
6
- subject { described_class.averager_data article_1 }
6
+ let!(:category) { create :category }
7
7
 
8
8
  let!(:user_1) { create :user }
9
9
  let!(:user_2) { create :user }
@@ -17,13 +17,32 @@ RSpec.describe Rating::Rating, ':averager_data' do
17
17
  create :rating_rate, author: user_1, resource: article_2, value: 11
18
18
  create :rating_rate, author: user_1, resource: article_3, value: 10
19
19
  create :rating_rate, author: user_2, resource: article_1, value: 1
20
+
21
+ create :rating_rate, author: user_1, resource: article_1, scopeable: category, value: 1
22
+ create :rating_rate, author: user_2, resource: article_1, scopeable: category, value: 2
20
23
  end
21
24
 
22
- it 'returns the values average of given resource type' do
23
- expect(subject.as_json['rating_avg']).to eq 30.5
25
+ context 'with no scopeable' do
26
+ subject { described_class.averager_data article_1, nil }
27
+
28
+ it 'returns the values average of given resource type' do
29
+ expect(subject.as_json['rating_avg']).to eq 30.5
30
+ end
31
+
32
+ it 'returns the average of number of records for the given resource type' do
33
+ expect(subject.as_json['count_avg']).to eq 1.3333333333333333
34
+ end
24
35
  end
25
36
 
26
- it 'returns the average of number of records for the given resource type' do
27
- expect(subject.as_json['count_avg']).to eq 1.3333333333333333
37
+ context 'with scopeable' do
38
+ subject { described_class.averager_data article_1, category }
39
+
40
+ it 'returns the values average of given resource type' do
41
+ expect(subject.as_json['rating_avg']).to eq 1.5
42
+ end
43
+
44
+ it 'returns the average of number of records for the given resource type' do
45
+ expect(subject.as_json['count_avg']).to eq 2
46
+ end
28
47
  end
29
48
  end
@@ -3,7 +3,7 @@
3
3
  require 'rails_helper'
4
4
 
5
5
  RSpec.describe Rating::Rating, ':data' do
6
- subject { described_class.data article_1 }
6
+ let!(:category) { create :category }
7
7
 
8
8
  let!(:user_1) { create :user }
9
9
  let!(:user_2) { create :user }
@@ -17,21 +17,48 @@ RSpec.describe Rating::Rating, ':data' do
17
17
  create :rating_rate, author: user_1, resource: article_2, value: 11
18
18
  create :rating_rate, author: user_1, resource: article_3, value: 10
19
19
  create :rating_rate, author: user_2, resource: article_1, value: 1
20
- end
21
20
 
22
- it 'returns the average of value for a resource' do
23
- expect(subject[:average]).to eq 50.5
21
+ create :rating_rate, author: user_1, resource: article_1, scopeable: category, value: 1
22
+ create :rating_rate, author: user_2, resource: article_1, scopeable: category, value: 2
24
23
  end
25
24
 
26
- it 'returns the sum of values for a resource' do
27
- expect(subject[:sum]).to eq 101
28
- end
25
+ context 'with no scopeable' do
26
+ subject { described_class.data article_1, nil }
27
+
28
+ it 'returns the average of value for a resource' do
29
+ expect(subject[:average]).to eq 50.5
30
+ end
31
+
32
+ it 'returns the sum of values for a resource' do
33
+ expect(subject[:sum]).to eq 101
34
+ end
35
+
36
+ it 'returns the count of votes for a resource' do
37
+ expect(subject[:total]).to eq 2
38
+ end
29
39
 
30
- it 'returns the count of votes for a resource' do
31
- expect(subject[:total]).to eq 2
40
+ it 'returns the estimate for a resource' do
41
+ expect(subject[:estimate]).to eq 42.50000000000001
42
+ end
32
43
  end
33
44
 
34
- it 'returns the estimate for a resource' do
35
- expect(subject[:estimate]).to eq 42.50000000000001
45
+ context 'with scopeable' do
46
+ subject { described_class.data article_1, category }
47
+
48
+ it 'returns the average of value for a resource' do
49
+ expect(subject[:average]).to eq 1.5
50
+ end
51
+
52
+ it 'returns the sum of values for a resource' do
53
+ expect(subject[:sum]).to eq 3
54
+ end
55
+
56
+ it 'returns the count of votes for a resource' do
57
+ expect(subject[:total]).to eq 2
58
+ end
59
+
60
+ it 'returns the estimate for a resource' do
61
+ expect(subject[:estimate]).to eq 1.5
62
+ end
36
63
  end
37
64
  end
@@ -3,6 +3,8 @@
3
3
  require 'rails_helper'
4
4
 
5
5
  RSpec.describe Rating::Rating, ':update_rating' do
6
+ let!(:category) { create :category }
7
+
6
8
  let!(:user_1) { create :user }
7
9
  let!(:user_2) { create :user }
8
10
 
@@ -15,14 +17,30 @@ RSpec.describe Rating::Rating, ':update_rating' do
15
17
  create :rating_rate, author: user_1, resource: article_2, value: 11
16
18
  create :rating_rate, author: user_1, resource: article_3, value: 10
17
19
  create :rating_rate, author: user_2, resource: article_1, value: 1
20
+
21
+ create :rating_rate, author: user_1, resource: article_1, scopeable: category, value: 1
22
+ create :rating_rate, author: user_2, resource: article_1, scopeable: category, value: 2
23
+ end
24
+
25
+ context 'with no scopeable' do
26
+ it 'updates the rating data of the given resource' do
27
+ record = described_class.find_by(resource: article_1)
28
+
29
+ expect(record.average).to eq 50.50000000000001
30
+ expect(record.estimate).to eq 42.50000000000001
31
+ expect(record.sum).to eq 101
32
+ expect(record.total).to eq 2
33
+ end
18
34
  end
19
35
 
20
- it 'updates the rating data of the given resource' do
21
- record = described_class.find_by(resource: article_1)
36
+ context 'with scopeable' do
37
+ it 'updates the rating data of the given resource respecting the scope' do
38
+ record = described_class.find_by(resource: article_1, scopeable: category)
22
39
 
23
- expect(record.average).to eq 50.50000000000001
24
- expect(record.estimate).to eq 42.50000000000001
25
- expect(record.sum).to eq 101
26
- expect(record.total).to eq 2
40
+ expect(record.average).to eq 1.5
41
+ expect(record.estimate).to eq 1.5
42
+ expect(record.sum).to eq 3
43
+ expect(record.total).to eq 2
44
+ end
27
45
  end
28
46
  end