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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +111 -5
- data/lib/generators/rating/install_generator.rb +7 -3
- data/lib/generators/rating/templates/db/migrate/create_rating_tables.rb +10 -6
- data/lib/rating/models/rating/extension.rb +32 -13
- data/lib/rating/models/rating/rate.rb +9 -8
- data/lib/rating/models/rating/rating.rb +34 -17
- data/lib/rating/version.rb +1 -1
- data/spec/factories/article.rb +1 -1
- data/spec/factories/author.rb +7 -0
- data/spec/factories/category.rb +7 -0
- data/spec/factories/user.rb +1 -1
- data/spec/models/extension/after_create_spec.rb +16 -7
- data/spec/models/extension/order_by_rating_spec.rb +75 -0
- data/spec/models/extension/rate_for_spec.rb +15 -3
- data/spec/models/extension/rate_spec.rb +15 -3
- data/spec/models/extension/rated_question_spec.rb +24 -6
- data/spec/models/extension/rated_records_spec.rb +26 -0
- data/spec/models/extension/rated_spec.rb +33 -13
- data/spec/models/extension/rates_records_spec.rb +26 -0
- data/spec/models/extension/rates_spec.rb +33 -17
- data/spec/models/extension/rating_records_spec.rb +28 -0
- data/spec/models/extension/rating_spec.rb +31 -15
- data/spec/models/rate/create_spec.rb +104 -37
- data/spec/models/rate/rate_for_spec.rb +26 -6
- data/spec/models/rate_spec.rb +2 -1
- data/spec/models/rating/averager_data_spec.rb +24 -5
- data/spec/models/rating/data_spec.rb +38 -11
- data/spec/models/rating/update_rating_spec.rb +24 -6
- data/spec/models/rating/values_data_spec.rb +31 -8
- data/spec/models/rating_spec.rb +1 -0
- data/spec/support/db/migrate/create_authors_table.rb +9 -0
- data/spec/support/db/migrate/create_category_spec.rb +9 -0
- data/spec/support/migrate.rb +3 -1
- data/spec/support/models/author.rb +5 -0
- data/spec/support/models/category.rb +4 -0
- metadata +22 -20
- 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, '
|
6
|
-
let!(:
|
7
|
-
let!(:article) { create :article }
|
5
|
+
RSpec.describe Rating::Extension, '.rating' do
|
6
|
+
let!(:category) { create :category }
|
8
7
|
|
9
|
-
|
8
|
+
let!(:user_1) { create :user }
|
9
|
+
let!(:user_2) { create :user }
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
let!(:article_1) { create :article }
|
12
|
+
let!(:article_2) { create :article }
|
13
|
+
let!(:article_3) { create :article }
|
14
14
|
|
15
|
-
|
16
|
-
|
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
|
-
|
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:
|
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:
|
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:
|
47
|
+
expect(Rating::Rating.where(resource: article_1).count).to eq 2
|
32
48
|
|
33
|
-
|
49
|
+
article_1.destroy!
|
34
50
|
|
35
|
-
expect(Rating::Rating.where(resource:
|
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
|
-
|
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
|
-
|
12
|
-
|
13
|
-
rate = described_class.last
|
32
|
+
context 'when rate already exists' do
|
33
|
+
let!(:user_2) { create :user }
|
14
34
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
55
|
+
it 'updates the unique rating entry' do
|
56
|
+
rating = Rating::Rating.find_by(resource: article)
|
22
57
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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 '
|
32
|
-
let!(:
|
67
|
+
context 'with scopeable' do
|
68
|
+
let!(:category) { create :category }
|
33
69
|
|
34
|
-
before { create :rating_rate, author:
|
70
|
+
before { create :rating_rate, author: user, resource: article, scopeable: category, value: 3 }
|
35
71
|
|
36
|
-
|
37
|
-
|
72
|
+
context 'when rate does not exist yet' do
|
73
|
+
it 'creates a rate entry' do
|
74
|
+
rate = described_class.last
|
38
75
|
|
39
|
-
|
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
|
-
|
82
|
+
it 'creates a rating entry' do
|
83
|
+
rating = Rating::Rating.last
|
42
84
|
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
94
|
+
context 'when rate already exists' do
|
95
|
+
let!(:user_2) { create :user }
|
48
96
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
119
|
+
it 'updates the unique rating entry' do
|
120
|
+
rating = Rating::Rating.find_by(resource: article, scopeable: category)
|
56
121
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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 '
|
10
|
-
|
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 '
|
14
|
-
|
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
|
-
|
17
|
-
|
36
|
+
expect(query).to eq described_class.last
|
37
|
+
end
|
18
38
|
end
|
19
39
|
end
|
20
40
|
end
|
data/spec/models/rate_spec.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
35
|
-
|
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
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|