rating 0.1.0 → 0.2.0

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