From f9de473ea4c16a6cc4454bb04e42290727e51401 Mon Sep 17 00:00:00 2001 From: Washington Botelho Date: Thu, 1 Mar 2018 17:50:28 -0300 Subject: [PATCH] feat: adds extra scopes option --- lib/rating/models/rating/extension.rb | 32 +++++++++++------ spec/models/extension/rate_for_spec.rb | 19 ++++++++-- spec/models/extension/rate_spec.rb | 20 +++++++---- spec/models/extension/rated_question_spec.rb | 38 ++++++++++++-------- spec/models/extension/rated_spec.rb | 8 +++++ spec/models/extension/rates_spec.rb | 8 +++++ spec/models/rate/create_spec.rb | 4 +-- spec/models/rate/rate_for_spec.rb | 4 +-- spec/models/rate_spec.rb | 7 ++-- spec/support/migrate.rb | 1 + 10 files changed, 99 insertions(+), 42 deletions(-) diff --git a/lib/rating/models/rating/extension.rb b/lib/rating/models/rating/extension.rb index cd601ff..0c7aee1 100644 --- a/lib/rating/models/rating/extension.rb +++ b/lib/rating/models/rating/extension.rb @@ -5,24 +5,36 @@ module Rating extend ActiveSupport::Concern included do - def rate(resource, value, author: self, metadata: {}, scope: nil) - Rate.create author: author, metadata: metadata, resource: resource, scopeable: scope, value: value + def rate(resource, value, author: self, extra_scopes: {}, metadata: {}, scope: nil) + Rate.create( + author: author, + extra_scopes: extra_scopes, + metadata: metadata, + resource: resource, + scopeable: scope, + value: value + ) end - def rate_for(resource, scope: nil) - Rate.rate_for author: self, resource: resource, scopeable: scope + def rate_for(resource, extra_scopes: {}, scope: nil) + Rate.rate_for author: self, extra_scopes: extra_scopes, resource: resource, scopeable: scope end - def rated?(resource, scope: nil) - !rate_for(resource, scope: scope).nil? + # TODO: use exists for performance + def rated?(resource, extra_scopes: {}, scope: nil) + !rate_for(resource, extra_scopes: extra_scopes, scope: scope).nil? end - def rates(scope: nil) - rates_records.where scopeable: scope + def rates(extra_scopes: {}, scope: nil) + attributes = { scopeable: scope }.merge(extra_scopes) + + rates_records.where attributes end - def rated(scope: nil) - rated_records.where scopeable: scope + def rated(extra_scopes: {}, scope: nil) + attributes = { scopeable: scope }.merge(extra_scopes) + + rated_records.where attributes end def rating(scope: nil) diff --git a/spec/models/extension/rate_for_spec.rb b/spec/models/extension/rate_for_spec.rb index c3682f5..30aa237 100644 --- a/spec/models/extension/rate_for_spec.rb +++ b/spec/models/extension/rate_for_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Rating::Extension, ':rate_for' do context 'with no scopeable' do it 'delegates to rate object' do - expect(Rating::Rate).to receive(:rate_for).with author: author, resource: article, scopeable: nil + expect(Rating::Rate).to receive(:rate_for).with author: author, extra_scopes: {}, resource: article, scopeable: nil author.rate_for article end @@ -18,9 +18,24 @@ RSpec.describe Rating::Extension, ':rate_for' do let!(:category) { build :category } it 'delegates to rate object' do - expect(Rating::Rate).to receive(:rate_for).with author: author, resource: article, scopeable: category + expect(Rating::Rate).to receive(:rate_for).with author: author, extra_scopes: {}, resource: article, scopeable: category author.rate_for article, scope: category end end + + context 'with extra_scopes' do + let!(:category) { build :category } + + it 'delegates to rate object' do + expect(Rating::Rate).to receive(:rate_for).with( + author: author, + extra_scopes: { scope_1: 'scope_1' }, + resource: article, + scopeable: category + ) + + author.rate_for article, extra_scopes: { scope_1: 'scope_1' }, scope: category + end + end end diff --git a/spec/models/extension/rate_spec.rb b/spec/models/extension/rate_spec.rb index 1dc5e00..8163a1f 100644 --- a/spec/models/extension/rate_spec.rb +++ b/spec/models/extension/rate_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Rating::Extension, ':rate' do context 'with no scopeable' do it 'delegates to rate object' do expect(Rating::Rate).to receive(:create).with( - author: author, metadata: {}, resource: article, scopeable: nil, value: 3 + author: author, extra_scopes: {}, metadata: {}, resource: article, scopeable: nil, value: 3 ) author.rate article, 3 @@ -21,7 +21,7 @@ RSpec.describe Rating::Extension, ':rate' do it 'delegates to rate object' do expect(Rating::Rate).to receive(:create).with( - author: author, metadata: {}, resource: article, scopeable: category, value: 3 + author: author, extra_scopes: {}, metadata: {}, resource: article, scopeable: category, value: 3 ) author.rate article, 3, scope: category @@ -31,7 +31,7 @@ RSpec.describe Rating::Extension, ':rate' do context 'with no metadata' do it 'delegates an empty hash to rate object' do expect(Rating::Rate).to receive(:create).with( - author: author, resource: article, metadata: {}, scopeable: nil, value: 3 + author: author, extra_scopes: {}, resource: article, metadata: {}, scopeable: nil, value: 3 ) author.rate article, 3 @@ -39,14 +39,22 @@ RSpec.describe Rating::Extension, ':rate' do end context 'with metadata' do - let!(:category) { build :category } - it 'delegates to rate object' do expect(Rating::Rate).to receive(:create).with( - author: author, metadata: { comment: 'comment' }, resource: article, scopeable: nil, value: 3 + author: author, extra_scopes: {}, metadata: { comment: 'comment' }, resource: article, scopeable: nil, value: 3 ) author.rate article, 3, metadata: { comment: 'comment' } end end + + context 'with extra_scopes' do + it 'delegates to rate object' do + expect(Rating::Rate).to receive(:create).with( + author: author, extra_scopes: { scope_1: 'scope_1' }, metadata: { comment: 'comment' }, resource: article, scopeable: nil, value: 3 + ) + + author.rate article, 3, extra_scopes: { scope_1: 'scope_1' }, metadata: { comment: 'comment' } + end + end end diff --git a/spec/models/extension/rated_question_spec.rb b/spec/models/extension/rated_question_spec.rb index fad5483..5189245 100644 --- a/spec/models/extension/rated_question_spec.rb +++ b/spec/models/extension/rated_question_spec.rb @@ -3,36 +3,44 @@ require 'rails_helper' RSpec.describe Rating::Extension, ':rated?' do - let!(:author) { create :author } - let!(:article) { create :article } + let!(:author) { create :author } + let!(:resource) { create :article } context 'with no scopeable' do - context 'when has no rate for the given resource' do - before { allow(author).to receive(:rate_for).with(article, scope: nil).and_return nil } + before { author.rate resource, 1 } - specify { expect(author.rated?(article)).to eq false } + context 'when has no rate for the given resource' do + specify { expect(author.rated?(create(:article))).to eq false } end context 'when has rate for the given resource' do - before { allow(author).to receive(:rate_for).with(article, scope: nil).and_return double } - - specify { expect(author.rated?(article)).to eq true } + specify { expect(author.rated?(resource)).to eq true } end end context 'with scopeable' do - let!(:category) { build :category } + let!(:category) { create :category } + + before { author.rate resource, 1, scope: category } context 'when has no rate for the given resource' do - before { allow(author).to receive(:rate_for).with(article, scope: category).and_return nil } - - specify { expect(author.rated?(article, scope: category)).to eq false } + specify { expect(author.rated?(resource, scope: create(:category))).to eq false } end context 'when has rate for the given resource' do - before { allow(author).to receive(:rate_for).with(article, scope: category).and_return double } - - specify { expect(author.rated?(article, scope: category)).to eq true } + specify { expect(author.rated?(resource, scope: category)).to eq true } end end + + context 'with extra scopes' do + before { author.rate resource, 1, extra_scopes: { scope_1: 'scope_1' } } + + context 'when has no rate for the given resource with given extra scopes' do + specify { expect(author.rated?(resource, extra_scopes: { scope_1: 'missing' })).to eq false } + end + + context 'when has rate for the given resource with given extra scopes' do + specify { expect(author.rated?(resource, extra_scopes: { scope_1: 'scope_1' })).to eq true } + end + end if ENV['CONFIG_ENABLED_WITH_EXTRA_SCOPES'] == 'true' end diff --git a/spec/models/extension/rated_spec.rb b/spec/models/extension/rated_spec.rb index 0f85790..1526090 100644 --- a/spec/models/extension/rated_spec.rb +++ b/spec/models/extension/rated_spec.rb @@ -37,4 +37,12 @@ RSpec.describe Rating::Extension, ':rated' do expect(Rating::Rate.where(resource: article_1).count).to eq 0 end end + + context 'with extra scopes' do + let!(:extra_scopes_rate) { author_1.rate article_1, 1, extra_scopes: { scope_1: 'scope_1' } } + + it 'returns records considering the extra scopes' do + expect(author_1.rated(extra_scopes: { scope_1: 'scope_1' })).to eq [extra_scopes_rate] + end + end if ENV['CONFIG_ENABLED_WITH_EXTRA_SCOPES'] == 'true' end diff --git a/spec/models/extension/rates_spec.rb b/spec/models/extension/rates_spec.rb index 40213f4..df6c916 100644 --- a/spec/models/extension/rates_spec.rb +++ b/spec/models/extension/rates_spec.rb @@ -37,4 +37,12 @@ RSpec.describe Rating::Extension, ':rates' do expect(Rating::Rate.where(resource: article_1).count).to eq 0 end end + + context 'with extra scopes' do + let!(:extra_scopes_rate) { author_1.rate article_1, 1, extra_scopes: { scope_1: 'scope_1' } } + + it 'returns records considering the extra scopes' do + expect(article_1.rates(extra_scopes: { scope_1: 'scope_1' })).to eq [extra_scopes_rate] + end + end if ENV['CONFIG_ENABLED_WITH_EXTRA_SCOPES'] == 'true' end diff --git a/spec/models/rate/create_spec.rb b/spec/models/rate/create_spec.rb index 924b097..fb5603d 100644 --- a/spec/models/rate/create_spec.rb +++ b/spec/models/rate/create_spec.rb @@ -6,8 +6,6 @@ RSpec.describe Rating::Rate, ':create' do let!(:author) { create :author } let!(:article) { create :article } - before(:all) { AddExtraScopesOnRatingRatesTable.new.change } - context 'with no scopeable' do before { described_class.create author: author, extra_scopes: {}, metadata: {}, resource: article, value: 3 } @@ -360,5 +358,5 @@ RSpec.describe Rating::Rate, ':create' do expect(rating.total).to eq 2 end end - end + end if ENV['CONFIG_ENABLED_WITH_EXTRA_SCOPES'] == 'true' end diff --git a/spec/models/rate/rate_for_spec.rb b/spec/models/rate/rate_for_spec.rb index d9723d1..fb37898 100644 --- a/spec/models/rate/rate_for_spec.rb +++ b/spec/models/rate/rate_for_spec.rb @@ -6,8 +6,6 @@ RSpec.describe Rating::Rate, ':rate_for' do let!(:author) { create :author } let!(:article) { create :article } - before(:all) { AddExtraScopesOnRatingRatesTable.new.change } - context 'with no scopeable' do context 'when rate does not exist' do it { expect(described_class.rate_for(author: author, resource: article)).to eq nil } @@ -103,5 +101,5 @@ RSpec.describe Rating::Rate, ':rate_for' do expect(result).to eq nil end end - end + end if ENV['CONFIG_ENABLED_WITH_EXTRA_SCOPES'] == 'true' end diff --git a/spec/models/rate_spec.rb b/spec/models/rate_spec.rb index 7553c95..3f7456d 100644 --- a/spec/models/rate_spec.rb +++ b/spec/models/rate_spec.rb @@ -20,8 +20,9 @@ RSpec.describe Rating::Rate do end it do - expect(object).to validate_uniqueness_of(:author_id) - .scoped_to(%i[author_type resource_id resource_type scopeable_id scopeable_type]) - .case_insensitive + scopes = %i[author_type resource_id resource_type scopeable_id scopeable_type] + scopes += %i[scope_1 scope_2] if ENV['CONFIG_ENABLED_WITH_EXTRA_SCOPES'] == 'true' + + expect(object).to validate_uniqueness_of(:author_id).scoped_to(scopes).case_insensitive end end diff --git a/spec/support/migrate.rb b/spec/support/migrate.rb index 1a24fbd..18377a6 100644 --- a/spec/support/migrate.rb +++ b/spec/support/migrate.rb @@ -14,3 +14,4 @@ CreateRatingTable.new.change CreateReviewRatingsTable.new.change CreateReviewsTable.new.change AddCommentOnRatingRatesTable.new.change +AddExtraScopesOnRatingRatesTable.new.change