diff options
| -rw-r--r-- | app/controllers/inboxes/base_controller.rb | 2 | ||||
| -rw-r--r-- | app/controllers/inboxes/discussions_controller.rb | 28 | ||||
| -rw-r--r-- | config/locales/en.yml | 2 | ||||
| -rw-r--r-- | config/locales/ru.yml | 2 | ||||
| -rw-r--r-- | inboxes.gemspec | 7 | ||||
| -rw-r--r-- | lib/inboxes.rb | 1 | ||||
| -rw-r--r-- | log/development.log | 0 | ||||
| -rw-r--r-- | spec/devise_config.rb | 210 | ||||
| -rw-r--r-- | spec/fake_app.rb | 44 | ||||
| -rw-r--r-- | spec/fake_gem.rb | 6 | ||||
| -rw-r--r-- | spec/inboxes/discussions_controller_spec.rb | 192 | ||||
| -rw-r--r-- | spec/spec_helper.rb | 18 | ||||
| -rw-r--r-- | spec/support/factories.rb | 48 |
13 files changed, 384 insertions, 176 deletions
diff --git a/app/controllers/inboxes/base_controller.rb b/app/controllers/inboxes/base_controller.rb index f1e77b1..3e3f8dc 100644 --- a/app/controllers/inboxes/base_controller.rb +++ b/app/controllers/inboxes/base_controller.rb @@ -5,9 +5,7 @@ class Inboxes::BaseController < ApplicationController @discussion = Discussion.find(params[:discussion_id]) end - # Needs to be overriden so that we use Spree's Ability rather than anyone else's. def current_ability - # raise "Loading Ability" @current_ability ||= Inboxes::Ability.new(current_user) end end
\ No newline at end of file diff --git a/app/controllers/inboxes/discussions_controller.rb b/app/controllers/inboxes/discussions_controller.rb index 04a8edd..52655e2 100644 --- a/app/controllers/inboxes/discussions_controller.rb +++ b/app/controllers/inboxes/discussions_controller.rb @@ -1,31 +1,21 @@ class Inboxes::DiscussionsController < Inboxes::BaseController load_and_authorize_resource - # before_filter :authenticate_user! - # before_filter :init_and_check_permissions, :only => :show before_filter :load_and_check_discussion_recipient, :only => [:create, :new] def index @discussions = current_user.discussions end - - # GET /discussions/1 - # GET /discussions/1.json + def show # @discussion = Discussion.includes(:messages, :speakers).find(params[:id]) @discussion.mark_as_read_for(current_user) end - - # GET /discussions/new - # GET /discussions/new.json + def new - # @discussion = Discussion.new @discussion.messages.build end - - # POST /discussions - # POST /discussions.json + def create - # @discussion = Discussion.new(params[:discussion]) @discussion.add_recipient_token current_user.id @discussion.messages.each do |m| @@ -41,16 +31,10 @@ class Inboxes::DiscussionsController < Inboxes::BaseController end private - - # def init_and_check_permissions - # @discussion = Discussion.includes(:messages, :speakers).find(params[:id]) - # redirect_to discussions_url, :notice => t("inboxes.discussions.can_not_participate") unless @discussion.can_participate?(current_user) - # end - + def load_and_check_discussion_recipient # initializing model for new and create actions @discussion = Discussion.new(params[:discussion].presence || {}) - # @discussion.recipient_tokens = params[:recipients] if params[:recipients] # pre-population # checking if discussion with this user already exists if @discussion.recipient_ids && @discussion.recipient_ids.size == 1 @@ -61,8 +45,8 @@ class Inboxes::DiscussionsController < Inboxes::BaseController @discussion.messages.each do |message| Message.create(:discussion => discussion, :user => current_user, :body => message.body) if message.body end - # перекидываем на нее - redirect_to discussion_url(discussion), :notice => t("inboxes.discussions.exists", :user => user[Inboxes::config.user_name]) + # redirecting to this discussion page + redirect_to discussion_url(discussion), :notice => t("inboxes.discussions.already_exists", :user => user[Inboxes::config.user_name]) end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 348e39b..a9a810d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -10,6 +10,6 @@ en: discussions: started: "Discussion started" leaved: "You leave the discussion" - exists: "Discussion between you and %{user} already exists" + already_exists: "Discussion between you and %{user} already exists" can_not_participate: "You are not listed in this discussion" choose_at_least_one_recipient: "You should choose at least one recipient of discussion"
\ No newline at end of file diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 1258f9f..1e311cd 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -9,7 +9,7 @@ ru: discussions: started: "Чат начат" leaved: "Вы покинули дискуссию" - exists: "Дискуссия между вами и %{user} уже существует" + already_exists: "Дискуссия между вами и %{user} уже существует" can_not_participate: "Вы не состоите в этой дискуссии" choose_at_least_one_recipient: "Укажите хотя бы одного получателя" speakers: diff --git a/inboxes.gemspec b/inboxes.gemspec index 9f7a2ba..1b05f38 100644 --- a/inboxes.gemspec +++ b/inboxes.gemspec @@ -21,10 +21,11 @@ Gem::Specification.new do |s| # specify any dependencies here; for example: # s.add_development_dependency "ruby-debug" s.add_runtime_dependency "haml-rails" - s.add_runtime_dependency "cancan", ['>= 0'] - # s.add_runtime_dependency "inherited_resources" + s.add_runtime_dependency "devise" + s.add_runtime_dependency "rails" + s.add_runtime_dependency "cancan" - # s.add_development_dependency 'dm-sqlite-adapter', ['>= 1.1.0'] + s.add_development_dependency "sqlite3" s.add_development_dependency 'rspec', ['>= 0'] s.add_development_dependency 'factory_girl', ['~> 1.2'] s.add_development_dependency 'rspec-rails', ['>= 0'] diff --git a/lib/inboxes.rb b/lib/inboxes.rb index a8192dc..af88b0c 100644 --- a/lib/inboxes.rb +++ b/lib/inboxes.rb @@ -3,6 +3,7 @@ require "inboxes/railtie" require "inboxes/ability" require "inboxes/engine" require "inboxes/active_record_extension" +require "cancan" module Inboxes def self.configure(&block) diff --git a/log/development.log b/log/development.log new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/log/development.log diff --git a/spec/devise_config.rb b/spec/devise_config.rb new file mode 100644 index 0000000..5e86e34 --- /dev/null +++ b/spec/devise_config.rb @@ -0,0 +1,210 @@ +# Use this hook to configure devise mailer, warden hooks and so forth. The first +# four configuration values can also be set straight in your models. +Devise.setup do |config| + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class with default "from" parameter. + config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com" + + # Configure the class responsible to send e-mails. + # config.mailer = "Devise::Mailer" + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require 'devise/orm/active_record' + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + # config.authentication_keys = [ :email ] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [ :email ] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [ :email ] + + # Tell if authentication through request.params is enabled. True by default. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Basic Auth is enabled. False by default. + # config.http_authenticatable = false + + # If http headers should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. "Application" by default. + # config.http_authentication_realm = "Application" + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 10. If + # using other encryptors, it sets how many times you want the password re-encrypted. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. + config.stretches = Rails.env.test? ? 1 : 10 + + # Setup a pepper to generate the encrypted password. + # config.pepper = "9a86f39fcb72573a367c4fcde09b1ae3fe81c3c2c5858c6024033360b39a0f46ab72c8aade6453e96dfae546262c0336372c19518600367fc8b94e9bb4d5db15" + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming his account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming his account, + # access will be blocked just in the third day. Default is 0.days, meaning + # the user cannot access the website without confirming his account. + # config.confirm_within = 2.days + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [ :email ] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + # config.remember_for = 2.weeks + + # If true, a valid remember token can be re-used between multiple browsers. + # config.remember_across_browsers = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # If true, uses the password salt as remember token. This should be turned + # to false if you are not using database authenticatable. + config.use_salt_as_remember_token = true + + # Options to be passed to the created cookie. For instance, you can set + # :secure => true in order to force SSL only cookies. + # config.cookie_options = {} + + # ==> Configuration for :validatable + # Range for password length. Default is 6..128. + # config.password_length = 6..128 + + # Email regex used to validate email formats. It simply asserts that + # an one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + # config.email_regexp = /\A[^@]+@[^@]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + # config.timeout_in = 30.minutes + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [ :email ] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + # config.reset_password_keys = [ :email ] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = 2.hours + + # ==> Configuration for :encryptable + # Allow you to use another encryption algorithm besides bcrypt (default). You can use + # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, + # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) + # and :restful_authentication_sha1 (then you should set stretches to 10, and copy + # REST_AUTH_SITE_KEY to pepper) + # config.encryptor = :sha512 + + # ==> Configuration for :token_authenticatable + # Defines name of the authentication token params key + # config.token_authentication_key = :auth_token + + # If true, authentication through token does not store user in session and needs + # to be supplied on each request. Useful if you are using the token as API token. + # config.stateless_token = false + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = false + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + + # Configure sign_out behavior. + # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope). + # The default is true, which means any logout action will sign out all active scopes. + # config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html, should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The :"*/*" and "*/*" formats below is required to match Internet + # Explorer requests. + # config.navigational_formats = [:"*/*", "*/*", :html] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + # config.warden do |manager| + # manager.failure_app = AnotherApp + # manager.intercept_401 = false + # manager.default_strategies(:scope => :user).unshift :some_external_strategy + # end +end diff --git a/spec/fake_app.rb b/spec/fake_app.rb index 37df9e2..f7db07f 100644 --- a/spec/fake_app.rb +++ b/spec/fake_app.rb @@ -2,6 +2,14 @@ require 'active_record' require 'action_controller/railtie' require 'action_view/railtie' +require "cancan" +require "cancan/ability" +require "cancan/controller_resource" +require "cancan/controller_additions" + +require 'devise' +require 'devise/orm/active_record' + # database ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}} ActiveRecord::Base.establish_connection('test') @@ -13,10 +21,7 @@ app.config.session_store :cookie_store, :key => "_myapp_session" app.config.active_support.deprecation = :log app.initialize! -# routes -app.routes.draw do - devise_for :users -end +require 'devise_config' # models class User < ActiveRecord::Base @@ -27,20 +32,11 @@ class User < ActiveRecord::Base has_inboxes end -# controllers -class ApplicationController < ActionController::Base - before_filter :assign_unread_discussions - - private - - def assign_unread_discussions - @unread_discussions_count = Discussion.unread_for(current_user).count if user_signed_in? - end +# routes +app.routes.draw do + devise_for :users end -# helpers -Object.const_set(:ApplicationHelper, Module.new) - #migrations ActiveRecord::Base.silence do ActiveRecord::Migration.verbose = false @@ -84,4 +80,18 @@ ActiveRecord::Base.silence do t.datetime "updated_at" end end -end
\ No newline at end of file +end + +# controllers +class ApplicationController < ActionController::Base + before_filter :assign_unread_discussions + + private + + def assign_unread_discussions + @unread_discussions_count = Discussion.unread_for(current_user).count if user_signed_in? + end +end + +# helpers +Object.const_set(:ApplicationHelper, Module.new)
\ No newline at end of file diff --git a/spec/fake_gem.rb b/spec/fake_gem.rb new file mode 100644 index 0000000..4435a70 --- /dev/null +++ b/spec/fake_gem.rb @@ -0,0 +1,6 @@ +# Simulate a gem providing a subclass of ActiveRecord::Base before the Railtie is loaded. + +require 'active_record' + +class GemDefinedModel < ActiveRecord::Base +end
\ No newline at end of file diff --git a/spec/inboxes/discussions_controller_spec.rb b/spec/inboxes/discussions_controller_spec.rb index 564e9e8..16a2514 100644 --- a/spec/inboxes/discussions_controller_spec.rb +++ b/spec/inboxes/discussions_controller_spec.rb @@ -1,96 +1,96 @@ -require 'spec_helper' - -describe Inboxes::DiscussionsController do - context "Guest" do - it "should not see discussions list" do - get :index - response.should redirect_to(sign_in_url) - end - - it "should not see new action" do - get :new - response.should redirect_to(sign_in_url) - end - - it "should not create discussion if model is valid" do - recipient_ids = [Factory(:user).id, Factory(:user).id] - post(:create, - :discussion => { - :recipient_ids => recipient_ids, - :messages_attributes => { - 0 => {:body => Factory.next(:string)} - } - } - ) - - response.should redirect_to(sign_in_url) - end - - end - - context("Authenticated admin") do - before(:each) do - @request.env["devise.mapping"] = Devise.mappings[:user] - @user = Factory(:user) - @user.set_role(:admin) - sign_in @user - end - - it "should see discussions list" do - get :index - response.should render_template(:index) - end - - it "should see new action" do - get :new - response.should render_template(:new) - end - - it "should open discussion" do - discussion = Factory.build(:discussion) - discussion.recipient_ids = [@user, Factory(:user)].map { |u| u.id } - discussion.save.should be true - - get(:show, :id => discussion) - response.status.should be 200 - end - - it "should create private discussion if model is valid" do - recipient_ids = [Factory(:user).id, Factory(:user).id] - post(:create, - :discussion => { - :recipient_ids => recipient_ids, - :messages_attributes => { - 0 => {:body => Factory.next(:string)} - } - } - ) - - response.should redirect_to(discussion_url(assigns[:discussion])) - end - - it "should create group discussion if model is valid" do - recipient_ids = [Factory(:user).id, Factory(:user).id, Factory(:user).id] - post(:create, - :discussion => { - :recipient_ids => recipient_ids, - :messages_attributes => { - 0 => {:body => Factory.next(:string)} - } - } - ) - - response.should redirect_to(discussion_url(assigns[:discussion])) - end - - it "should not create discussion with empty message" do - discussion = Discussion.new - discussion.recipient_ids = [Factory(:user).id, Factory(:user).id, Factory(:user).id] - post(:create, :discussion => discussion) - - response.should render_template(:new) - end - - end - -end +# require 'spec_helper' +# +# describe Inboxes::DiscussionsController do +# context "Guest" do +# it "should not see discussions list" do +# get :index +# response.should redirect_to(sign_in_url) +# end +# +# it "should not see new action" do +# get :new +# response.should redirect_to(sign_in_url) +# end +# +# it "should not create discussion if model is valid" do +# recipient_ids = [Factory(:user).id, Factory(:user).id] +# post(:create, +# :discussion => { +# :recipient_ids => recipient_ids, +# :messages_attributes => { +# 0 => {:body => Factory.next(:string)} +# } +# } +# ) +# +# response.should redirect_to(sign_in_url) +# end +# +# end +# +# context("Authenticated admin") do +# before(:each) do +# @request.env["devise.mapping"] = Devise.mappings[:user] +# @user = Factory(:user) +# @user.set_role(:admin) +# sign_in @user +# end +# +# it "should see discussions list" do +# get :index +# response.should render_template(:index) +# end +# +# it "should see new action" do +# get :new +# response.should render_template(:new) +# end +# +# it "should open discussion" do +# discussion = Factory.build(:discussion) +# discussion.recipient_ids = [@user, Factory(:user)].map { |u| u.id } +# discussion.save.should be true +# +# get(:show, :id => discussion) +# response.status.should be 200 +# end +# +# it "should create private discussion if model is valid" do +# recipient_ids = [Factory(:user).id, Factory(:user).id] +# post(:create, +# :discussion => { +# :recipient_ids => recipient_ids, +# :messages_attributes => { +# 0 => {:body => Factory.next(:string)} +# } +# } +# ) +# +# response.should redirect_to(discussion_url(assigns[:discussion])) +# end +# +# it "should create group discussion if model is valid" do +# recipient_ids = [Factory(:user).id, Factory(:user).id, Factory(:user).id] +# post(:create, +# :discussion => { +# :recipient_ids => recipient_ids, +# :messages_attributes => { +# 0 => {:body => Factory.next(:string)} +# } +# } +# ) +# +# response.should redirect_to(discussion_url(assigns[:discussion])) +# end +# +# it "should not create discussion with empty message" do +# discussion = Discussion.new +# discussion.recipient_ids = [Factory(:user).id, Factory(:user).id, Factory(:user).id] +# post(:create, :discussion => discussion) +# +# response.should render_template(:new) +# end +# +# end +# +# end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a0e9366..5caa0f5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,8 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'rails' -# require 'inboxes' -require 'devise' +require 'active_record' +require 'inboxes' # require 'database_cleaner' # Ensure we use 'syck' instead of 'psych' in 1.9.2 # RubyGems >= 1.5.0 uses 'psych' on 1.9.2, but @@ -20,10 +20,10 @@ require 'rspec/rails' # in ./support/ and its subdirectories. Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} -RSpec.configure do |config| - config.mock_with :rr - config.before :all do -# ActiveRecord::Base.connection.execute 'CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255))' unless ActiveRecord::Base.connection.table_exists? 'users' - # CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? 'users' - end -end
\ No newline at end of file +# RSpec.configure do |config| +# config.mock_with :rr +# config.before :all do +# # ActiveRecord::Base.connection.execute 'CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255))' unless ActiveRecord::Base.connection.table_exists? 'users' +# # CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? 'users' +# end +# end
\ No newline at end of file diff --git a/spec/support/factories.rb b/spec/support/factories.rb index a7eaad6..9a5bb87 100644 --- a/spec/support/factories.rb +++ b/spec/support/factories.rb @@ -1,25 +1,23 @@ -FactoryGirl.define do - - factory :user do - email {Factory.next(:email)} - first_name 'user' - last_name 'usered' - username {Factory.next(:login)} - password "foobar" - password_confirmation { |u| u.password } - role 2 - end - - factory :discussion do - recipient_ids {[Factory(:user).id, Factory(:user).id]} - end - - factory :message do - association :user - association :discussion - # user {Factory(:user)} - # discussion {Factory(:discussion)} - end - - -end
\ No newline at end of file +# FactoryGirl.define do +# +# factory :user do +# email {Factory.next(:email)} +# first_name 'user' +# last_name 'usered' +# username {Factory.next(:login)} +# password "foobar" +# password_confirmation { |u| u.password } +# role 2 +# end +# +# factory :discussion do +# recipient_ids {[Factory(:user).id, Factory(:user).id]} +# end +# +# factory :message do +# association :user +# association :discussion +# # user {Factory(:user)} +# # discussion {Factory(:discussion)} +# end +# end
\ No newline at end of file |
