diff --git a/Gemfile b/Gemfile index 84d11b7..46da0bf 100644 --- a/Gemfile +++ b/Gemfile @@ -18,10 +18,12 @@ gem 'sendgrid' # Use mongoid to utilise mongodb gem 'mongoid' -# The following gems for testing purpose in development and testing environment -group :development, :test do +# The following gems for testing purpose in testing environment +group :test do # Rspec is used to write the test cases - gem 'rspec-rails' + gem 'rspec-rails', '~> 3.1' + gem 'mongoid-rspec' + gem 'byebug' # Use factory girl to pass random data for test cases gem 'factory_girl_rails' # Use faker to generate fake strings and data @@ -30,9 +32,6 @@ group :development, :test do gem 'database_cleaner' # Use to track how much code has been tested gem 'simplecov', '~> 0.7.1' -end - -group :test do # Webmock to stub http requests gem 'webmock' # VCR to record the responses from web and replay them when needed diff --git a/Gemfile.lock b/Gemfile.lock index a20dff9..4237c26 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,16 @@ GIT oauth (>= 0.3.6) oauth2 (>= 0.5.0) +GIT + remote: git://github.com/aq1018/mongoid-history.git + revision: 2935da05ccf24027c83b3bd1a92b39edc78ee6b8 + specs: + mongoid-history (0.8.4) + activesupport + easy_diff + mongoid (>= 3.0) + mongoid-compatibility (>= 0.5.1) + PATH remote: . specs: @@ -25,12 +35,13 @@ PATH jquery-rails mini_magick mongoid + mongoid-history omniauth-google-oauth2 rails (~> 4.2.5.2) redactor-rails (= 0.4.5) redis-namespace redis-rails - rest_client + rest-client sass-rails (~> 4.0.3) select2-rails sendgrid @@ -85,16 +96,17 @@ GEM addressable (>= 2.3.1) extlib (>= 0.9.15) multi_json (>= 1.0.0) - autoprefixer-rails (7.2.2) + autoprefixer-rails (9.8.6) execjs bcrypt (3.1.7) bootstrap-datepicker-rails (1.3.0.2) railties (>= 3.0) - bootstrap-sass (3.3.5) - autoprefixer-rails (>= 5.0.0.1) - sass (>= 3.2.19) + bootstrap-sass (3.4.1) + autoprefixer-rails (>= 5.2.1) + sassc (>= 2.0.0) bson (2.3.0) builder (3.2.3) + byebug (10.0.2) carrierwave (0.10.0) activemodel (>= 3.2.0) activesupport (>= 3.2.0) @@ -104,7 +116,7 @@ GEM carrierwave (>= 0.8.0, < 0.11.0) mongoid (>= 3.0, < 5.0) mongoid-grid_fs (>= 1.3, < 3.0) - celluloid (0.17.3) + celluloid (0.17.4) celluloid-essentials celluloid-extras celluloid-fsm @@ -148,7 +160,10 @@ GEM devise_invitable (1.6.1) actionmailer (>= 3.2.6) devise (>= 3.2.0) - diff-lcs (1.2.5) + diff-lcs (1.4.4) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + easy_diff (1.0.0) erubis (2.7.0) execjs (2.7.0) extlib (0.9.16) @@ -161,7 +176,8 @@ GEM i18n (~> 0.5) faraday (0.9.0) multipart-post (>= 1.2, < 3) - globalid (0.4.1) + ffi (1.12.2) + globalid (0.4.2) activesupport (>= 4.2.0) google-api-client (0.7.1) addressable (>= 2.3.2) @@ -174,7 +190,7 @@ GEM retriable (>= 1.4) signet (>= 0.5.0) uuidtools (>= 2.1.0) - haml (5.0.4) + haml (5.2.0) temple (>= 0.8.0) tilt haml-rails (1.0.0) @@ -186,22 +202,23 @@ GEM hashdiff (0.2.3) hashie (2.1.2) hike (1.2.3) - hitimes (1.2.6) html2haml (2.2.0) erubis (~> 2.7.0) haml (>= 4.0, < 6) nokogiri (>= 1.6.0) ruby_parser (~> 3.5) + http-accept (1.7.0) + http-cookie (1.0.3) + domain_name (~> 0.5) httparty (0.13.1) json (~> 1.8) multi_xml (>= 0.5.2) i18n (0.9.1) concurrent-ruby (~> 1.0) imgkit (1.6.0) - jbuilder (2.7.0) + jbuilder (2.9.1) activesupport (>= 4.2.0) - multi_json (>= 1.2) - jquery-rails (4.3.1) + jquery-rails (4.4.0) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) @@ -213,7 +230,7 @@ GEM loofah (2.1.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) - mail (2.7.0) + mail (2.7.1) mini_mime (>= 0.1.1) method_source (0.8.2) mime-types (2.99.3) @@ -223,7 +240,7 @@ GEM mina_extensions (0.0.2) mini_magick (3.8.0) subexec (~> 0.2.1) - mini_mime (1.0.0) + mini_mime (1.0.2) mini_portile2 (2.3.0) minitest (5.10.3) mongoid (4.0.0) @@ -231,11 +248,21 @@ GEM moped (~> 2.0.0) origin (~> 2.1) tzinfo (>= 0.3.37) + mongoid-compatibility (0.5.1) + activesupport + mongoid (>= 2.0) mongoid-grid_fs (2.1.0) mime-types (>= 1.0, < 3.0) mongoid (>= 3.0, < 5.0) mongoid-paperclip (0.0.9) paperclip (>= 2.3.6) + mongoid-rspec (4.1.0) + activesupport (>= 3.0.0) + mongoid (>= 3.1) + mongoid-compatibility (>= 0.5.1) + rspec-core (~> 3.3) + rspec-expectations (~> 3.3) + rspec-mocks (~> 3.3) mongoid_slug (3.2.1) mongoid (> 3.0) stringex (~> 2.0) @@ -246,7 +273,7 @@ GEM multi_json (1.12.2) multi_xml (0.5.5) multipart-post (2.0.0) - netrc (0.7.7) + netrc (0.11.0) nokogiri (1.8.1) mini_portile2 (~> 2.3.0) oauth (0.4.7) @@ -336,26 +363,30 @@ GEM ref (1.0.5) responders (2.1.1) railties (>= 4.2.0, < 5.1) - rest_client (1.7.3) - netrc (~> 0.7.7) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) retriable (1.4.1) - rspec-core (3.0.3) - rspec-support (~> 3.0.0) - rspec-expectations (3.0.3) + rspec-core (3.9.3) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.4) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.0.0) - rspec-mocks (3.0.3) - rspec-support (~> 3.0.0) - rspec-rails (3.0.2) + rspec-support (~> 3.9.0) + rspec-rails (3.9.1) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) - rspec-support (~> 3.0.0) - rspec-support (3.0.3) - ruby_parser (3.10.1) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-support (~> 3.9.0) + rspec-support (3.9.4) + ruby_parser (3.15.0) sexp_processor (~> 4.9) safe_yaml (1.0.3) sass (3.2.19) @@ -364,13 +395,15 @@ GEM sass (~> 3.2.2) sprockets (~> 2.8, < 3.0) sprockets-rails (~> 2.0) + sassc (2.4.0) + ffi (~> 1.9) select2-rails (3.5.9) thor (~> 0.14) sendgrid (1.2.0) json sendgrid_toolkit (1.4.0) httparty (>= 0.7.6) - sexp_processor (4.10.0) + sexp_processor (4.15.1) sidekiq (3.3.0) celluloid (>= 0.16.0) connection_pool (>= 2.0.0) @@ -396,7 +429,7 @@ GEM slop (3.6.0) spring (2.0.2) activesupport (>= 4.2) - sprockets (2.12.4) + sprockets (2.12.5) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) @@ -407,22 +440,24 @@ GEM sprockets (>= 2.8, < 4.0) stringex (2.5.2) subexec (0.2.3) - temple (0.8.0) + temple (0.8.2) therubyracer (0.12.1) libv8 (~> 3.16.14.0) ref thor (0.20.0) thread_safe (0.3.6) tilt (1.4.1) - timers (4.1.2) - hitimes - turbolinks (5.0.1) - turbolinks-source (~> 5) - turbolinks-source (5.0.3) + timers (4.3.2) + turbolinks (5.2.1) + turbolinks-source (~> 5.2) + turbolinks-source (5.2.0) tzinfo (1.2.4) thread_safe (~> 0.1) - uglifier (4.0.1) + uglifier (4.2.0) execjs (>= 0.3.0, < 3) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.7) uuidtools (2.1.4) vcr (2.9.2) warden (1.2.3) @@ -436,6 +471,7 @@ PLATFORMS ruby DEPENDENCIES + byebug carrierwave carrierwave-mongoid database_cleaner @@ -449,7 +485,9 @@ DEPENDENCIES mina_extensions mini_magick mongoid + mongoid-history! mongoid-paperclip + mongoid-rspec mongoid_slug omniauth-google-oauth2 pry @@ -457,8 +495,8 @@ DEPENDENCIES redis-namespace redis-rails responders (~> 2.0) - rest_client - rspec-rails + rest-client + rspec-rails (~> 3.1) select2-rails sendgrid sendgrid_toolkit @@ -469,5 +507,8 @@ DEPENDENCIES vcr webmock +RUBY VERSION + ruby 2.2.4p230 + BUNDLED WITH - 1.11.2 + 1.17.3 diff --git a/Rakefile b/Rakefile index 3c32ad9..67cfae3 100644 --- a/Rakefile +++ b/Rakefile @@ -4,10 +4,10 @@ rescue LoadError puts 'You must `gem install bundler` and `bundle install` to run rake tasks' end -APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile",_FILE_) +APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile",__FILE__) load 'rails/tasks/engine.rake' Bundler::GemHelper.install_tasks -Dir[File.join(File.dirname(_FILE_), 'tasks/**/*.rake')].each {|f| load f } +Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f } #require 'rdoc/task' require 'rspec/core' diff --git a/app/controllers/light/newsletters_controller.rb b/app/controllers/light/newsletters_controller.rb index acabd75..2819dd1 100644 --- a/app/controllers/light/newsletters_controller.rb +++ b/app/controllers/light/newsletters_controller.rb @@ -1,95 +1,108 @@ -require_dependency "light/application_controller" +require_dependency 'light/application_controller' module Light class NewslettersController < ApplicationController - before_filter :load_newsletter, only: [:send_opt_in, :send_opt_in_test, :test_opt_in, - :send_opt_out, :send_opt_out_test, :test_opt_out] + before_filter :load_newsletter, only: [:send_newsletter, :send_test_mail, :test_mail, + :show, :edit, :update, :destroy, :web_version] def index - @newsletters = Newsletter.monthly_letters.order_by([:sent_on, :desc]) - end - - def opt_in - @newsletters = Newsletter.opt_in_letters.order_by([:sent_on, :desc]) - end - - def opt_out - @newsletters = Newsletter.opt_out_letters.order_by([:sent_on, :desc]) + type = params[:type].present? ? params[:type] : Newsletter::NEWSLETTER_TYPES[:MONTHLY] + @newsletters = Newsletter.where(newsletter_type: type).order_by([:sent_on, :desc]) end def show - @newsletter = Newsletter.find(params[:id]) end - def new + def new @newsletter = Newsletter.new end - def create + def create @newsletter = Newsletter.new(newsletters_params) if @newsletter.save @newsletter.update(sent_on: Date.today) Light::CreateImageWorker.perform_async(@newsletter.id.to_s) - redirect_to newsletters_path + flash[:success] = 'Newsletter created successfully' + redirect_to newsletters_path(type: @newsletter.newsletter_type) else + flash[:error] = 'Error while creating newsletter' render action: 'new' end end def edit - @newsletter = Newsletter.find(params[:id]) end def update - @newsletter = Newsletter.find(params[:id]) if @newsletter.update_attributes(newsletters_params) Light::CreateImageWorker.perform_async(@newsletter.id.to_s) - redirect_to newsletters_path + flash[:success] = 'Newsletter updated successfully' + redirect_to newsletters_path(type: @newsletter.newsletter_type) else + flash[:error] = 'Error while updating newsletter' render action: 'edit' end end def destroy - @newsletter = Newsletter.find(params[:id]) - @newsletter.destroy - redirect_to newsletters_path + if @newsletter && @newsletter.destroy + flash[:success] = 'Newsletter deleted successfully' + redirect_to newsletters_path(type: @newsletter.newsletter_type) + else + flash[:error] = 'Error while deleting newsletter' + redirect_to newsletters_path + end end def web_version - @newsletter = Newsletter.find(params[:id]) render layout: false end - def test_opt_in - end - - def send_opt_in_test - emails = params[:email][:email_id].split(",") - Light::UserMailer.welcome_message(emails, @newsletter, 'test_user_dummy_id').deliver if @newsletter - redirect_to newsletter_path(@newsletter) + def send_newsletter + if @newsletter + type = @newsletter.newsletter_type + + case type + when Newsletter::NEWSLETTER_TYPES[:OPT_IN] + Light::OptInWorker.perform_async(@newsletter.id.to_s) + flash[:notice] = 'Sent Opt-In newsletter successfully' + when Newsletter::NEWSLETTER_TYPES[:OPT_OUT] + Light::OptOutWorker.perform_async(@newsletter.id.to_s) + flash[:notice] = 'Sent Opt-Out newsletter successfully' + when Newsletter::NEWSLETTER_TYPES[:MONTHLY] + Light::UserWorker.perform_async(@newsletter.id.to_s) + flash[:notice] = 'Sent Monthly newsletter successfully' + else + flash[:error] = 'Invalid newsletter type' + end + redirect_to newsletters_path(type: type) + else + flash[:error] = 'Newsletter not found.' + redirect_to newsletters_path + end end - def send_opt_in - Light::OptInWorker.perform_async(@newsletter.id.to_s) - redirect_to opt_in_newsletters_path - end - - def test_opt_out + def send_test_mail + emails = params[:email][:email_id].split(',') + unless emails.empty? + if @newsletter + Light::UserMailer.welcome_message(emails, @newsletter, 'test_user_dummy_id').deliver_now + flash[:notice] = 'You will receive newsletter on the given email ids shortly.' + redirect_to newsletters_path(type: @newsletter.newsletter_type) + else + flash[:error] = 'Newsletter not found.' + redirect_to newsletters_path + end + else + flash[:error] = 'Atleast one email ID is expected.' + render 'test_mail' + end end - def send_opt_out_test - emails = params[:email][:email_id].split(",") - Light::UserMailer.welcome_message(emails, @newsletter, 'test_user_dummy_id').deliver if @newsletter - redirect_to newsletter_path(@newsletter) + def test_mail end - def send_opt_out - Light::OptOutWorker.perform_async(@newsletter.id.to_s) - redirect_to opt_out_newsletters_path - end - private def newsletters_params diff --git a/app/controllers/light/users_controller.rb b/app/controllers/light/users_controller.rb index a53e4d2..d5263c6 100644 --- a/app/controllers/light/users_controller.rb +++ b/app/controllers/light/users_controller.rb @@ -1,8 +1,9 @@ -require_dependency "light/application_controller" +require_dependency 'light/application_controller' module Light class UsersController < ApplicationController respond_to :js, :json, :html before_filter :user_with_token, only: [:remove, :unsubscribe, :subscribe] + before_filter :load_user, only: [:show, :edit, :update, :destroy] def index offset_val = params[:offset] || 0 @@ -14,7 +15,6 @@ def index end def show - @user = Light::User.find(params[:id]) end def new @@ -25,77 +25,70 @@ def create @user = Light::User.new(users_params) @user.sent_on = Array.new if @user.save - @user.update(source: 'Manual', sent_on: Array.new, sidekiq_status: 'new user' ) + @user.update(source: 'Manual', sent_on: Array.new, sidekiq_status: 'new user') + flash[:success] = 'User created successfully' redirect_to users_path else + flash[:error] = 'Error while creating user' render action: 'new' end end - def testmail - end - - def sendtest - emails = params[:email][:email_id].split(",") - Light::Enqueue.perform_async(emails) - - redirect_to newsletters_path - end - def unsubscribe if @user.present? && @user.sidekiq_status == 'Subscribed' - @user.update(is_subscribed: 'false', - unsubscribed_at: DateTime.now, - sidekiq_status: 'Unsubscribed') + @user.update( + is_subscribed: false, + unsubscribed_at: DateTime.now, + sidekiq_status: 'Unsubscribed' + ) @message = 'Unsubscribed successfully!!' else - @message = response_message('unsubscribed') + @message = response_message('Unsubscribed') end end def subscribe if @user.present? && @user.sidekiq_status == 'Unsubscribed' - @user.update(is_subscribed: 'true', - sidekiq_status: 'Subscribed', - subscribed_at: DateTime.now, - remote_ip: request.remote_ip, - user_agent: request.env['HTTP_USER_AGENT']) + @user.update_attributes( + is_subscribed: true, + sidekiq_status: 'Subscribed', + subscribed_at: DateTime.now, + remote_ip: request.remote_ip, + user_agent: request.env['HTTP_USER_AGENT'] + ) @message = 'Subscribed successfully!!' else - @message = response_message('subscribed') + @message = response_message('Subscribed') end end - def sendmailer - Light::UserWorker.perform_async - redirect_to newsletters_path - end - def edit - @user = Light::User.find(params[:id]) end def update - @user = Light::User.find(params[:id]) - if @user.update_attributes(users_params) + if @user && @user.update_attributes(users_params) + flash[:success] = 'User info updated successfully' redirect_to users_path else + flash[:error] = 'Error while updating user' render action: 'edit' end end def destroy - @user = Light::User.find(params[:id]) - @user.destroy + if @user && @user.destroy + flash[:success] = 'User deleted successfully' + else + flash[:error] = 'Error while deleting user' + end redirect_to users_path end def remove - if @user.present? - @user.destroy - @message = "We have removed you from our database!" + if @user.present? && @user.destroy + @message = 'We have removed you from our database!' else - @message = "No user with this token exists!" + @message = 'No user with this token exists!' end end @@ -110,31 +103,34 @@ def import def auto_opt_in @user = Light::User.new - @newsletters = Light::Newsletter.all.desc(:sent_on) + @newsletters = Light::Newsletter.all.desc(:sent_on) end def opt_in @user = Light::User.where(email_id: params[:email]).first if @user.present? - @user.update_attributes(is_subscribed: true, - sidekiq_status: 'Subscribed', - subscribed_at: DateTime.now) + @user.update_attributes( + is_subscribed: true, + sidekiq_status: 'Subscribed', + subscribed_at: DateTime.now + ) else u_name = params[:username].blank? ? params[:email] : params[:username] - @user = Light::User.new(username: u_name, - email_id: params[:email], - source: 'web subscription request', - subscribed_at: DateTime.now, - sidekiq_status: 'Subscribed') + @user = Light::User.new( + username: u_name, + email_id: params[:email], + source: 'web subscription request', + subscribed_at: DateTime.now, + sidekiq_status: 'Subscribed' + ) end respond_to do |format| - format.json { head :no_content } + format.json {head :no_content} format.html {redirect_to main_app.users_thank_you_path} end end def thank_you - end private @@ -152,14 +148,18 @@ def dummy_token? def response_message(status) if dummy_token? - "#{status.capitalize} successfully!!" + "#{status} successfully!!" elsif @user.nil? - "Hey, it seems request you are trying to access is invalid. If you have any " + + 'Hey, it seems request you are trying to access is invalid. If you have any ' + "concerns about our newsletter's subscription, kindly get in touch with " + "hr@joshsoftware.com" else "You have already #{status}!!" end end + + def load_user + @user = Light::User.find(params[:id]) + end end end diff --git a/app/models/light/newsletter.rb b/app/models/light/newsletter.rb index 828b286..9a70a93 100644 --- a/app/models/light/newsletter.rb +++ b/app/models/light/newsletter.rb @@ -4,39 +4,41 @@ class Newsletter include Mongoid::Slug include Mongoid::Paperclip - VALID_NEWSLETTER_TYPES = { MONTHLY: 'Monthly Newsletter', - OPT_IN: 'Opt-In Letter', - OPT_OUT: 'Opt-Out Letter' } + NEWSLETTER_TYPES = { + MONTHLY: 'Monthly Newsletter', + OPT_IN: 'Opt-In Letter', + OPT_OUT: 'Opt-Out Letter' + } field :subject, type: String - field :content, type: String + field :content, type: String field :sent_on, type: Date field :users_count, type: Integer, default: 0 - field :newsletter_type, type: String, default: VALID_NEWSLETTER_TYPES[:MONTHLY] + field :newsletter_type, type: String, default: NEWSLETTER_TYPES[:MONTHLY] validates :content, :subject, :newsletter_type, presence: true validates :subject, uniqueness: true - validates :newsletter_type, inclusion: {in: VALID_NEWSLETTER_TYPES.values} + validates :newsletter_type, inclusion: {in: NEWSLETTER_TYPES.values} - scope :opt_in_letters, -> { where(newsletter_type: VALID_NEWSLETTER_TYPES[:OPT_IN]) } - scope :opt_out_letters, -> { where(newsletter_type: VALID_NEWSLETTER_TYPES[:OPT_OUT]) } - scope :monthly_letters, -> { where(newsletter_type: VALID_NEWSLETTER_TYPES[:MONTHLY]) } - - has_mongoid_attached_file :photo,:styles => {:original => ['1920x1680>', :png],:small => ['240x200!', :png]} - validates_attachment_content_type :photo, :content_type => ["image/jpg", "image/jpeg", "image/png", "application/pdf"] + scope :opt_in_letters, -> { where(newsletter_type: NEWSLETTER_TYPES[:OPT_IN]) } + scope :opt_out_letters, -> { where(newsletter_type: NEWSLETTER_TYPES[:OPT_OUT]) } + scope :monthly_letters, -> { where(newsletter_type: NEWSLETTER_TYPES[:MONTHLY]) } + + has_mongoid_attached_file :photo,styles: {original: ['1920x1680>', :png],small: ['240x200!', :png]} + validates_attachment_content_type :photo, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'application/pdf'] slug :subject def get_image - photo.present? ? photo.url(:small) : "/images/newsletter.jpg" + photo.present? ? photo.url(:small) : '/images/newsletter.jpg' end def opt_in? - newsletter_type.eql?(VALID_NEWSLETTER_TYPES[:OPT_IN]) + newsletter_type.eql?(NEWSLETTER_TYPES[:OPT_IN]) end def opt_out? - newsletter_type.eql?(VALID_NEWSLETTER_TYPES[:OPT_OUT]) + newsletter_type.eql?(NEWSLETTER_TYPES[:OPT_OUT]) end end end diff --git a/app/models/light/user.rb b/app/models/light/user.rb index 8309e65..d3714b2 100644 --- a/app/models/light/user.rb +++ b/app/models/light/user.rb @@ -1,10 +1,12 @@ +require 'devise' + module Light class User include Mongoid::Document include Mongoid::Slug include Mongoid::History::Trackable - NEW_USER = "new user" + NEW_USER = 'new user' field :email_id, type: String field :username, type: String @@ -28,7 +30,7 @@ class User slug :username - track_history on: [:opt_in_mail_sent_at, :subscribed_at, :remote_ip, + track_history on: [:opt_in_mail_sent_at, :subscribed_at, :remote_ip, :user_agent, :is_subscribed, :unsubscribed_at] before_create do self.joined_on = Date.today @@ -57,7 +59,8 @@ def self.add_users_from_worksheet(worksheet, column = 1) username: worksheet[i + 1, column - 1], is_subscribed: true, joined_on: Date.today, - source: 'Google Spreadsheet') + source: 'Google Spreadsheet' + ) if user.save else @@ -69,8 +72,8 @@ def self.add_users_from_worksheet(worksheet, column = 1) end def self.import(file, email='') - return {error: "Please select CSV file"} if (file.blank? or file.content_type != 'text/csv') - file = CSV.open(file.path, :row_sep => :auto, :col_sep => ",") + return {error: 'Please select CSV file'} if (file.blank? or file.content_type != 'text/csv') + file = CSV.open(file.path, :row_sep => :auto, :col_sep => ',') rows = file.read header = rows.delete_at(0) if header.first.strip.downcase != 'full name' and header[1].strip.downcase != 'email' @@ -80,13 +83,8 @@ def self.import(file, email='') {success: 'You will get an update email.'} end - def self.users_for_opt_in_mail - date = Date.today.strftime("%Y%m") - self.new_users.where(:sent_on.nin => [date], is_blocked: false).order_by([:email_id, :asc]) - end - - def self.users_for_opt_out_mail - date = Date.today.strftime("%Y%m") + def self.get_new_users + date = Date.today.strftime('%Y%m') self.new_users.where(:sent_on.nin => [date], is_blocked: false).order_by([:email_id, :asc]) end end diff --git a/app/views/light/newsletters/_form.html.haml b/app/views/light/newsletters/_form.html.haml index b3261d9..9e3558f 100644 --- a/app/views/light/newsletters/_form.html.haml +++ b/app/views/light/newsletters/_form.html.haml @@ -5,7 +5,7 @@ = "Please Replace unsubscribe link with #{LIGHT_HOST_URL}/unsubscribe/<%= @user_id %>" %br = news.input :subject, :label => "Subject", :input_html => { :class => 'span8', :placeholder => 'Enter subject here...' } - = news.input :newsletter_type, collection: Light::Newsletter::VALID_NEWSLETTER_TYPES.values , + = news.input :newsletter_type, collection: Light::Newsletter::NEWSLETTER_TYPES.values , :label => "Type" = news.text_area :content, :placeholder => "Input here..", :class => "redactor", :rows => 20, :cols => 40 = news.button :submit, class: "btn btn-primary" diff --git a/app/views/light/newsletters/_newsletters.html.haml b/app/views/light/newsletters/_newsletters.html.haml index 7ca5be3..ce3cc87 100644 --- a/app/views/light/newsletters/_newsletters.html.haml +++ b/app/views/light/newsletters/_newsletters.html.haml @@ -1,10 +1,10 @@ = render 'top_navbar' %table.table - -count=3 - -@newsletters.each do |newsletter| - -if count > 2 - -count=0 + - count = 3 + - @newsletters.each do |newsletter| + - if count > 2 + - count = 0 %tr %td %center @@ -14,11 +14,13 @@ = image_tag newsletter.get_image %div.cap %h4 - = newsletter.sent_on.strftime("%B %Y") + = newsletter.sent_on.strftime('%B %Y') = "(#{newsletter.users_count} users)" %center %hr - = link_to "Edit", edit_newsletter_path(newsletter), class: "btn btn-mini btn-success", data: { no_turbolink: true } - = link_to "Delete", newsletter_path(newsletter), method: :delete, class: "btn btn-mini btn-danger" - -count+=1 + = link_to '', edit_newsletter_path(newsletter), class: 'btn btn-lg icon-edit', data: { no_turbolink: true } + = link_to '', newsletter_path(newsletter), method: :delete, class: 'btn btn-lg icon-trash', :data => { :confirm => 'Are you sure, you want to delete newsletter?'} + = link_to 'Send Mail', send_newsletter_path(newsletter), method: :post, :class => 'btn btn-mini btn-danger', :data => { :confirm => 'Are you sure ?'} + = link_to 'Test Mail', test_mail_newsletter_path(newsletter), :class => 'btn btn-mini btn-success' + - count += 1 diff --git a/app/views/light/newsletters/_top_navbar.html.haml b/app/views/light/newsletters/_top_navbar.html.haml index bbabe36..3563fbc 100644 --- a/app/views/light/newsletters/_top_navbar.html.haml +++ b/app/views/light/newsletters/_top_navbar.html.haml @@ -1,16 +1,18 @@ = nav_bar :brand => 'Newsletters', :responsive => true, :static => :top, :fluid => :true do = menu_group do - = menu_item "Add Newsletter", new_newsletter_path - = menu_item "Opt in letters", opt_in_newsletters_path - = menu_item "Opt out letters", opt_out_newsletters_path - = drop_down "Add Users" do - = menu_item "Add Manually", new_user_path - = menu_item "Import Opt-in Users", users_import_path - = menu_item "Google Spreadsheets", spreadsheets_path + = menu_item 'Add Newsletter', new_newsletter_path + = menu_item 'Opt in letters', newsletters_path(type: 'Opt-In Letter') + = menu_item 'Opt out letters', newsletters_path(type: 'Opt-Out Letter') + = drop_down 'Add Users' do + = menu_item 'Add Manually', new_user_path + = menu_item 'Import Opt-in Users', users_import_path + = menu_item 'Google Spreadsheets', spreadsheets_path - = menu_item "Show Users", users_path, ({:method => 'get'} if params[:controller] == 'light/users' && params[:action].in?(['new', 'create'])) - = menu_group :pull => :right do - .btn-mail - = content_tag :a, "Send Mail", :href => sendmailer_path, :class => 'btn btn-danger', :data => { :confirm => 'Are you sure ?'} - = content_tag :a, "Test Mail", :href => testmail_path, :class => 'btn btn-success' + = menu_item 'Show Users', users_path, ({:method => 'get'} if params[:controller] == 'light/users' && params[:action].in?(['new', 'create'])) %br + +:javascript + $(document).ready(function() { + $('.nav').find('.active').removeClass('active'); + $('a[href="' + location.pathname + location.search + '"]').closest('li').addClass('active'); + }); diff --git a/app/views/light/newsletters/opt_in.html.haml b/app/views/light/newsletters/opt_in.html.haml deleted file mode 100644 index e3024f7..0000000 --- a/app/views/light/newsletters/opt_in.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= render 'newsletters' - - diff --git a/app/views/light/newsletters/opt_out.html.haml b/app/views/light/newsletters/opt_out.html.haml deleted file mode 100644 index 0537ed9..0000000 --- a/app/views/light/newsletters/opt_out.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'newsletters' diff --git a/app/views/light/newsletters/show.html.haml b/app/views/light/newsletters/show.html.haml index d1c70c9..8c394af 100644 --- a/app/views/light/newsletters/show.html.haml +++ b/app/views/light/newsletters/show.html.haml @@ -1,11 +1,9 @@ = render 'top_navbar' +%h2.text-center + = @newsletter.subject + = link_to '', edit_newsletter_path(@newsletter), class: 'icon-edit pull-right', data: { no_turbolink: true } = raw @newsletter.content -- if @newsletter.opt_in? - = link_to "Send Opt-In Mail", send_opt_in_newsletter_path(@newsletter), +%center + = link_to 'Send Mail', send_newsletter_path(@newsletter), :class => 'btn btn-danger', :data => { :confirm => 'Are you sure ?'}, method: :post - = link_to "Send Opt-In Test Mail", test_opt_in_newsletter_path(@newsletter), :class => "btn btn-success" - -- elsif @newsletter.opt_out? - = link_to "Send Opt-Out Mail", send_opt_out_newsletter_path(@newsletter), - :class => 'btn btn-danger', :data => { :confirm => 'Are you sure ?'}, method: :post - = link_to "Send Opt-Out Test Mail", test_opt_out_newsletter_path(@newsletter), :class => "btn btn-success" + = link_to 'Send Test Mail', test_mail_newsletter_path(@newsletter), :class => 'btn btn-success' \ No newline at end of file diff --git a/app/views/light/newsletters/test_mail.html.haml b/app/views/light/newsletters/test_mail.html.haml new file mode 100644 index 0000000..56f58ac --- /dev/null +++ b/app/views/light/newsletters/test_mail.html.haml @@ -0,0 +1,18 @@ += render 'top_navbar' +%center + .panel.panel-primary + .panel-heading + %h2 + = @newsletter.subject + Test Mail + .panel-body + = simple_form_for :email, as: :post, url: send_test_mail_newsletter_path(@newsletter), html: {role: 'form', class: 'form-horizontal'} do |f| + %table + %tr + %td + = f.label :email_id + = f.input :email_id, input_html: { placeholder: 'For multiple email ids - separate them by comma', class: 'span4 required'}, + as: :text, label: false, autofocus: true + %tr + %td + = f.button :submit, "Sent Test Mail", class: "btn btn-success span4 pull-right" diff --git a/app/views/light/newsletters/test_opt_in.html.haml b/app/views/light/newsletters/test_opt_in.html.haml deleted file mode 100644 index 3adf6ae..0000000 --- a/app/views/light/newsletters/test_opt_in.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.panel.panel-primary - .panel-heading - Test Mail - .panel-body - = form_for :email, as: :post, url: send_opt_in_test_newsletter_path(@newsletter) do |f| - = f.text_area :email_id - = f.button :submit, class: "btn btn-success" diff --git a/app/views/light/newsletters/test_opt_out.html.haml b/app/views/light/newsletters/test_opt_out.html.haml deleted file mode 100644 index 3636de0..0000000 --- a/app/views/light/newsletters/test_opt_out.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.panel.panel-primary - .panel-heading - Test Mail - .panel-body - = form_for :email, as: :post, url: send_opt_out_test_newsletter_path(@newsletter) do |f| - = f.text_area :email_id - = f.button :submit, class: "btn btn-success" diff --git a/app/views/light/users/_form.html.haml b/app/views/light/users/_form.html.haml index ebd213a..c1e1a73 100644 --- a/app/views/light/users/_form.html.haml +++ b/app/views/light/users/_form.html.haml @@ -5,7 +5,9 @@ = simple_form_for (@user), html: {role: 'form', class: 'form-horizontal'} do |f| = f.input :email_id, input_html:{class: 'span3'} = f.input :username, input_html:{class: 'span3'} - = f.input :is_subscribed, :as => :select, input_html:{class: 'span3'} + = f.label 'Subscribed' + .make-switch{"data-on" => "success", "data-off" => "warning", "data-on-label" => "True", "data-off-label" => "False"} + = f.check_box :is_subscribed, {}, 'true', 'false' = f.input :joined_on, input_html: { 'data-behaviour' => 'datepicker'}, input_html:{class: 'span3'} = f.input :source, input_html:{class: 'span3'} = f.button :submit, class: "btn btn-success controls" diff --git a/app/views/light/users/edit.html.haml b/app/views/light/users/edit.html.haml index a5a2d86..dddcea6 100644 --- a/app/views/light/users/edit.html.haml +++ b/app/views/light/users/edit.html.haml @@ -6,14 +6,13 @@ %td = f.input :email_id, input_html:{class: 'span3'} = f.input :username, input_html:{class: 'span3'} - = f.input :is_subscribed, :as => :select, input_html:{class: 'span3'} - = f.input :joined_on, input_html: { 'data-behaviour' => 'datepicker'}, input_html:{class: 'span3'} + = f.label 'Subscribed' + .make-switch{'data-on': 'success', 'data-off': 'warning', 'data-on-label': 'True', 'data-off-label': 'False'} + = f.check_box :is_subscribed, {}, 'true', 'false' + %br + %br + = f.input :joined_on, input_html: {type: 'date', class: 'date-picker', value: @user.joined_on.try(:strftime, '%Y-%m-%d')} = f.input :source, input_html:{class: 'span3'} = f.button :submit, class: "btn btn-success controls" -:javascript - $('[data-behaviour~=datepicker]').datepicker({ - format: 'yyyy-mm-dd' - }) - diff --git a/app/views/light/users/index.html.haml b/app/views/light/users/index.html.haml index ce54cf5..5328086 100644 --- a/app/views/light/users/index.html.haml +++ b/app/views/light/users/index.html.haml @@ -51,9 +51,9 @@ %td.text-center= '{{email_id}}' %td.text-center= '{{username}}' %td.text-center - %a{ :href => "/newsletter/users/{{_id.$oid}}/edit", :class => 'btn btn-sm btn-success'} Edit + %a{ :href => "/newsletter/users/{{id}}/edit", :class => 'btn btn-sm btn-success'} Edit - %a{ :href => "/newsletter/users/{{_id.$oid}}", data:{ :confirm => 'Are you sure?', method: 'delete'}, :class => 'btn btn-sm btn-danger' } Delete + %a{ :href => "/newsletter/users/{{id}}", data:{ :confirm => 'Are you sure?', method: 'delete'}, :class => 'btn btn-sm btn-danger' } Delete .col-lg-12.padding_none.pull-right #user_pagination.col-lg-12 diff --git a/app/views/light/users/sendmailer.html.haml b/app/views/light/users/sendmailer.html.haml deleted file mode 100644 index 8b13789..0000000 --- a/app/views/light/users/sendmailer.html.haml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/views/light/users/testmail.html.haml b/app/views/light/users/testmail.html.haml deleted file mode 100644 index 5b6f6a2..0000000 --- a/app/views/light/users/testmail.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.panel.panel-primary - .panel-heading - Test Mail - .panel-body - = form_for :email, as: :post, url: sendtest_path do |f| - = f.text_area :email_id - = f.button :submit, class: "btn btn-success" diff --git a/app/workers/light/enqueue.rb b/app/workers/light/enqueue.rb index 9d75ee5..7427ca9 100644 --- a/app/workers/light/enqueue.rb +++ b/app/workers/light/enqueue.rb @@ -5,9 +5,9 @@ class Enqueue def perform(email) date = Date.today.strftime("%Y%m") - news = Light::Newsletter.where(newsletter_type: Light::Newsletter::VALID_NEWSLETTER_TYPES[:MONTHLY]). + news = Light::Newsletter.where(newsletter_type: Light::Newsletter::NEWSLETTER_TYPES[:MONTHLY]). order_by([:sent_on, :desc]).first - Light::UserMailer.welcome_message(email, news, 'test_user_dummy_id').deliver if news + Light::UserMailer.welcome_message(email, news, 'test_user_dummy_id').deliver_now if news end end end diff --git a/app/workers/light/hard_worker.rb b/app/workers/light/hard_worker.rb index 3b86625..3c6eecb 100644 --- a/app/workers/light/hard_worker.rb +++ b/app/workers/light/hard_worker.rb @@ -1,24 +1,28 @@ module Light class HardWorker include Sidekiq::Worker - sidekiq_options :queue => :lightair + sidekiq_options queue: :lightair def perform(user_ids, newsletter_id, date, status = nil) newsletter = Light::Newsletter.where(id: newsletter_id).first user_ids.each do |id| user = Light::User.where(id: id, :sent_on.nin => [date]).first if user.present? - Light::UserMailer.welcome_message(user.email_id, newsletter, user.token).deliver + Light::UserMailer.welcome_message(user.email_id, newsletter, user.token).deliver_now sent_on = user.sent_on << date if status.present? && status.include?('Opt in') - user.update_attributes(sent_on: sent_on, - sidekiq_status: status, - opt_in_mail_sent_at: DateTime.now) + user.update_attributes( + sent_on: sent_on, + sidekiq_status: status, + opt_in_mail_sent_at: DateTime.now + ) elsif status.present? && status.include?('Opt out') - user.update_attributes(sent_on: sent_on, - sidekiq_status: 'Subscribed', - subscribed_at: DateTime.now, - is_subscribed: true) + user.update_attributes( + sent_on: sent_on, + sidekiq_status: 'Subscribed', + subscribed_at: DateTime.now, + is_subscribed: true + ) else user.update_attributes(sent_on: sent_on) end diff --git a/app/workers/light/import_worker.rb b/app/workers/light/import_worker.rb index 3b3a522..e0204d2 100644 --- a/app/workers/light/import_worker.rb +++ b/app/workers/light/import_worker.rb @@ -1,22 +1,27 @@ module Light class ImportWorker include Sidekiq::Worker - sidekiq_options :queue => :lightair + sidekiq_options queue: :lightair - def perform(rows, email_id, source = "Business Card") + def perform(rows, email_id, source = 'Business Card') file_path = "#{Rails.root.to_s}/tmp/import_contacts_#{Time.now.to_i}.csv" - CSV.open(file_path, "wb") do |csv| #creates a tempfile csv + CSV.open(file_path, 'wb') do |csv| #creates a tempfile csv csv << ['Total number of users in the database', Light::User.count] csv << ['Total number of rows in uploaded CSV (including blank)', rows.count] - csv << ["Email", "Name", "Error"] + csv << ['Email', 'Name', 'Error'] rows.each do |row| email = "#{row[1]}" name = "#{row[0] || row[1]}" - user = Light::User.create(username: name, email_id: email, source: source, - is_subscribed: false, sidekiq_status: Light::User::NEW_USER) if email.present? or name.present? + user = Light::User.create( + username: name, + email_id: email, + source: source, + is_subscribed: false, + sidekiq_status: Light::User::NEW_USER + ) if email.present? or name.present? csv << [email, row[0], user.errors.messages] if user.present? and user.errors.present? end - UserMailer.import_contacts_update(email_id, file_path).deliver + UserMailer.import_contacts_update(email_id, file_path).deliver_now end end end diff --git a/app/workers/light/opt_in_worker.rb b/app/workers/light/opt_in_worker.rb index ffc4f24..c06f215 100644 --- a/app/workers/light/opt_in_worker.rb +++ b/app/workers/light/opt_in_worker.rb @@ -4,24 +4,24 @@ class OptInWorker sidekiq_options :queue => :lightair def perform(newsletter_id) - date = Date.today.strftime("%Y%m") - users = Light::User.users_for_opt_in_mail + date = Date.today.strftime('%Y%m') + users = Light::User.get_new_users number_of_opt_in_users = users.count number_of_opt_in_users_count = number_of_opt_in_users current_batch = 0 users_in_batch = 250 - newsletter = Light::Newsletter.find_by(id: newsletter_id) + newsletter = Light::Newsletter.where(id: newsletter_id).first if newsletter while number_of_opt_in_users > 0 user_ids = users.limit(users_in_batch).skip(users_in_batch*current_batch).collect { |user| user.id.to_s } current_batch += 1 number_of_opt_in_users -= users_in_batch - Light::HardWorker.perform_async(user_ids, newsletter.id.to_s, date, "Opt in mail sent") + Light::HardWorker.perform_async(user_ids, newsletter.id.to_s, date, 'Opt in mail sent') end opt_in_count = newsletter.users_count + number_of_opt_in_users_count newsletter.update_attribute(:users_count, opt_in_count) else - logger.info = "No newsletter present" + logger.info = 'No newsletter present' end end end diff --git a/app/workers/light/opt_out_worker.rb b/app/workers/light/opt_out_worker.rb index 72da0b3..9bd8a51 100644 --- a/app/workers/light/opt_out_worker.rb +++ b/app/workers/light/opt_out_worker.rb @@ -4,13 +4,13 @@ class OptOutWorker sidekiq_options :queue => :lightair def perform(newsletter_id) - date = Date.today.strftime("%Y%m") - users = Light::User.users_for_opt_out_mail + date = Date.today.strftime('%Y%m') + users = Light::User.get_new_users number_of_opt_out_users = users.count number_of_opt_out_users_count = number_of_opt_out_users current_batch = 0 users_in_batch = 250 - newsletter = Light::Newsletter.find_by(id: newsletter_id) + newsletter = Light::Newsletter.where(id: newsletter_id).first if newsletter while number_of_opt_out_users > 0 user_ids = users.limit(users_in_batch).skip(users_in_batch*current_batch).collect { |user| user.id.to_s } diff --git a/app/workers/light/user_worker.rb b/app/workers/light/user_worker.rb index 992b28c..f3481d0 100644 --- a/app/workers/light/user_worker.rb +++ b/app/workers/light/user_worker.rb @@ -3,22 +3,21 @@ class UserWorker include Sidekiq::Worker sidekiq_options :queue => :lightair - def perform + def perform(newsletter_id) date = Date.today.strftime("%Y%m") number_of_subscribed_users = Light::User.where(is_subscribed: true, :sent_on.nin => [date], is_blocked: {"$ne" => true}).count - #number_of_subscribed_users = Light::User.users_for_opt_in_mail.count + #number_of_subscribed_users = Light::User.get_new_users.count number_of_subscribed_users_count = number_of_subscribed_users current_batch = 0 users_in_batch = 250 - newsletter = Light::Newsletter.where(newsletter_type: Light::Newsletter::VALID_NEWSLETTER_TYPES[:MONTHLY]). - order_by([:sent_on, :desc]).first + newsletter = Light::Newsletter.where(id: newsletter_id).first - #newsletter = Light::Newsletter.where(newsletter_type: Light::Newsletter::VALID_NEWSLETTER_TYPES[:OPT_IN]). + #newsletter = Light::Newsletter.where(newsletter_type: Light::Newsletter::NEWSLETTER_TYPES[:OPT_IN]). # order_by([:sent_on, :desc]).first if newsletter while number_of_subscribed_users > 0 user_ids = Light::User.where(is_subscribed: true, :sent_on.nin => [date] , is_blocked: {"$ne" => true}).order_by([:email_id, :asc]).limit(users_in_batch).skip(users_in_batch*current_batch).collect { |user| user.id.to_s } - #user_ids = Light::User.users_for_opt_in_mail.order_by([:email_id, :asc]).limit(users_in_batch).skip(users_in_batch*current_batch).collect { |user| user.id.to_s } + #user_ids = Light::User.get_new_users.order_by([:email_id, :asc]).limit(users_in_batch).skip(users_in_batch*current_batch).collect { |user| user.id.to_s } current_batch += 1 number_of_subscribed_users -= users_in_batch Light::HardWorker.perform_async(user_ids, newsletter.id.to_s, date) diff --git a/config/routes.rb b/config/routes.rb index 732fe8f..78a41e7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,28 +1,18 @@ Light::Engine.routes.draw do mount RedactorRails::Engine => '/redactor_rails' - get '/users/sendmailer', to: 'users#sendmailer', as: 'sendmailer' get '/users/subscribe', to: 'users#subscribe', as: 'subscribe' - get '/users/testmail', to: 'users#testmail', as: 'testmail' - post '/users/sendtest', to: 'users#sendtest', as: 'sendtest' - get '/users/remove', to: 'users#remove', as: 'remove' + get '/users/unsubscribe', to: 'users#unsubscribe', as: 'unsubscribe' + delete '/users/remove', to: 'users#remove', as: 'remove' get '/auth/:provider/callback', to: 'spreadsheets#new', as: 'google_spreadsheet' get '/auth/failure', to: 'spreadsheets#failure' match 'users/import', to: 'users#import', via: [:get, :post] resources :newsletters do - collection do - get 'opt-in', as: 'opt_in' - get 'opt-out', as: 'opt_out' - end - member do - get 'test-opt-in' , as: 'test_opt_in' - post 'send-opt-in' , as: 'send_opt_in' - post 'send-opt-in-test' , as: 'send_opt_in_test' - get 'test-opt-out' , as: 'test_opt_out' - post 'send-opt-out' , as: 'send_opt_out' - post 'send-opt-out-test' , as: 'send_opt_out_test' + get 'test', to: 'newsletters#test_mail', as: 'test_mail' + post 'send', to: 'newsletters#send_newsletter', as: 'send' + post 'sendtest', to: 'newsletters#send_test_mail', as: 'send_test_mail' end end diff --git a/spec/controllers/light/newsletters_controller_spec.rb b/spec/controllers/light/newsletters_controller_spec.rb index 095a979..ca11735 100644 --- a/spec/controllers/light/newsletters_controller_spec.rb +++ b/spec/controllers/light/newsletters_controller_spec.rb @@ -2,74 +2,203 @@ module Light -RSpec.describe NewslettersController, :type => :controller do + RSpec.describe NewslettersController, type: :controller do - routes { Light::Engine.routes} + routes { Light::Engine.routes} - context "GET index" do - it "list all the newsletters" do - get :index - expect(response).to render_template("index") - end - end + context 'GET index' do + it 'list all the newsletters' do + get :index + expect(response).to have_http_status(:success) + end - context "GET show" do - let(:newsletter) {FactoryGirl.create(:newsletter)} - it "show the deatails of the newsletters" do - get :show, {:id => newsletter.id} - expect(response).to render_template("show") + it 'list all the newsletters' do + get :index, {type: 'Opt-In Letter'} + expect(response).to have_http_status(:success) + end end - end - context "GET new" do - let(:new_newsletter) {FactoryGirl.create(:newsletter)} - it "display new form for adding newsletter" do - post :new, {newsletter: new_newsletter} - expect(response).to render_template("new") + context 'GET show' do + let(:newsletter) {FactoryGirl.create(:newsletter)} + + it 'show the details of the newsletters' do + get :show, {id: newsletter.id} + expect(assigns(:newsletter)).to eq(newsletter) + expect(response).to render_template('show') + end end - end - context "POST create" do - let(:new_newsletter) {FactoryGirl.attributes_for(:newsletter)} - it "display new form for adding newsletter" do - post :create, {newsletter: new_newsletter} - expect(response).to redirect_to(newsletters_path) + context 'GET new' do + let(:new_newsletter) {FactoryGirl.create(:newsletter)} + + it 'display new form for adding newsletter' do + get :new, {newsletter: new_newsletter} + expect(assigns(:newsletter).new_record?).to eq(true) + expect(response).to render_template('new') + end end - it "not arise" do - post :create, {newsletter: {content: "",sent_on: "2014-1-1", users_count: 0}} - expect(response).to render_template("new") + context 'POST create' do + let(:new_newsletter) {FactoryGirl.attributes_for(:newsletter)} + + it 'display new form for adding newsletter' do + post :create, {newsletter: new_newsletter} + + expect(Newsletter.count).to eq(1) + expect(flash[:success]).to eq('Newsletter created successfully') + expect(response).to redirect_to(newsletters_path(type: 'Monthly Newsletter')) + end + + it 'create a newsletter failure' do + post :create, {newsletter: {content: '', sent_on: '2014-1-1', users_count: 0}} + expect(flash[:error]).to eq('Error while creating newsletter') + expect(response).to render_template('new') + end end - end - context "GET update" do + context 'GET edit' do let(:new_newsletter) {FactoryGirl.create(:newsletter)} - it "fetches the specific newsletter" do + + it 'fetches the specific newsletter' do get :edit, {id: new_newsletter.id} - expect(response).to render_template("edit") + expect(assigns(:newsletter)).to eq(new_newsletter) + expect(response).to render_template('edit') end end - context "DELETE delete" do + context 'PUT update' do + let(:new_newsletter) {FactoryGirl.create(:newsletter)} + + it 'updates details of specified newsletter' do + put :update, {id: new_newsletter.id, newsletter: {subject: 'August 2020'}} + + expect(flash[:success]).to eq('Newsletter updated successfully') + expect(new_newsletter.reload.subject).to eq('August 2020') + expect(response).to redirect_to(newsletters_path(type: new_newsletter.newsletter_type)) + end + + it 'update a newsletter failure' do + put :update, {id: new_newsletter.id, newsletter: {content: ''}} + + expect(flash[:error]).to eq('Error while updating newsletter') + expect(response).to render_template('edit') + end + end + + context 'DELETE delete' do let(:newsletter) {FactoryGirl.create(:newsletter)} - it "delete a newsletter" do + + it 'delete a newsletter success' do delete :destroy, {id: newsletter.id} - expect(response).to redirect_to(newsletters_path) + expect(flash[:success]).to eq('Newsletter deleted successfully') + expect(assigns(:newsletter).destroyed?).to be(true) + expect(response).to redirect_to(newsletters_path(type: newsletter.newsletter_type)) end end - context "PUT update" do - let(:new_newsletter) {FactoryGirl.create(:newsletter)} - it "updates details of specified newsletter" do - put :update, {id: new_newsletter.id, newsletter: {content: new_newsletter.content}} - expect(response).to redirect_to(newsletters_path) + context 'GET test_mail' do + let(:newsletter) {FactoryGirl.create(:newsletter)} + + it 'should render test mail template' do + get :test_mail, {id: newsletter} + expect(response).to render_template('test_mail') + end + end + + context 'POST test_mail' do + let(:newsletter) {FactoryGirl.create(:newsletter)} + + before :each do + ActionMailer::Base.deliveries = [] + end + + it 'should send test mail to email ids passed to it' do + post :send_test_mail, {id: newsletter.id, email: {email_id: 'pamela@joshsoftware.com,winona@joshsoftware.com'}} + + expect(flash[:notice]).to eq('You will receive newsletter on the given email ids shortly.') + expect(ActionMailer::Base.deliveries.count).to eq(1) + expect(ActionMailer::Base.deliveries.first.subject).to eq(newsletter.subject) + expect(ActionMailer::Base.deliveries.first.to.count).to eq(2) + expect(response).to redirect_to(newsletters_path(type: 'Monthly Newsletter')) end - it "not arise" do - put :update, {id: new_newsletter.id, newsletter: {content: ""}} - expect(response).to render_template("edit") + it 'should fail if not email ids passed to it' do + post :send_test_mail, {id: newsletter.id, email: {email_id: ''}} + + expect(flash[:error]).to eq('Atleast one email ID is expected.') + expect(ActionMailer::Base.deliveries.count).to eq(0) + expect(response).to render_template('test_mail') end end -end + context 'POST send_newsletter' do + before :each do + @new_user = FactoryGirl.create(:user, is_subscribed: false, sidekiq_status: 'new user') + @subscribed = FactoryGirl.create(:user, is_subscribed: true, sidekiq_status: 'Subscribed') + @unsubscribed = FactoryGirl.create(:user, is_subscribed: false, sidekiq_status: 'Unubscribed') + @date = Date.today.strftime('%Y%m') + @sent_on_date = DateTime.now + ActionMailer::Base.deliveries = [] + end + + it 'should send monthly newsletter to subscribed users only ' + + 'and update the sent_on attribute for user and newsletter' do + Sidekiq::Testing.inline! do + @monthly = FactoryGirl.create(:newsletter, sent_on: []) + post :send_newsletter, {id: @monthly.id} + + expect(flash[:notice]).to eq('Sent Monthly newsletter successfully') + expect(ActionMailer::Base.deliveries.count).to eq(1) + expect(ActionMailer::Base.deliveries.first.subject).to eq(@monthly.subject) + expect(ActionMailer::Base.deliveries.first.to).to eq([@subscribed.email_id]) + expect(@monthly.reload.users_count).to eq(1) + expect(@subscribed.reload.sent_on).to include(@date) + expect(@unsubscribed.reload.sent_on.empty?).to eq(true) + expect(@new_user.reload.sent_on.empty?).to eq(true) + expect(response).to redirect_to(newsletters_path(type: @monthly.newsletter_type)) + end + end + + it 'should send opt-in newsletter to new users only ' + + 'and update necessary attributes for user and newsletter' do + Sidekiq::Testing.inline! do + @opt_in = FactoryGirl.create(:newsletter, sent_on: [], newsletter_type: 'Opt-In Letter') + post :send_newsletter, {id: @opt_in.id} + + expect(flash[:notice]).to eq('Sent Opt-In newsletter successfully') + expect(ActionMailer::Base.deliveries.count).to eq(1) + expect(ActionMailer::Base.deliveries.first.subject).to eq(@opt_in.subject) + expect(ActionMailer::Base.deliveries.first.to).to eq([@new_user.email_id]) + expect(@opt_in.reload.users_count).to eq(1) + expect(@new_user.reload.sent_on).to include(@date) + expect(@subscribed.reload.sent_on.empty?).to eq(true) + expect(@unsubscribed.reload.sent_on.empty?).to eq(true) + expect(@new_user.sidekiq_status).to eq('Opt in mail sent') + expect(@new_user.opt_in_mail_sent_at).to be > @sent_on_date + expect(response).to redirect_to(newsletters_path(type: @opt_in.newsletter_type)) + end + end + + it 'should send opt-out newsletter to new users only ' + + 'and update necessary attributes for user and newsletter' do + Sidekiq::Testing.inline! do + @opt_out = FactoryGirl.create(:newsletter, sent_on: [], newsletter_type: 'Opt-Out Letter') + post :send_newsletter, {id: @opt_out.id} + + expect(flash[:notice]).to eq('Sent Opt-Out newsletter successfully') + expect(ActionMailer::Base.deliveries.count).to eq(1) + expect(ActionMailer::Base.deliveries.first.subject).to eq(@opt_out.subject) + expect(ActionMailer::Base.deliveries.first.to).to eq([@new_user.email_id]) + expect(@opt_out.reload.users_count).to eq(1) + expect(@new_user.reload.sent_on).to include(@date) + expect(@subscribed.reload.sent_on.empty?).to eq(true) + expect(@unsubscribed.reload.sent_on.empty?).to eq(true) + expect(@new_user.sidekiq_status).to eq('Subscribed') + expect(@new_user.subscribed_at).to be > @sent_on_date + expect(@new_user.is_subscribed).to eq(true) + expect(response).to redirect_to(newsletters_path(type: @opt_out.newsletter_type)) + end + end + end + end end diff --git a/spec/controllers/light/users_controller_spec.rb b/spec/controllers/light/users_controller_spec.rb index 379bd2b..fdb290f 100644 --- a/spec/controllers/light/users_controller_spec.rb +++ b/spec/controllers/light/users_controller_spec.rb @@ -2,134 +2,240 @@ require 'sidekiq/testing' module Light - RSpec.describe UsersController, :type => :controller do + RSpec.describe UsersController, type: :controller do routes { Light::Engine.routes} - context "Get index" do - it "list of user email" do + context 'Get index' do + it 'list of user email' do get :index - expect(response).to render_template("index") + expect(response).to render_template('index') end end - context "GET show" do + context 'GET show' do let(:user) {FactoryGirl.create(:user)} - it "show the details of the users" do + + it 'show the details of the users' do get :show, {id: user.id} - expect(response).to render_template("show") + expect(assigns(:user)).to eq(user) + expect(response).to render_template('show') end end - context "GET new" do + context 'GET new' do let(:new_user) {FactoryGirl.attributes_for(:user)} - it "display new form for adding user" do - post :new, {user: new_user} - expect(response).to render_template("new") + + it 'display new form for adding user' do + get :new, {user: new_user} + expect(assigns(:user).new_record?).to eq(true) + expect(response).to render_template('new') end end - context " POST create" do + context 'POST create' do context 'creates new user' do - before(:all) do - @create_params = {email_id: 'test@sub.com', username: 'test'} + before(:each) do + user = FactoryGirl.build(:user).attributes + @create_params = user.slice('email_id', 'username') end - it "redirects to users path" do + it 'redirects to users path' do post :create, {user: @create_params} + + user = Light::User.last + expect(flash[:success]).to eq('User created successfully') + expect(Light::User.count).to eq(1) + expect(user.email_id).to eq(@create_params['email_id']) + expect(user.username).to eq(@create_params['username']) expect(response).to redirect_to(users_path) end - it "default status is new user and is_subscribed is false" do + it 'default status is new user and is_subscribed is false' do post :create, {user: @create_params} - user = User.find_by(email_id: 'test@sub.com') + user = User.find_by(email_id: @create_params['email_id']) + expect(flash[:success]).to eq('User created successfully') expect(user.sidekiq_status).to eq 'new user' + expect(user.source).to eq 'Manual' expect(user.is_subscribed).to eq false end end - it "not arise" do - post :create, {user: {email_id: "",username: "kanhaiya", is_subscribed: "false"}} - expect(response).to render_template("new") + it 'not arise' do + post :create, {user: {email_id: '', username: 'kanhaiya', is_subscribed: false}} + expect(flash[:error]).to eq('Error while creating user') + expect(response).to render_template('new') end end - context "GET edit" do + context 'GET edit' do let(:new_user) {FactoryGirl.create(:user)} - it "fetches the specific all the users" do + + it 'fetches the specific user record' do get :edit, {id: new_user.id} - expect(response).to render_template("edit") + expect(assigns(:user)).to eq(new_user) + expect(response).to render_template('edit') end end - context "DELETE delete" do + context 'DELETE delete' do let(:user) {FactoryGirl.create(:user)} - it "delete an user" do + + it 'delete an user success' do delete :destroy, {id: user.id} + expect(flash[:success]).to eq('User deleted successfully') + expect(Light::User.count).to eq(0) + expect(assigns(:user).destroyed?).to be(true) expect(response).to redirect_to(users_path) end end + context 'GET remove' do + let(:user) {FactoryGirl.create(:user)} + + it 'remove an user success' do + delete :remove, {token: user.token} + + expect(Light::User.count).to eq(0) + expect(assigns(:user).destroyed?).to be(true) + expect(assigns(:message)).to eq('We have removed you from our database!') + end - context "PUT update" do + it 'remove an user failure' do + delete :remove, {token: 'dummy_token'} + expect(assigns(:message)).to eq('No user with this token exists!') + end + end + + context 'PUT update' do let(:new_user) {FactoryGirl.create(:user)} - it "updates details of specified user" do - patch :update, {id: new_user.id, user: { email_id: new_user.email_id}} + + it 'updates details of specified user' do + patch :update, {id: new_user.id, user: {username: 'kanhaiya'}} + + expect(flash[:success]).to eq('User info updated successfully') + expect(new_user.reload.username).to eq('kanhaiya') expect(response).to redirect_to(users_path) end - it " not arise" do - put :update, {id: new_user.id, user: { email_id: ""}} - expect(response).to render_template("edit") + + it 'not arise' do + put :update, {id: new_user.id, user: { email_id: ''}} + expect(flash[:error]).to eq('Error while updating user') + expect(response).to render_template('edit') end end - context "GET subscribe" do - let(:new_user) {FactoryGirl.create(:user)} - it "unsubcribes a particular user" do - get :subscribe, {id: new_user.id} - expect(response).to render_template("subscribe") + context 'GET subscribe' do + let(:user) {FactoryGirl.create(:user)} + + it 'should update the status to Subscribe if user is Unsubscribed' do + user.update_attributes(sidekiq_status: 'Unsubscribed') + get :subscribe, {token: user.token} + + expect(user.reload.sidekiq_status).to eq('Subscribed') + expect(user.is_subscribed).to eq(true) + expect(assigns(:message)).to eq('Subscribed successfully!!') + expect(response).to render_template('subscribe') end - end - context "GET sendmailer" do - it "sends mails to user" do - VCR.use_cassette 'controllers/user-mails', record: :new_episodes do - get :sendmailer - expect(response).to redirect_to(newsletters_path) - end + it 'should send appropriate message if user is already subscribed' do + user.update_attributes(sidekiq_status: 'Subscribed') + get :subscribe, {token: user.token} + + expect(user.reload.sidekiq_status).to eq('Subscribed') + expect(user.is_subscribed).to eq(true) + expect(assigns(:message)).to eq('You have already Subscribed!!') + expect(response).to render_template('subscribe') + end + + it 'should send appropriate message if token is dummy' do + get :subscribe, {token: 'test_user_dummy_id'} + + expect(assigns(:message)).to eq('Subscribed successfully!!') + expect(assigns(:user).present?).to eq(false) + expect(response).to render_template('subscribe') + end + + it 'should send appropriate message if token is invalid' do + response_msg = 'Hey, it seems request you are trying to access is invalid. If you have any ' + + 'concerns about our newsletters subscription, kindly get in touch with ' + + "hr@joshsoftware.com" + get :subscribe, {token: 'invalid token'} + + expect(assigns(:message)).to eq(response_msg) + expect(assigns(:user).present?).to eq(false) + expect(response).to render_template('subscribe') end end - context "GET sendTest" do - it "sends Test mails to user" do - VCR.use_cassette 'controllers/user-mails', record: :new_episodes do - get :sendtest, email: {email_id: "pankajb@joshsoftware.com"} - expect(response).to redirect_to(newsletters_path) - end + context 'GET unsubscribe' do + let(:user) {FactoryGirl.create(:user)} + + it 'should update the status to Subscribe if user is Unsubscribed' do + user.update_attributes(sidekiq_status: 'Subscribed') + get :unsubscribe, {token: user.token} + + expect(user.reload.sidekiq_status).to eq('Unsubscribed') + expect(user.is_subscribed).to eq(false) + expect(assigns(:message)).to eq('Unsubscribed successfully!!') + expect(response).to render_template('unsubscribe') + end + + it 'should send appropriate message if user is already subscribed' do + user.update_attributes(sidekiq_status: 'Unsubscribed') + get :unsubscribe, {token: user.token} + + expect(user.reload.sidekiq_status).to eq('Unsubscribed') + expect(user.is_subscribed).to eq(true) + expect(assigns(:message)).to eq('You have already Unsubscribed!!') + expect(response).to render_template('unsubscribe') + end + + it 'should send appropriate message if token is dummy' do + get :unsubscribe, {token: 'test_user_dummy_id'} + + expect(assigns(:message)).to eq('Unsubscribed successfully!!') + expect(assigns(:user).present?).to eq(false) + expect(response).to render_template('unsubscribe') + end + + it 'should send appropriate message if token is invalid' do + response_msg = 'Hey, it seems request you are trying to access is invalid. If you have any ' + + "concerns about our newsletter's subscription, kindly get in touch with " + + "hr@joshsoftware.com" + get :unsubscribe, {token: 'invalid token'} + + expect(assigns(:message)).to eq(response_msg) + expect(assigns(:user).present?).to eq(false) + expect(response).to render_template('unsubscribe') end end context 'GET import' do it 'should render import template' do get :import - expect(response).to render_template("import") + expect(response).to render_template('import') end end context 'POST import ' do - context 'data from file import_users.csv' do - let(:file) { Rack::Test::UploadedFile.new("#{Rails.root}/files/import_users.csv", 'text/csv') } - let!(:existing_user) {create :user, username: "Winona Bayer", email_id: "winona@gmail.com", is_subscribed: false } + let!(:existing_user) { + create :user, + username: 'Winona Bayer', + email_id: 'winona@gmail.com', + is_subscribed: false + } it 'File to be imported should contain following data ' do - users = [['Full Name', 'Email'], - ["Miss Pamela Kovacek","pamela@gmail.com"], - [nil, "claud@gmail.com"], - ["Delmer Botsford", nil], - ["Winona Bayer", "winona@gmail.com"], + users = [ + ['Full Name', 'Email'], + ['Miss Pamela Kovacek','pamela@gmail.com'], + [nil, 'claud@gmail.com'], + ['Delmer Botsford', nil], + ['Winona Bayer', 'winona@gmail.com'] ] expect(User.find_by(email_id: users.last.last)).to be_present rows = CSV.read(file.path) @@ -139,39 +245,38 @@ module Light it 'should import users with valid information' do post :import, file: file - expect(flash['success']).to eq("You will get an update email.") + expect(flash['success']).to eq('You will get an update email.') expect(ImportWorker.jobs.size).to eq(1) ImportWorker.drain expect(ImportWorker.jobs.size).to eq(0) expect(User.count).to eq(3) - expect(User.find_by(email_id: "pamela@gmail.com")).to be_present + expect(User.find_by(email_id: 'pamela@gmail.com')).to be_present existing_user.reload expect(existing_user).to be_present expect(existing_user.is_subscribed).to eq(false) - user = User.find_by(email_id: "claud@gmail.com") + user = User.find_by(email_id: 'claud@gmail.com') expect(user).to be_present expect(user.is_subscribed).to eq(false) expect(user.sidekiq_status).to eq('new user') - expect(user.source).to eq("Business Card") + expect(user.source).to eq('Business Card') expect(user.username).to eq(user.email_id) # Since username is empty we are storing email id in username end end + context 'should return success if' do - after do - create :user, username: "Winona Bayer", email_id: "winona@gmail.com", is_subscribed: false - file = Rack::Test::UploadedFile.new(@file_path, 'text/csv') + file = Rack::Test::UploadedFile.new(@file_path, 'text/csv') post :import, file: file - expect(flash['success']).to eq("You will get an update email.") + expect(flash['success']).to eq('You will get an update email.') expect(ImportWorker.jobs.size).to eq(1) ImportWorker.drain expect(ImportWorker.jobs.size).to eq(0) expect(User.count).to eq(3) - expect(User.find_by(email_id: "pamela@gmail.com")).to be_present + expect(User.find_by(email_id: 'pamela@gmail.com')).to be_present end it 'header contains spaces before or after name' do @@ -187,7 +292,7 @@ module Light end end - context "should raise error if " do + context 'should raise error if' do it "headers doesn't match" do User.destroy_all file2 = Rack::Test::UploadedFile.new("#{Rails.root}/files/import_without_header.csv", 'text/csv') @@ -200,12 +305,10 @@ module Light User.destroy_all file2 = Rack::Test::UploadedFile.new("#{Rails.root}/files/contacts.txt") post :import, file: file2 - expect(flash[:error]).to eq("Please select CSV file") + expect(flash[:error]).to eq('Please select CSV file') expect(User.all).to be_empty end end end - end - end diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb index ec2c5f8..e47be32 100644 --- a/spec/dummy/config/environments/test.rb +++ b/spec/dummy/config/environments/test.rb @@ -14,7 +14,7 @@ config.eager_load = false # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_assets = true + config.serve_static_files = true config.static_cache_control = 'public, max-age=3600' # Show full error reports and disable caching. diff --git a/spec/mailers/light/user_mailer_spec.rb b/spec/mailers/light/user_mailer_spec.rb index 03dace1..f2bf7a3 100644 --- a/spec/mailers/light/user_mailer_spec.rb +++ b/spec/mailers/light/user_mailer_spec.rb @@ -9,7 +9,7 @@ module Light ActionMailer::Base.delivery_method = :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries = [] - UserMailer.welcome_message(user.email_id, FactoryGirl.create(:newsletter), user.id).deliver + UserMailer.welcome_message(user.email_id, FactoryGirl.create(:newsletter), user.id).deliver_now end after(:each) do diff --git a/spec/models/light/newsletter_spec.rb b/spec/models/light/newsletter_spec.rb index 902b5ad..e7ec0ef 100644 --- a/spec/models/light/newsletter_spec.rb +++ b/spec/models/light/newsletter_spec.rb @@ -1,20 +1,52 @@ require 'rails_helper' module Light - RSpec.describe Newsletter, :type => :model do + RSpec.describe Newsletter, type: :model do before(:each) do @newsletter = FactoryGirl.create(:newsletter) end - it "validates presence of content" do - expect(@newsletter.content).to be_present + describe 'validates' do + it 'presence of content' do + expect(@newsletter.content).to be_present + end + + it 'presence of sent date' do + expect(@newsletter.sent_on).to be_present + end + + it 'presence of user count' do + expect(@newsletter.users_count).to be_present + end + + it 'default value of type to be Monthly Newsletter' do + @newsletter.update_attribute(:newsletter_type, 'Monthly Newsletter') + expect(@newsletter.newsletter_type).to include('Monthly Newsletter') + end end - it "validates presence of sent date" do - expect(@newsletter.sent_on).to be_present + context 'get_image' do + it 'should return default url if no photo present' do + expect(@newsletter.get_image).to include('/images/newsletter.jpg') + end + end + + context 'opt_in?' do + it 'should return true if type of newsletter is opt-in' do + @newsletter.update_attribute(:newsletter_type, 'Opt-In Letter') + expect(@newsletter.opt_in?).to eq(true) + end + + it 'should return false if type of newsletter is not opt-in' do + @newsletter.update_attribute(:newsletter_type, 'Monthly Newsletter') + expect(@newsletter.opt_in?).to eq(false) + end end - it "validates presence of user count" do - expect(@newsletter.users_count).to be_present + context 'opt_out?' do + it 'should return false if type of newsletter is not opt-out' do + @newsletter.update_attribute(:newsletter_type, 'Monthly Newsletter') + expect(@newsletter.opt_out?).to eq(false) + end end end end diff --git a/spec/models/light/user_spec.rb b/spec/models/light/user_spec.rb index c837dde..56198b7 100644 --- a/spec/models/light/user_spec.rb +++ b/spec/models/light/user_spec.rb @@ -1,32 +1,32 @@ require 'rails_helper' module Light -RSpec.describe User, :type => :model do - before(:each) do - @user = FactoryGirl.create(:user) - end + RSpec.describe User, type: :model do + before(:each) do + @user = FactoryGirl.create(:user) + end - it "validates presence of email_id" do - expect(@user.email_id).to be_present - end + it 'validates presence of email_id' do + expect(@user.email_id).to be_present + end - it "validates presence of subcription" do - expect(@user.is_subscribed).to be_present - end + it 'validates presence of subcription' do + expect(@user.is_subscribed).to be_present + end - it "validates presence of joined date" do - expect(@user.joined_on).to be_present - end + it 'validates presence of joined date' do + expect(@user.joined_on).to be_present + end - it "validates presence of source" do - expect(@user.source).to be_present - end + it 'validates presence of source' do + expect(@user.source).to be_present + end - it "validates uniqueness of email id" do - k=User.new(@user.attributes) - expect(k).not_to be_valid - end + it 'validates uniqueness of email id' do + k=User.new(@user.attributes) + expect(k).not_to be_valid + end - let(:user) {FactoryGirl.create(:user)} - let(:newsletter) {FactoryGirl.create(:newsletter)} -end + let(:user) {FactoryGirl.create(:user)} + let(:newsletter) {FactoryGirl.create(:newsletter)} + end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 8330fe5..51f5efc 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,114 +1,2 @@ -ENV["RAILS_ENV"] ||= 'test' -require_relative 'dummy/config/environment' require 'spec_helper' -#require 'rspec/autorun' -require 'rspec/rails' -ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../') - -Dir[File.join(ENGINE_RAILS_ROOT, "spec/helpers/**/*.rb")].each {|f| require f } -Dir[File.join(ENGINE_RAILS_ROOT, "spec/factories/**/*.rb")].each {|f| require f } -# This file was generated by the `rails generate rspec:install` command. Conventionally, all -# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. -# The generated `.rspec` file contains `--require spec_helper` which will cause this -# file to always be loaded, without a need to explicitly require it in any files. -# -# Given th at it is always loaded, you are encouraged to keep this file as -# light-weight as possible. Requiring heavyweight dependencies from this file -# will add to the boot time of your test suite on EVERY test run, even for an -# individual file that may not need all of that loaded. Instead, make a -# separate helper file that requires this one and then use it only in the specs -# that actually need it. -# -# The `.rspec` file also contains a few flags that are not defaults but that -# users commonly want. -# -# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration - - -RSpec.configure do |config| - - config.before(:suite) do - DatabaseCleaner.strategy = :truncation - DatabaseCleaner.clean_with(:truncation) - end - - config.before(:each) do - Rails.application.load_seed - DatabaseCleaner.start - end - - config.after(:each) do - DatabaseCleaner.clean - end - - #config.before(:each) {@routes = Light::Engine.routes} -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed - - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # Enable only the newer, non-monkey-patching expect syntax. - # For more details, see: - # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax - expectations.syntax = :expect - end - - # rspec-mocks config goes here. You can use an alternate test double - # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| - # Enable only the newer, non-monkey-patching expect syntax. - # For more details, see: - # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - mocks.syntax = :expect - - # Prevents you from mocking or stubbing a method that does not exist on - # a real object. This is generally recommended. - mocks.verify_partial_doubles = true - end -=end - -config.infer_base_class_for_anonymous_controllers = false -config.order = "random" -config.include FactoryGirl::Syntax::Methods -I18n.enforce_available_locales = false - -#config.include Mongoid::Matchers -#config.extend ControllerHelper, type: :controller -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c1f0efb..920f3cc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,16 +1,18 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' +ENV['RAILS_ENV'] ||= 'test' require 'simplecov' SimpleCov.start 'rails' require_relative 'dummy/config/environment' -require 'rspec/autorun' require 'rspec/rails' require 'database_cleaner' require 'sidekiq/testing' require 'webmock/rspec' Sidekiq::Testing.fake! +# globally disable all history tracking by default +Mongoid::History.disable! + ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../') Dir[File.join(ENGINE_RAILS_ROOT, "spec/helpers/**/*.rb")].each {|f| require f } @@ -39,7 +41,6 @@ end config.before(:each) do - Rails.application.load_seed DatabaseCleaner.start end @@ -51,15 +52,12 @@ # automatically. This will be the default behavior in future versions of # rspec-rails. config.infer_base_class_for_anonymous_controllers = false - + config.use_transactional_fixtures = false # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 - config.order = "random" - + config.order = 'random' config.include FactoryGirl::Syntax::Methods - I18n.enforce_available_locales = false - end