seems_rateable 1.0.13 → 2.0.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/.gitignore +20 -0
- data/Gemfile +3 -0
- data/README.md +41 -61
- data/Rakefile +8 -2
- data/app/assets/javascripts/seems_rateable/index.js +1 -0
- data/{lib/generators/seems_rateable/install/templates → app/assets/javascripts/seems_rateable}/jRating.js.erb +225 -225
- data/app/assets/stylesheets/seems_rateable/{application.css → index.css.erb} +2 -2
- data/app/controllers/seems_rateable/application_controller.rb +1 -3
- data/app/controllers/seems_rateable/rates_controller.rb +31 -0
- data/app/models/seems_rateable/rate.rb +2 -2
- data/bin/rails +8 -0
- data/config/routes.rb +1 -1
- data/lib/generators/seems_rateable/install/install_generator.rb +34 -28
- data/lib/generators/seems_rateable/install/templates/initializer.rb +5 -2
- data/lib/generators/seems_rateable/install/templates/rateable.js.erb +12 -22
- data/lib/generators/seems_rateable/install/templates/rates_migration.rb +6 -9
- data/lib/generators/seems_rateable/manifest_finder.rb +25 -0
- data/lib/generators/seems_rateable/migration_helpers.rb +21 -0
- data/lib/generators/seems_rateable/uninstall/templates/drop_seems_rateable_rates_table.rb +9 -0
- data/lib/generators/seems_rateable/uninstall/uninstall_generator.rb +50 -0
- data/lib/generators/seems_rateable/uninstall_old/templates/drop_seems_rateable_cached_ratings_table.rb +9 -0
- data/lib/generators/seems_rateable/uninstall_old/templates/drop_seems_rateable_rates_table.rb +9 -0
- data/lib/generators/seems_rateable/uninstall_old/uninstall_old_generator.rb +48 -0
- data/lib/seems_rateable.rb +22 -7
- data/lib/seems_rateable/builder.rb +35 -0
- data/lib/seems_rateable/builder/html_options.rb +37 -0
- data/lib/seems_rateable/configuration.rb +23 -0
- data/lib/seems_rateable/engine.rb +12 -7
- data/lib/seems_rateable/errors.rb +3 -17
- data/lib/seems_rateable/helpers/action_view_extension.rb +18 -0
- data/lib/seems_rateable/helpers/current_rater.rb +15 -0
- data/lib/seems_rateable/models/active_record_extension.rb +23 -0
- data/lib/seems_rateable/models/active_record_extension/rateable.rb +26 -0
- data/lib/seems_rateable/models/active_record_extension/rater.rb +11 -0
- data/lib/seems_rateable/rating.rb +19 -0
- data/lib/seems_rateable/routes.rb +1 -1
- data/lib/seems_rateable/version.rb +1 -1
- data/seems_rateable.gemspec +32 -0
- data/spec/builder_spec.rb +53 -0
- data/spec/controllers/rates_controller_spec.rb +56 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/{app/assets/javascripts/seems_rateable → spec/dummy/app/assets/javascripts}/application.js +4 -3
- data/spec/dummy/app/assets/javascripts/posts.js +2 -0
- data/spec/dummy/app/assets/javascripts/rateable/rateable.js.erb +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +19 -0
- data/spec/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/posts_controller.rb +58 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/post.rb +3 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +26 -0
- data/spec/dummy/app/views/posts/_form.html.erb +21 -0
- data/spec/dummy/app/views/posts/edit.html.erb +6 -0
- data/spec/dummy/app/views/posts/index.html.erb +28 -0
- data/spec/dummy/app/views/posts/new.html.erb +5 -0
- data/spec/dummy/app/views/posts/show.html.erb +9 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +42 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/devise.rb +254 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/seems_rateable.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/devise.en.yml +59 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +8 -0
- data/spec/dummy/db/migrate/20140506144141_create_posts.rb +9 -0
- data/spec/dummy/db/migrate/20140506144841_devise_create_users.rb +42 -0
- data/spec/dummy/db/migrate/20140520170316_create_seems_rateable_rates.rb +15 -0
- data/spec/dummy/db/schema.rb +54 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/posts.rb +5 -0
- data/spec/factories/rate.rb +7 -0
- data/spec/factories/users.rb +7 -0
- data/spec/features/rating_spec.rb +63 -0
- data/spec/helpers/action_view_extension_spec.rb +59 -0
- data/spec/models/active_record_extension_spec.rb +105 -0
- data/spec/models/rate_spec.rb +6 -0
- data/spec/rating_spec.rb +70 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/support/dummies.rb +19 -0
- metadata +263 -25
- data/app/controllers/seems_rateable/ratings_controller.rb +0 -13
- data/app/models/seems_rateable/cached_rating.rb +0 -5
- data/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb +0 -17
- data/lib/seems_rateable/helpers.rb +0 -27
- data/lib/seems_rateable/model.rb +0 -91
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative 'builder/html_options'
|
|
2
|
+
|
|
3
|
+
module SeemsRateable
|
|
4
|
+
class Builder
|
|
5
|
+
include ActionView::Helpers::TagHelper
|
|
6
|
+
|
|
7
|
+
attr_reader :rateable, :options
|
|
8
|
+
|
|
9
|
+
def self.build(rateable, options)
|
|
10
|
+
new(rateable, options).build
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(rateable, options)
|
|
14
|
+
@rateable, @options = rateable, options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def build
|
|
18
|
+
content_tag :div, nil, html_options
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def html_options
|
|
24
|
+
HtmlOptions.new(rating, options).to_h
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def rating
|
|
28
|
+
rateable.rating dimension
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def dimension
|
|
32
|
+
options.delete(:dimension)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module SeemsRateable
|
|
2
|
+
class Builder
|
|
3
|
+
class HtmlOptions
|
|
4
|
+
attr_reader :rating, :options
|
|
5
|
+
|
|
6
|
+
def initialize(rating, options)
|
|
7
|
+
@rating, @options = rating, options
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_h
|
|
11
|
+
options[:class] = "#{klass} #{disabled}".strip
|
|
12
|
+
options[:data] = options.fetch(:data, {}).merge(rating_attributes)
|
|
13
|
+
options
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def rating_attributes
|
|
19
|
+
rate_params.merge average: rating.average
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Avoids passing nil dimension to the data html attrbitutes
|
|
23
|
+
# because it gets processed as data-dimension="null"
|
|
24
|
+
def rate_params
|
|
25
|
+
rating.rates.where_values_hash.keep_if { |k, v| v }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def klass
|
|
29
|
+
options[:class] || SeemsRateable.config.default_selector_class
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def disabled
|
|
33
|
+
'jDisabled' if options[:disabled]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module SeemsRateable
|
|
2
|
+
def self.config
|
|
3
|
+
@config ||= Configuration.new
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def self.configure(&block)
|
|
7
|
+
yield config if block_given?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Configuration
|
|
11
|
+
include ActiveSupport::Configurable
|
|
12
|
+
|
|
13
|
+
config_accessor :rate_owner_class
|
|
14
|
+
config_accessor :current_rater_method
|
|
15
|
+
config_accessor :default_selector_class
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
configure do |config|
|
|
19
|
+
config.rate_owner_class = 'User'
|
|
20
|
+
config.current_rater_method = :current_user
|
|
21
|
+
config.default_selector_class = 'rateable'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -2,15 +2,20 @@ module SeemsRateable
|
|
|
2
2
|
class Engine < ::Rails::Engine
|
|
3
3
|
isolate_namespace SeemsRateable
|
|
4
4
|
|
|
5
|
-
config.generators do |g|
|
|
6
|
-
g.test_framework :rspec, :fixture => false
|
|
7
|
-
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
|
8
|
-
end
|
|
9
|
-
|
|
10
5
|
initializer :seems_rateable do
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
::ActiveSupport.on_load(:active_record) { extend SeemsRateable::Models::ActiveRecordExtension }
|
|
7
|
+
::ActiveSupport.on_load(:action_view) { include SeemsRateable::Helpers::ActionViewExtension }
|
|
8
|
+
::ActiveSupport.on_load(:action_controller) { include SeemsRateable::Helpers::CurrentRater }
|
|
13
9
|
ActionDispatch::Routing::Mapper.send :include, SeemsRateable::Routes
|
|
14
10
|
end
|
|
11
|
+
|
|
12
|
+
config.after_initialize do
|
|
13
|
+
require 'seems_rateable/application_controller'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
config.generators do |g|
|
|
17
|
+
g.test_framework :rspec, fixture: false
|
|
18
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
|
19
|
+
end
|
|
15
20
|
end
|
|
16
21
|
end
|
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
module SeemsRateable
|
|
2
2
|
module Errors
|
|
3
|
-
class
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
end
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
class NoCurrentUserInstanceError < StandardError
|
|
10
|
-
def to_s
|
|
11
|
-
"User instance current_user is not available."
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class AlreadyRatedError < StandardError
|
|
16
|
-
def to_s
|
|
17
|
-
"User has already rated an object."
|
|
18
|
-
end
|
|
19
|
-
end
|
|
3
|
+
class InvalidRateableError < StandardError;end
|
|
4
|
+
class NonExistentDimension < StandardError;end
|
|
5
|
+
class NoCurrentRaterError < StandardError;end
|
|
20
6
|
end
|
|
21
7
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module SeemsRateable
|
|
2
|
+
module Helpers
|
|
3
|
+
module ActionViewExtension
|
|
4
|
+
def rating_for(rateable, options={})
|
|
5
|
+
unless rateable.kind_of? Models::ActiveRecordExtension::Rateable
|
|
6
|
+
raise Errors::InvalidRateableError, "#{rateable.inspect} is not a rateable" +
|
|
7
|
+
" object, try adding 'seems_rateable' into your object's model"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
if !current_rater || rateable.rated_by?(current_rater, options[:dimension])
|
|
11
|
+
options[:disabled] = true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
SeemsRateable::Builder.build(rateable, options)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module SeemsRateable
|
|
2
|
+
module Models
|
|
3
|
+
module ActiveRecordExtension
|
|
4
|
+
def seems_rateable(*dimensions)
|
|
5
|
+
has_many :_rates, -> { where dimension: nil }, as: :rateable, class_name: SeemsRateable::Rate, dependent: :destroy
|
|
6
|
+
has_many :_raters, through: :_rates, source: :rater, dependent: :destroy
|
|
7
|
+
|
|
8
|
+
dimensions.each do |dimension|
|
|
9
|
+
has_many :"#{dimension}_rates", -> { where dimension: dimension }, as: :rateable, class_name: SeemsRateable::Rate, dependent: :destroy
|
|
10
|
+
has_many :"#{dimension}_raters", through: :"#{dimension}_rates", source: :rater, dependent: :destroy
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
include Rateable
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def seems_rateable_rater
|
|
17
|
+
has_many :rates_given, class_name: SeemsRateable::Rate, foreign_key: :rater_id
|
|
18
|
+
|
|
19
|
+
include Rater
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module SeemsRateable
|
|
2
|
+
module Models
|
|
3
|
+
module ActiveRecordExtension
|
|
4
|
+
module Rateable
|
|
5
|
+
%w[rates raters].each do |m|
|
|
6
|
+
define_method m do |dimension=nil|
|
|
7
|
+
if respond_to? "#{dimension}_#{m}"
|
|
8
|
+
send "#{dimension}_#{m}"
|
|
9
|
+
else
|
|
10
|
+
raise Errors::NonExistentDimension, "Dimension '#{dimension.inspect}' does not exist for #{self.class}"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def rating(dimension=nil)
|
|
16
|
+
SeemsRateable::Rating.new rates(dimension)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def rated_by?(rater, dimension=nil)
|
|
20
|
+
return unless rater
|
|
21
|
+
raters(dimension).include? rater
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module SeemsRateable
|
|
2
|
+
class Rating < Struct.new(:rates)
|
|
3
|
+
def average
|
|
4
|
+
sum/(count.nonzero? || 1)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def sum
|
|
8
|
+
stars.inject(:+).to_f
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def count
|
|
12
|
+
stars.length
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def stars
|
|
16
|
+
@stars ||= rates.pluck(:stars)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
2
|
+
|
|
3
|
+
require "seems_rateable/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "seems_rateable"
|
|
7
|
+
s.version = SeemsRateable::VERSION
|
|
8
|
+
s.authors = ["Peter Toth"]
|
|
9
|
+
s.email = ["peter@petertoth.me"]
|
|
10
|
+
s.homepage = "http://rateable.herokuapp.com"
|
|
11
|
+
s.summary = "Star Rating Engine"
|
|
12
|
+
s.description = "Star rating engine using jQuery plugin jRating for Rails applications"
|
|
13
|
+
|
|
14
|
+
s.files = `git ls-files`.split("\n")
|
|
15
|
+
s.test_files = `git ls-files -- spec/**/*`.split("\n")
|
|
16
|
+
|
|
17
|
+
s.add_dependency "rails", ">= 4.0.0"
|
|
18
|
+
s.add_dependency "jquery-rails"
|
|
19
|
+
|
|
20
|
+
s.add_development_dependency "pry-rails"
|
|
21
|
+
s.add_development_dependency "sqlite3"
|
|
22
|
+
s.add_development_dependency "devise"
|
|
23
|
+
|
|
24
|
+
s.add_development_dependency "rspec-rails"
|
|
25
|
+
s.add_development_dependency "factory_girl_rails"
|
|
26
|
+
s.add_development_dependency "database_cleaner"
|
|
27
|
+
s.add_development_dependency "capybara"
|
|
28
|
+
s.add_development_dependency "selenium-webdriver"
|
|
29
|
+
s.add_development_dependency "shoulda-matchers"
|
|
30
|
+
s.add_development_dependency "simplecov"
|
|
31
|
+
s.add_development_dependency "generator_spec"
|
|
32
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
feature SeemsRateable::Builder do
|
|
4
|
+
let(:rateable) { DummyModel.seems_rateable.create }
|
|
5
|
+
let(:options) { {} }
|
|
6
|
+
|
|
7
|
+
describe ".build" do
|
|
8
|
+
it "initializes a new builder object and builds it" do
|
|
9
|
+
SeemsRateable::Builder.should_receive(:new).with(rateable, kind_of(Hash)).and_call_original
|
|
10
|
+
SeemsRateable::Builder.any_instance.should_receive(:build)
|
|
11
|
+
SeemsRateable::Builder.build(rateable, options)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "#build" do
|
|
16
|
+
def rating(rateable, options)
|
|
17
|
+
Capybara.string(SeemsRateable::Builder.new(rateable, options).build).first('div')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
subject { rating(rateable, options) }
|
|
21
|
+
|
|
22
|
+
describe "attributes" do
|
|
23
|
+
its(['class']) { should include(SeemsRateable.config.default_selector_class) }
|
|
24
|
+
its(['data-rateable-type']) { should eq(rateable.class.name) }
|
|
25
|
+
its(['data-rateable-id']) { should eq(rateable.id.to_s) }
|
|
26
|
+
its(['data-average']) { should_not be_nil }
|
|
27
|
+
its(['data-dimension']) { should be_nil }
|
|
28
|
+
|
|
29
|
+
context "with explicit class passed" do
|
|
30
|
+
let(:klass) { 'stuff' }
|
|
31
|
+
|
|
32
|
+
subject { rating(rateable, class: klass) }
|
|
33
|
+
|
|
34
|
+
its(['class']) { should include(klass) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context "with dimension" do
|
|
38
|
+
let(:dimension) { 'quality' }
|
|
39
|
+
let(:rateable) { DummyModel.seems_rateable(dimension).create }
|
|
40
|
+
|
|
41
|
+
subject { rating(rateable, dimension: dimension) }
|
|
42
|
+
|
|
43
|
+
its(['data-dimension']) { should eq(dimension) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "when disabled" do
|
|
47
|
+
subject { rating(rateable, disabled: true) }
|
|
48
|
+
|
|
49
|
+
its(['class']) { should include('jDisabled') }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SeemsRateable::RatesController do
|
|
4
|
+
routes { SeemsRateable::Engine.routes }
|
|
5
|
+
|
|
6
|
+
let(:user) { FactoryGirl.create(:user) }
|
|
7
|
+
let(:article) { FactoryGirl.create(:post) }
|
|
8
|
+
|
|
9
|
+
describe "POST #create" do
|
|
10
|
+
def create_rate
|
|
11
|
+
xhr :post, :create, valid_attributes(article)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def valid_attributes(rateable)
|
|
15
|
+
{
|
|
16
|
+
rate: {
|
|
17
|
+
rateable_type: rateable.class.name,
|
|
18
|
+
rateable_id: rateable.id,
|
|
19
|
+
stars: rand(1..5),
|
|
20
|
+
dimension: ['speed', 'quality', nil].sample
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "when valid" do
|
|
26
|
+
before do
|
|
27
|
+
controller.stub(:current_user).and_return(user)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "creates a new rate" do
|
|
31
|
+
expect { create_rate }.to change(SeemsRateable::Rate, :count).by(1)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "assigns a newly created rate as @rate" do
|
|
35
|
+
create_rate
|
|
36
|
+
assigns(:rate).should be_a(SeemsRateable::Rate)
|
|
37
|
+
assigns(:rate).should be_persisted
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "renders average rating as json" do
|
|
41
|
+
create_rate
|
|
42
|
+
expect(response.content_type).to eq('application/json')
|
|
43
|
+
expect(response.status).to eq(200)
|
|
44
|
+
expect(JSON.parse(response.body)).to have_key("average")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "when invalid" do
|
|
49
|
+
context "when user is not signed in" do
|
|
50
|
+
it "raises a NoCurrentRaterError error" do
|
|
51
|
+
expect { create_rate }.to raise_error
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
== README
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
|
4
|
+
application up and running.
|
|
5
|
+
|
|
6
|
+
Things you may want to cover:
|
|
7
|
+
|
|
8
|
+
* Ruby version
|
|
9
|
+
|
|
10
|
+
* System dependencies
|
|
11
|
+
|
|
12
|
+
* Configuration
|
|
13
|
+
|
|
14
|
+
* Database creation
|
|
15
|
+
|
|
16
|
+
* Database initialization
|
|
17
|
+
|
|
18
|
+
* How to run the test suite
|
|
19
|
+
|
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
|
21
|
+
|
|
22
|
+
* Deployment instructions
|
|
23
|
+
|
|
24
|
+
* ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
|
28
|
+
<tt>rake doc:app</tt>.
|