From 6a2b547f04c23a2dcf62a6668087ffcc7f384d12 Mon Sep 17 00:00:00 2001 From: amitk Date: Wed, 12 Jul 2017 15:26:56 +0530 Subject: [PATCH 01/11] One can download the Requests which are active and inactive A route added to redeem request with a method download in the controller to download requests in csv format. --- .../stylesheets/admin/redeem_requests.scss | 4 ++++ .../admin/redeem_requests_controller.rb | 23 +++++++++++++++---- .../redeem_requests/_redeem_request.html.haml | 1 + .../admin/redeem_requests/_tagtable.html.haml | 1 + .../admin/redeem_requests/index.html.haml | 7 ++++-- config/application.rb | 1 + config/routes.rb | 6 ++++- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/admin/redeem_requests.scss b/app/assets/stylesheets/admin/redeem_requests.scss index 52998458..a3e8e012 100644 --- a/app/assets/stylesheets/admin/redeem_requests.scss +++ b/app/assets/stylesheets/admin/redeem_requests.scss @@ -3,4 +3,8 @@ // You can use Sass (SCSS) here: http://sass-lang.com/ .slide{ float: right; +} + +.btn-group{ + float: right; } \ No newline at end of file diff --git a/app/controllers/admin/redeem_requests_controller.rb b/app/controllers/admin/redeem_requests_controller.rb index a14227a0..c6adbefa 100644 --- a/app/controllers/admin/redeem_requests_controller.rb +++ b/app/controllers/admin/redeem_requests_controller.rb @@ -1,12 +1,10 @@ class Admin::RedeemRequestsController < ApplicationController before_action :authenticate_user! before_action :authenticate_admin! + before_action :load_redeem_request, only: [:index, :download] def index - #status(false) = status(Open) - #status(true) = status(Close) - @status = params[:status] ? params[:status] : false - @redeem_requests = RedeemRequest.where(:status => @status).desc(:created_at).page(params[:page]) + @redeem_requests = @redeem_requests.page(params[:page]) if request.xhr? respond_to do|format| format.js @@ -30,10 +28,27 @@ def destroy redirect_to admin_redeem_requests_path end + def download + csv_string = CSV.generate do |csv| + csv << ["user","Gift Shop", "Store","Points","cost","Date","coupon Code","Address"] + @redeem_requests.each do |redeem_request| + csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at,redeem_request.coupon_code,redeem_request.address] + end + end + send_data csv_string, + :type => 'text/csv; header=present;', + :disposition => "filename=requests.csv" + end + private def redeem_params params.fetch(:redeem_request).permit(:coupon_code, :comment, :points, :status) end + def load_redeem_request + @status = params[:status] ? params[:status] : false + @redeem_requests = RedeemRequest.where(:status => @status).desc(:created_at) + end + end diff --git a/app/views/admin/redeem_requests/_redeem_request.html.haml b/app/views/admin/redeem_requests/_redeem_request.html.haml index 2cdbbcd5..e2750f5d 100644 --- a/app/views/admin/redeem_requests/_redeem_request.html.haml +++ b/app/views/admin/redeem_requests/_redeem_request.html.haml @@ -7,6 +7,7 @@ = redeem_request.retailer.upcase %td= redeem_request.store? ? redeem_request.store.upcase : "NA" %td= redeem_request.points + %td= redeem_request.points/10 %td= redeem_request.created_at.strftime('%D %T') %td= redeem_request.coupon_code %td= redeem_request.address diff --git a/app/views/admin/redeem_requests/_tagtable.html.haml b/app/views/admin/redeem_requests/_tagtable.html.haml index f25d12df..93127959 100644 --- a/app/views/admin/redeem_requests/_tagtable.html.haml +++ b/app/views/admin/redeem_requests/_tagtable.html.haml @@ -4,6 +4,7 @@ %th.col-xs-1 Gift Shop %th.col-xs-1 Store %th.col-xs-1 Points + %th.col-xs-1 Cost($) %th.col-xs-2 Date %th.col-xs-2 Coupon Code %th.col-xs-1 Address diff --git a/app/views/admin/redeem_requests/index.html.haml b/app/views/admin/redeem_requests/index.html.haml index 9a0ca001..bd890c2f 100644 --- a/app/views/admin/redeem_requests/index.html.haml +++ b/app/views/admin/redeem_requests/index.html.haml @@ -1,9 +1,12 @@ %section.content-header %h1 - Redeem Requests + Redeem Requests %label.slide %input.check#redeem{checked: 'checked', name: 'status', type: 'checkbox', data: {toggle: 'toggle', width: '100', height: '40', on: 'Status Open', off: 'Status Close'}} - #console-event + #console-event + .btn-group + %a.btn.btn-primary.glyphicon.glyphicon-download{:href => download_admin_redeem_requests_path(:status => "false")} Active + %a.btn.btn-primary.glyphicon.glyphicon-download{:href => download_admin_redeem_requests_path(:status => "true") } Completed %section.content .row .col-xs-12 diff --git a/config/application.rb b/config/application.rb index 4d8f5c85..14391b1f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,5 +1,6 @@ require File.expand_path('../boot', __FILE__) +require 'csv' require 'rails' # Pick the frameworks you want: require 'active_model/railtie' diff --git a/config/routes.rb b/config/routes.rb index a39f398a..cfbd23b5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -51,7 +51,11 @@ get :mark_as_close end - resources :redeem_requests, only: [:index, :update, :destroy] + resources :redeem_requests, only: [:index, :update, :destroy] do + collection do + get 'download' + end + end resources :ignored_files, except: [:show] do get :search, on: :collection From 2467b3b6587dacdce858a7815ed0abdb77648958 Mon Sep 17 00:00:00 2001 From: amitk Date: Wed, 12 Jul 2017 16:50:22 +0530 Subject: [PATCH 02/11] Data export in form of csv[#296] --- app/controllers/admin/redeem_requests_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/redeem_requests_controller.rb b/app/controllers/admin/redeem_requests_controller.rb index c6adbefa..68da6dbf 100644 --- a/app/controllers/admin/redeem_requests_controller.rb +++ b/app/controllers/admin/redeem_requests_controller.rb @@ -32,7 +32,7 @@ def download csv_string = CSV.generate do |csv| csv << ["user","Gift Shop", "Store","Points","cost","Date","coupon Code","Address"] @redeem_requests.each do |redeem_request| - csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at,redeem_request.coupon_code,redeem_request.address] + csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at.strftime(fmt='%F %T'),redeem_request.coupon_code,redeem_request.address] end end send_data csv_string, From 50966a4a2b2286313c56cb6696d9d70441d3e1a1 Mon Sep 17 00:00:00 2001 From: tejaswini-gambhire Date: Wed, 12 Jul 2017 13:05:14 +0530 Subject: [PATCH 03/11] Sponsor signup feature (#299) * Adds is_sponsorere field for sponsors[#276] * Displays sponsor button on all webpages[#276] A floating Sponsor button is displayed on homepage as well as at the right side of each page if user is not sponsorer * Adds mongoid-paperclip gem for image upload[#276] * Defines routes for sponsorer detail[#277] * defines payment plans for sponsor[#277] * creates sponsorer details model[#277] * creates viewes for sponsor[#277] * testcases for sponsor detail model[#276] * Sponsorer need not to set goal on signup[#276] * triggers the button click on sign up of sponsor[#276] * creates controller for sponsorer detail[#276] * test cases for sponsorer details controller[#276] * modifies partial for sponsor button[#276] * helper for sponsorer detail[#276] * creates sidebar for sponsor[#276] * Associates user model with sponsorer detail[#276] * github signup of sponsor and it's testcases[#276] * Ignores local storage of sponsor profile photos[#276] * Adds stripe gem for recurring payments[#276] * Configures stripe keys for application[#276] * Changes in SponsorerDetail model[#276] changes the type of payment plan from integer to string, adds some extra fields for subscription and changes in validations * Changes the names of SPONSOR config variables[#276] * Modifies sponsorship details form to add stripe checkout[#276] * Creates stripe customer and subscription[#276] * Modifies sponsor dashboard, sidebar and profile[#276] * Adds route for stripe webhook[#276] * Creates stripe controller for handling stripe events with webhook[#276] * Creates mailer to notify sponsor[#276] * Sends an email on payment failure to sponsorer[#276] * Modifies stripe subscription creation[#276] Creates subscription and customer on stripe by one function call only instead of creating it separately * Skips set goal for sponsorer[#276] * Adds validations for stripe subscription details[#276] presence validation on stripe customer id, subscription id, status etc. * client side validation for image upload[#276] verifies whether uploaded file is image only * Replaces create.js.haml with create.html.haml[#276] * Adds update credit card functionality for sponsore[#276] Sponsor can update his credit card details * Minor changes in sponsor index and omniauth controller[#276] * Adds route for updating credit card[#276] * Modifies sponsorer_details factory[#276] * Adds stripe_ruby_mock gem for testing stripe[#276] * Removes presence validation on stripe details[#276] Form is validated before creating stripe subscription so removed the validation on these fields * Shows subscrption details on sponsor index page[#276] Earlier subscription details were shown on users profile page * Adds route for cancel subscription[#276] * Allowes sponsorer to cancel subscription[#276] * Modification in sponsorer detail testcase[#276] * Functional test cases for SponsorerDetail[#276] * Creates Payment model[#276] Stores the details of monthly payment * Creates association between sponsorer detail and payment[#276] * Handles stripe events[#276] * Shows payment details of sponsor[#276] * Optimizes the stripe controller[#276] * Saves payment details of sponsorer[#276] Saves payment detail when invoice payment succeded event triggers * Adds validations for payment model * Minor modifications in sponsorer controller[#276] * Moves subscription deletion code to concern[#276] * Cancels subscription while deleting account[#276] If user is sponsorer and tries to delete his account first cancel his subscription and then delete his account * Creates partial for mail signature[#276] * Yields the mail signature within layout[#276] * Renders the mail signature in the mailers[#276] * Uses different mail signature for sponsor mailer[#276] * Minor changes in sponsor's functional testcase[#276] * Testcase scenarios for stripe controller[#276] * Fixes the javascript reference error[#276] Fixes the error that was causing to fail integration test cases * Fixes the failure and error in test cases[#276] * Fixes the pagination of sponsorer payment details[#276] * Fixes failing test cases of sponsorer detail[#276] --- .gitignore | 3 + Gemfile | 3 + Gemfile.lock | 37 ++++- .../javascripts/sponsorer_details.coffee | 30 ++++ app/assets/javascripts/stripe.coffee | 3 + app/assets/stylesheets/application.scss | 53 +++++++ app/assets/stylesheets/sponsorer_details.scss | 3 + app/assets/stylesheets/stripe.scss | 3 + app/controllers/application_controller.rb | 8 +- app/controllers/concerns/sponsorer_helper.rb | 13 ++ .../sponsorer_details_controller.rb | 86 ++++++++++ app/controllers/stripe_controller.rb | 70 +++++++++ .../users/omniauth_callbacks_controller.rb | 16 ++ app/controllers/users_controller.rb | 10 ++ app/helpers/sponsorer_details_helper.rb | 2 + app/helpers/stripe_helper.rb | 2 + app/mailers/sponsor_mailer.rb | 14 ++ app/models/payment.rb | 12 ++ app/models/sponsorer_detail.rb | 54 +++++++ app/models/user.rb | 8 +- .../application/_mail_signature.html.haml | 9 ++ app/views/application/_sidebar.html.haml | 5 + app/views/application/_sponsor.html.haml | 13 ++ .../group_invitation_mailer/invite.html.haml | 3 + app/views/home/index.html.haml | 1 + app/views/layouts/application.html.haml | 2 + app/views/layouts/mailer.html.haml | 10 +- app/views/layouts/mailer.text.haml | 1 + app/views/redeem_mailer/coupon_code.html.haml | 3 + .../redeem_mailer/notify_admin.html.haml | 3 + .../redeem_mailer/redeem_request.html.haml | 3 + .../notify_subscription_details.html.haml | 15 ++ .../subscription_payment_failed.html.haml | 13 ++ .../sponsorer_details/_individual.html.haml | 15 ++ app/views/sponsorer_details/_new.html.haml | 22 +++ .../sponsorer_details/_organization.html.haml | 15 ++ .../sponsorer_details/_payment.html.haml | 5 + .../_payments_table.html.haml | 11 ++ app/views/sponsorer_details/create.html.haml | 8 + app/views/sponsorer_details/index.html.haml | 81 ++++++++++ app/views/sponsorer_details/index.js.haml | 1 + app/views/sponsorer_details/new.js.haml | 2 + .../subscription_mailer/progress.html.haml | 3 + .../redeem_points.html.haml | 3 + .../subscription_email.html.haml | 3 + app/views/users/_sponsor_profile.html.haml | 13 ++ config/code_curiosity_config.yml | 10 ++ config/initializers/globals.rb | 1 + config/initializers/stripe.rb | 6 + config/routes.rb | 9 ++ .../sponsorer_details_controller_test.rb | 148 ++++++++++++++++++ test/controllers/stripe_controller_test.rb | 43 +++++ .../omniauth_callbacks_controller_test.rb | 55 ++++++- test/factories/payments.rb | 5 + test/factories/sponsorer_details.rb | 21 +++ test/fixtures/rails.png | Bin 0 -> 13729 bytes test/fixtures/test.csv | 4 + test/helpers/sponsorer_details_helper_test.rb | 5 + test/helpers/stripe_helper_test.rb | 5 + .../previews/sponsor_mailer_preview.rb | 4 + test/mailers/sponsor_mailer_test.rb | 4 + test/models/payment_test.rb | 5 + test/models/sponsorer_detail_test.rb | 78 +++++++++ test/models/user_test.rb | 4 + test/test_helper.rb | 1 + 65 files changed, 1088 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/sponsorer_details.coffee create mode 100644 app/assets/javascripts/stripe.coffee create mode 100644 app/assets/stylesheets/sponsorer_details.scss create mode 100644 app/assets/stylesheets/stripe.scss create mode 100644 app/controllers/concerns/sponsorer_helper.rb create mode 100644 app/controllers/sponsorer_details_controller.rb create mode 100644 app/controllers/stripe_controller.rb create mode 100644 app/helpers/sponsorer_details_helper.rb create mode 100644 app/helpers/stripe_helper.rb create mode 100644 app/mailers/sponsor_mailer.rb create mode 100644 app/models/payment.rb create mode 100644 app/models/sponsorer_detail.rb create mode 100644 app/views/application/_mail_signature.html.haml create mode 100644 app/views/application/_sponsor.html.haml create mode 100644 app/views/layouts/mailer.text.haml create mode 100644 app/views/sponsor_mailer/notify_subscription_details.html.haml create mode 100644 app/views/sponsor_mailer/subscription_payment_failed.html.haml create mode 100644 app/views/sponsorer_details/_individual.html.haml create mode 100644 app/views/sponsorer_details/_new.html.haml create mode 100644 app/views/sponsorer_details/_organization.html.haml create mode 100644 app/views/sponsorer_details/_payment.html.haml create mode 100644 app/views/sponsorer_details/_payments_table.html.haml create mode 100644 app/views/sponsorer_details/create.html.haml create mode 100644 app/views/sponsorer_details/index.html.haml create mode 100644 app/views/sponsorer_details/index.js.haml create mode 100644 app/views/sponsorer_details/new.js.haml create mode 100644 app/views/users/_sponsor_profile.html.haml create mode 100644 config/initializers/stripe.rb create mode 100644 test/controllers/sponsorer_details_controller_test.rb create mode 100644 test/controllers/stripe_controller_test.rb create mode 100644 test/factories/payments.rb create mode 100644 test/factories/sponsorer_details.rb create mode 100644 test/fixtures/rails.png create mode 100644 test/fixtures/test.csv create mode 100644 test/helpers/sponsorer_details_helper_test.rb create mode 100644 test/helpers/stripe_helper_test.rb create mode 100644 test/mailers/previews/sponsor_mailer_preview.rb create mode 100644 test/mailers/sponsor_mailer_test.rb create mode 100644 test/models/payment_test.rb create mode 100644 test/models/sponsorer_detail_test.rb diff --git a/.gitignore b/.gitignore index c00181ae..33940e8d 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,9 @@ # Ignore ENV variables *.env.* +# Ignore local storage of profile photos +/public/system/sponsorer + 1 dump.rdb /repositories diff --git a/Gemfile b/Gemfile index bc74039e..610c32b0 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,8 @@ gem 'mongoid-slug', '~> 5.2' gem 'redcarpet' gem 'rollbar' gem 'mongoid-paranoia' +gem 'mongoid-paperclip', require: 'mongoid_paperclip' +gem 'stripe' group :development, :test do gem 'byebug' @@ -60,6 +62,7 @@ group :test do gem 'poltergeist' gem 'mocha' gem 'timecop' + gem 'stripe-ruby-mock', '~> 2.4.1', :require => 'stripe_mock' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 87994ba3..b731cb2b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,7 +82,10 @@ GEM rack-test (>= 0.5.4) xpath (~> 2.0) chronic (0.10.2) + climate_control (0.1.0) cliver (0.3.2) + cocaine (0.5.8) + climate_control (>= 0.0.3, < 1.0) codeclimate-test-reporter (0.6.0) simplecov (>= 0.7.1, < 1.0.0) coderay (1.1.1) @@ -97,6 +100,7 @@ GEM connection_pool (2.2.0) crack (0.4.3) safe_yaml (~> 1.0.0) + dante (0.2.0) database_cleaner (1.5.3) debug_inspector (0.0.2) descendants_tracker (0.0.4) @@ -109,6 +113,8 @@ GEM thread_safe (~> 0.1) warden (~> 1.2.3) docile (1.1.5) + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) dotenv (2.1.1) dotenv-rails (2.1.1) dotenv (= 2.1.1) @@ -151,6 +157,8 @@ GEM haml (~> 4.0.0) nokogiri (~> 1.6.0) ruby_parser (~> 3.5) + http-cookie (1.0.3) + domain_name (~> 0.5) i18n (0.7.0) jbuilder (2.6.0) activesupport (>= 3.0.0, < 5.1) @@ -175,6 +183,7 @@ GEM mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) + mimemagic (0.3.2) mina (0.3.8) open4 (~> 1.3.4) rake @@ -208,6 +217,9 @@ GEM mongoid-compatibility (0.4.0) activesupport mongoid (>= 2.0) + mongoid-paperclip (0.0.11) + mongoid + paperclip (>= 2.3.6, != 4.3.0) mongoid-paranoia (2.0.0) activesupport (~> 4.0) mongoid (>= 4.0.0, <= 6.0.0) @@ -218,6 +230,7 @@ GEM multi_json (1.12.1) multi_xml (0.5.5) multipart-post (2.0.0) + netrc (0.11.0) nokogiri (1.6.8) mini_portile2 (~> 2.1.0) pkg-config (~> 1.1.7) @@ -239,6 +252,12 @@ GEM open4 (1.3.4) origin (2.2.0) orm_adapter (0.5.0) + paperclip (5.1.0) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + cocaine (~> 0.5.5) + mime-types + mimemagic (~> 0.3.0) pkg-config (1.1.7) poltergeist (1.10.0) capybara (~> 2.1) @@ -252,7 +271,7 @@ GEM pry (>= 0.9.10, < 0.11.0) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) - rack (1.6.4) + rack (1.6.8) rack-protection (1.5.3) rack rack-test (0.6.3) @@ -305,6 +324,10 @@ GEM redis (>= 2.2) responders (2.2.0) railties (>= 4.2.0, < 5.1) + rest-client (2.0.2) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) rollbar (2.12.0) multi_json ruby_parser (3.8.2) @@ -348,6 +371,12 @@ GEM activesupport (>= 4.0) sprockets (>= 3.0.0) stringex (2.6.1) + stripe (1.58.0) + rest-client (>= 1.4, < 4.0) + stripe-ruby-mock (2.4.1) + dante (>= 0.2.0) + multi_json (~> 1.0) + stripe (>= 1.31.0, <= 1.58.0) thor (0.19.1) thread_safe (0.3.5) tilt (2.0.5) @@ -358,6 +387,9 @@ GEM thread_safe (~> 0.1) uglifier (3.0.1) execjs (>= 0.3.0, < 3) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.4) warden (1.2.6) rack (>= 1.0) web-console (2.3.0) @@ -410,6 +442,7 @@ DEPENDENCIES minitest-rails-capybara mocha mongoid (~> 5.0) + mongoid-paperclip mongoid-paranoia mongoid-slug (~> 5.2) omniauth-github (~> 1.1.2) @@ -428,6 +461,8 @@ DEPENDENCIES simple_form (~> 3.2.1) simplecov spring + stripe + stripe-ruby-mock (~> 2.4.1) timecop turbolinks (~> 2.5) uglifier (>= 1.3.0) diff --git a/app/assets/javascripts/sponsorer_details.coffee b/app/assets/javascripts/sponsorer_details.coffee new file mode 100644 index 00000000..3d17cf8d --- /dev/null +++ b/app/assets/javascripts/sponsorer_details.coffee @@ -0,0 +1,30 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ + +$(document).on "ready", -> + $('body').on 'change', '.sponsorer_detail_avatar', () -> + inputFile = $(this).val(); + validateFiles(inputFile); + if window.location.pathname == '/sponsorer_details' + showmodal(); + +showmodal = () -> + if modal == "true" + $("#rotate").click(); + +validateFiles = (inputFile) -> + extErrorMessage = 'Only image file with extension: .jpg, .jpeg, .gif or .png is allowed' + allowedExtension = [ + 'jpg' + 'jpeg' + 'gif' + 'png' + ] + extName = inputFile.split('.').pop() + extError = false + if $.inArray(extName, allowedExtension) == -1 + window.alert extErrorMessage + $(inputFile).val '' + $(this).val '' + return \ No newline at end of file diff --git a/app/assets/javascripts/stripe.coffee b/app/assets/javascripts/stripe.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/stripe.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 6b2fce7c..d82fc20e 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -31,3 +31,56 @@ .typeahead.dropdown-menu, .tt-hint, .tt-input, .tt-menu { width: 90%; } + +.sticky-container{ + padding:0px; + margin:0px; + position:fixed; + right:-105px; + top:60%; + width:200px; + z-index: 1100; +} + +.sticky li{ + list-style-type:none; + //background-color:#fff; + color:#808080; + height:43px; + padding:0px; + margin:0px 0px 1px 0px; + -webkit-transition:all 0.25s ease-in-out; + -moz-transition:all 0.25s ease-in-out; + -o-transition:all 0.25s ease-in-out; + transition:all 0.25s ease-in-out; + cursor:pointer; +} +.sticky li:hover{ + margin-left:-15px; +} +.sticky li span{ + float:left; +} +.sticky li p{ + padding-top:5px; + margin:0px; + line-height:16px; + //font-size:11px; +} + +.sticky li p a{ + text-decoration:none; + color:#fff; +} + +#rotate{ + vertical-align: top; + //margin-top: 30%; + //margin-right: 0px; + //float: right; + //width:80px;height: 30px; + transform:rotate(7deg); + -ms-transform:rotate(90deg); /* IE 9 */ + -moz-transform:rotate(90deg); /* Firefox */ + -webkit-transform:rotate(90deg); /* Safari and Chrome */ + -o-transform:rotate(90deg); /* Opera */} diff --git a/app/assets/stylesheets/sponsorer_details.scss b/app/assets/stylesheets/sponsorer_details.scss new file mode 100644 index 00000000..76871355 --- /dev/null +++ b/app/assets/stylesheets/sponsorer_details.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the SponsorerDetails controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/stripe.scss b/app/assets/stylesheets/stripe.scss new file mode 100644 index 00000000..f6262701 --- /dev/null +++ b/app/assets/stylesheets/stripe.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the stripe controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5ff29ace..373f0803 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -31,7 +31,7 @@ def select_goal return true if params[:controller] == 'goals' && params[:action] == 'index' return true if params[:action] == 'set_goal' || params[:controller] == 'devise/sessions' return true if current_user.is_admin? - + if current_user.goal.blank? redirect_to goals_path, notice: I18n.t('goal.please_select') end @@ -49,6 +49,12 @@ def authenticate_admin! end end + def authenticate_sponsor! + if current_user && !current_user.is_sponsorer? + redirect_back(notice: I18n.t('messages.unauthorized_access')) + end + end + def redirect_back(opts = {}) redirect_to(request.env['HTTP_REFERER'] || root_path, opts) end diff --git a/app/controllers/concerns/sponsorer_helper.rb b/app/controllers/concerns/sponsorer_helper.rb new file mode 100644 index 00000000..94fdd1ed --- /dev/null +++ b/app/controllers/concerns/sponsorer_helper.rb @@ -0,0 +1,13 @@ +module SponsorerHelper + def createStripeCustomer(email, token, plan) + Stripe::Customer.create( + :email => email, + :source => token, + :plan => plan + ) + end + + def delete_subscription(subscription_id) + Stripe::Subscription.retrieve(subscription_id).delete + end +end \ No newline at end of file diff --git a/app/controllers/sponsorer_details_controller.rb b/app/controllers/sponsorer_details_controller.rb new file mode 100644 index 00000000..be65ff18 --- /dev/null +++ b/app/controllers/sponsorer_details_controller.rb @@ -0,0 +1,86 @@ +class SponsorerDetailsController < ApplicationController + include SponsorerHelper + require "stripe" + # after_action :set_sponsorer, only: [:create] + before_action :authenticate_user! + # before_action :authenticate_sponsor!, except: [:new, :create] + skip_before_action :select_goal + before_action :load_sponsorer, only: [:update_card, :cancel_subscription] + + def index + @user = current_user + @sponsor = @user.sponsorer_detail + if @sponsor + @card = SponsorerDetail.get_credit_card(@sponsor.stripe_customer_id) + @payments = @sponsor.payments.page(params[:page]) + end + end + + def new + @sponsorer_detail = SponsorerDetail.new + end + + def create + @sponsorer = SponsorerDetail.new(sponsorer_params) + @sponsorer.user_id = current_user.id + if @sponsorer.valid? + begin + plan_id = @sponsorer.payment_plan+"-"+@sponsorer.sponsorer_type.downcase + + customer = createStripeCustomer(current_user.email, params[:stripeToken], plan_id) + + @sponsorer.stripe_customer_id = customer.id + + subscription = customer.subscriptions.data.first + @sponsorer.stripe_subscription_id = subscription.id + @sponsorer.subscribed_at = Time.at(subscription.created).to_datetime + @sponsorer.subscription_expires_at = Time.at(subscription.current_period_end).to_datetime + @sponsorer.subscription_status = subscription.status + rescue Stripe::StripeError => e + flash[:error] = e.message + else + if @sponsorer.save + SponsorMailer.notify_subscription_details(@sponsorer.user_id.to_s, @sponsorer.payment_plan, SPONSOR[@sponsorer.sponsorer_type.downcase][@sponsorer.payment_plan]).deliver_later + redirect_to sponsorer_details_path #sponsorer dashboard + flash[:notice] = "saved sponsorship details successfully" + end + end + else + flash[:error] = @sponsorer.errors.full_messages.join(',') + end + end + + def update_card + begin + customer = Stripe::Customer.retrieve(@sponsor.stripe_customer_id) + customer.source = params[:stripeToken] + rescue Stripe::StripeError => e + flash[:error] = e.message + else + customer.save + flash[:notice] = 'Your card has been updated successfully' + end + redirect_to sponsorer_details_path + end + + def cancel_subscription + begin + delete_subscription(@sponsor.stripe_subscription_id) + rescue Stripe::StripeError => e + flash[:error] = e.message + else + flash[:notice] = "Your subscription has been cancelled successfully" + end + redirect_to sponsorer_details_path + end + + private + + def sponsorer_params + params.require(:sponsorer_detail).permit! + end + + def load_sponsorer + @sponsor = SponsorerDetail.find_by(user_id: params[:id]) + end +end diff --git a/app/controllers/stripe_controller.rb b/app/controllers/stripe_controller.rb new file mode 100644 index 00000000..8be6861c --- /dev/null +++ b/app/controllers/stripe_controller.rb @@ -0,0 +1,70 @@ +class StripeController < ApplicationController + require "stripe" + protect_from_forgery :except => :webhooks + + def webhooks + begin + event_json = JSON.parse(request.body.read) + event_object = event_json['data']['object'] + subscriber = SponsorerDetail.find_by(stripe_customer_id: event_object['customer']) + #refer event types here https://stripe.com/docs/api#event_types + case event_json['type'] + when 'customer.subscription.created' + handle_subscription_created_event(subscriber, event_object) + when 'invoice.payment_succeeded' + handle_payment_succeded_event(subscriber, event_object) + when 'invoice.payment_failed' + handle_payment_failed_event(subscriber, event_object) + when 'customer.subscription.updated' + update_subscription_status(subscriber, event_object) + when 'customer.source.created' + handle_source_created_event(subscriber, event_object) + when 'customer.subscription.deleted' + update_subscription_status(subscriber, event_object) + end + rescue Exception => ex + render :json => {:status => 422, :error => "Webhook call failed"} + return + end + render :json => {:status => 200} + end + + def handle_subscription_created_event(subscriber, event_object) + subscriber.subscribed_at = Time.at(event_object['start']).to_datetime + subscriber.subscription_expires_at = Time.at(event_object['current_period_end']).to_datetime + subscriber.subscription_status = event_object['status'] + subscriber.save + end + + def handle_payment_succeded_event(subscriber, event_object) + #send a mail regarding successfull payment, update expiry date + subscriber.subscription_expires_at = Time.at(event_object['lines']['data'].first['period']['end']).to_datetime + plan = event_object['lines']['data'].first['plan']['name'] + subscriber.save_payment_details(plan, event_object['amount_due'], event_object['date']) + subscriber.save + end + + def handle_payment_failed_event(subscriber, event_object) + #send a mail regarding unsuccessfull payment + if event_object['attempt_count'] == 1 + charge = Stripe::Charge.retrieve(event_object['charge']) + message = charge.failure_message + user_id = SponsorerDetail.find_by(stripe_customer_id: event_object['customer']).user_id + SponsorMailer.subscription_payment_failed(user_id.to_s, message).deliver_later + end + end + + def handle_source_created_event(subscriber, event_object) + #reopen the latest invoice and pay + if subscriber.subscription_status == 'unpaid' + latest_invoice = Stripe::Invoice.list(:customer => subscriber.stripe_customer_id).data.first + invoice.update(closed: false) + invoice.pay + end + end + + def update_subscription_status(subscriber, event_object) + subscriber.subscription_status = event_object['status'] + subscriber.save + end +end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 81c8bd3f..6ff57ed0 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -4,6 +4,22 @@ class Users::OmniauthCallbacksController < ApplicationController def github @user = User.from_omniauth(request.env["omniauth.auth"]) + if request.env["omniauth.params"].present? && request.env["omniauth.params"]["user"] == "Sponsorer" + @role = Role.find_or_create_by(name: 'Sponsorer') + #fresh login of a non existing user as sponsorer + if @user.last_sign_in_at == nil + session[:sponsor] = true + else + #existing user + session[:sponsor] = true unless @user.is_sponsorer? #detects first time login as sponsorer + end + sign_in :user, @user + redirect_to sponsorer_details_path #redirect to fill sponsor details + flash[:notice] = "Signed in as sponsorer" + return + end + + #normal user sign in sign_in :user, @user if session[:group_invitation_url].present? diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 37210617..4c4bf653 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,5 +1,6 @@ class UsersController < ApplicationController include ContributionHelper + include SponsorerHelper before_action :authenticate_user!, except: [:show] def index @@ -63,6 +64,15 @@ def search def destroy user = current_user + if user.is_sponsorer && user.sponsorer_detail.subscription_status != 'canceled' + sponsor = user.sponsorer_detail + begin + delete_subscription(sponsor.stripe_subscription_id) + rescue + flash[:error] = "There was some problem while canceling your subscription. Please try after some time" + redirect_to user_path and return + end + end sign_out current_user # We cannot delete the user completely, because there are plenty of associations. diff --git a/app/helpers/sponsorer_details_helper.rb b/app/helpers/sponsorer_details_helper.rb new file mode 100644 index 00000000..122dceaf --- /dev/null +++ b/app/helpers/sponsorer_details_helper.rb @@ -0,0 +1,2 @@ +module SponsorerDetailsHelper +end diff --git a/app/helpers/stripe_helper.rb b/app/helpers/stripe_helper.rb new file mode 100644 index 00000000..be903036 --- /dev/null +++ b/app/helpers/stripe_helper.rb @@ -0,0 +1,2 @@ +module StripeHelper +end diff --git a/app/mailers/sponsor_mailer.rb b/app/mailers/sponsor_mailer.rb new file mode 100644 index 00000000..d5948ef9 --- /dev/null +++ b/app/mailers/sponsor_mailer.rb @@ -0,0 +1,14 @@ +class SponsorMailer < ApplicationMailer + def subscription_payment_failed(user, message) + @user = User.find(id: user) + @message = message + mail(to: @user.email, subject: "Payment to CodeCuriosity failed") + end + + def notify_subscription_details(user, plan, amount) + @user = User.find(id: user) + @plan = plan + @amount = amount + mail(to: @user.email, subject: "Details of subscription as sponsor to CodeCuriosity") + end +end diff --git a/app/models/payment.rb b/app/models/payment.rb new file mode 100644 index 00000000..e72ca140 --- /dev/null +++ b/app/models/payment.rb @@ -0,0 +1,12 @@ +class Payment + include Mongoid::Document + + field :subscription_plan, type: String + field :amount, type: Integer + field :date, type: DateTime + + belongs_to :sponsorer_detail + + validates :subscription_plan, :amount, :date, presence: true + validates :amount, numericality: { only_integer: true, greater_than: 0 } +end diff --git a/app/models/sponsorer_detail.rb b/app/models/sponsorer_detail.rb new file mode 100644 index 00000000..bb585efb --- /dev/null +++ b/app/models/sponsorer_detail.rb @@ -0,0 +1,54 @@ +class SponsorerDetail + include Mongoid::Document + include Mongoid::Paperclip + + field :sponsorer_type, type: String + field :payment_plan, type: String + field :publish_profile, type: Boolean, default: false + field :stripe_customer_id, type: String + field :stripe_subscription_id, type: String + field :subscribed_at, type: DateTime + field :subscription_expires_at, type: DateTime + field :subscription_status, type: String + + has_mongoid_attached_file :avatar, + path: ':rails_root/public/system/sponsorer/:id/:style/:filename', + url: '/system/sponsorer/:id/:style/:filename', + :styles => { :default => "300x300>"} + + belongs_to :user + has_many :payments + + validates :sponsorer_type, :user, :payment_plan, presence: true + validates :sponsorer_type, :inclusion => { :in => ['INDIVIDUAL','ORGANIZATION'] } + validates :payment_plan, :inclusion => { :in => SPONSOR['individual'].keys } + # validates :publish_profile, :inclusion => { :in => [true, false] } + # validate attachment presence + # validates_attachment_presence :avatar + # Validate filename + validates_attachment_file_name :avatar, matches: [/png\Z/, /jpe?g\Z/] + # Validate content type + validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/ + + after_create :update_user_as_sponsor + + def save_payment_details(plan, amount, date) + payment = self.payments.build(subscription_plan: plan, amount: amount/100, date: Time.at(date).to_datetime) + payment.save + end + + private + + def self.get_credit_card(customer_id) + customer = Stripe::Customer.retrieve(customer_id) + card = customer.sources.first + end + + def update_user_as_sponsor + @user = self.user + @role = Role.find_or_create_by(name: 'Sponsorer') + @user.roles << @role unless @user.is_sponsorer? + @user.set({is_sponsorer: true}) + end + +end diff --git a/app/models/user.rb b/app/models/user.rb index 9cbe6471..9ebcc1d0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -28,6 +28,7 @@ class User field :github_handle, type: String field :active, type: Boolean, default: true field :is_judge, type: Boolean, default: false + field :is_sponsorer, type: Boolean, default: false field :name, type: String field :provider, type: String field :uid, type: String @@ -66,7 +67,8 @@ class User has_and_belongs_to_many :judges_repositories, class_name: 'Repository', inverse_of: 'judges' has_and_belongs_to_many :roles, inverse_of: nil has_and_belongs_to_many :organizations - has_and_belongs_to_many :groups, class_name: 'Group', inverse_of: 'members' + has_and_belongs_to_many :groups, class_name: 'Group', inverse_of: 'members' + has_one :sponsorer_detail, dependent: :destroy slug :github_handle @@ -129,6 +131,10 @@ def is_admin? roles.where(name: ROLES[:admin]).any? end + def is_sponsorer? + roles.where(name: 'Sponsorer').any? + end + def repo_names judges_repositories.map(&:name).join(",") end diff --git a/app/views/application/_mail_signature.html.haml b/app/views/application/_mail_signature.html.haml new file mode 100644 index 00000000..0ab8a5c6 --- /dev/null +++ b/app/views/application/_mail_signature.html.haml @@ -0,0 +1,9 @@ +%div   +%div Keep those contributions coming! +%div - Team CodeCuriosity  +%div   +%div + %em "Open Source is now fun and rewarding!"   +%div + %em #CodeCuriosity +%div   \ No newline at end of file diff --git a/app/views/application/_sidebar.html.haml b/app/views/application/_sidebar.html.haml index ceda0df3..63decba1 100644 --- a/app/views/application/_sidebar.html.haml +++ b/app/views/application/_sidebar.html.haml @@ -16,6 +16,11 @@ %span Judging = render 'admin_sidebar' if current_user.is_admin? = render 'orgs_sidebar' if current_user.organizations.any? + - if current_user.is_sponsorer + %li + %a{href: sponsorer_details_path} + %i.fa.fa-gears + %span Sponsor %li{class: is_active(params[:action], 'goals')} = link_to goals_path do %i.fa.fa-trophy diff --git a/app/views/application/_sponsor.html.haml b/app/views/application/_sponsor.html.haml new file mode 100644 index 00000000..5b37cc3a --- /dev/null +++ b/app/views/application/_sponsor.html.haml @@ -0,0 +1,13 @@ +.sticky-container + %ul.sticky + %li + %p + - if user_signed_in? + = link_to("Sponsor", new_sponsorer_detail_path, class: "btn btn-lg btn-success", id: "rotate", :remote => true, 'data-toggle' => "modal", 'data-target' => '#modal-window') + - else + = link_to("Sponsor", omniauth_authorize_path(:user, :github, user: 'Sponsorer'), class: "btn btn-lg btn-success", id: "rotate") + +#modal-window.modal.fade{"aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex =>"-1"} +/ = link_to("Sponsor", user_signed_in? ? "#" : new_sponsorer_detail_path, class: "btn btn-lg btn-success", id: "rotate", :remote => true, 'data-toggle' => "modal", 'data-target' => '#modal-window') +/ %a#rotate{ href: user_signed_in? ? new_sponsorer_detail_path : omniauth_authorize_path(:user, :github, user: 'Sponsorer'), class: "btn btn-lg btn-success" } +/ Sponsor \ No newline at end of file diff --git a/app/views/group_invitation_mailer/invite.html.haml b/app/views/group_invitation_mailer/invite.html.haml index 4cd17629..02bbf3a9 100644 --- a/app/views/group_invitation_mailer/invite.html.haml +++ b/app/views/group_invitation_mailer/invite.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h3= "Hello #{@group_invitation.user.try(:github_handle) || @email}," %p diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index fd34b59a..fd27f4de 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -34,3 +34,4 @@ = render partial: 'featured_groups' .row = render partial: 'trend' += render 'sponsor' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index f80a5f87..9635ec99 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -24,3 +24,5 @@ - if flash.any? :javascript #{show_flash_notifications} + - unless current_user.is_sponsorer + = render 'sponsor' diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml index f1073291..cace5252 100644 --- a/app/views/layouts/mailer.html.haml +++ b/app/views/layouts/mailer.html.haml @@ -124,15 +124,7 @@ %table.module{:border => "0", :cellpadding => "0", :cellspacing => "0", "data-attributes" => "%7B%22dropped%22%3Atrue%2C%22child%22%3Afalse%2C%22padding%22%3A%2210%2C10%2C10%2C10%22%2C%22containerbackground%22%3A%22%23ffffff%22%7D", "data-type" => "text", :role => "module", :style => "table-layout: fixed;", :width => "100%"} %tr %td{:bgcolor => "#ffffff", :height => "100%", :role => "module-content", :style => "padding: 10px 10px 10px 10px;", :valign => "top"} - %div   - %div Keep those contributions coming! - %div - Team CodeCuriosity  - %div   - %div - %em "Open Source is now fun and rewarding!"   - %div - %em #CodeCuriosity - %div   + = yield :signature %table.wrapper{:align => "center", :border => "0", :cellpadding => "0", :cellspacing => "0", "data-attributes" => "%7B%22backgroundcolor%22%3A%22%23FFFFFF%22%2C%22iconsize%22%3A30%2C%22iconcolor%22%3A%22AUTO%22%2C%22borderradius%22%3A2%2C%22padding%22%3A%225%2C0%2C5%2C0%22%2C%22alignment%22%3A%22center%22%2C%22option_facebook%22%3A%7B%22checked%22%3Atrue%2C%22text%22%3A%22https%3A//www.facebook.com/joshsoftware%22%2C%22filename%22%3A%22facebook.png%22%2C%22title%22%3A%22Facebook%22%2C%22backgroundcolor%22%3A%22%233B579D%22%7D%2C%22option_twitter%22%3A%7B%22checked%22%3Atrue%2C%22text%22%3A%22https%3A//twitter.com/joshsoftware%22%2C%22filename%22%3A%22twitter.png%22%2C%22title%22%3A%22Twitter%22%2C%22backgroundcolor%22%3A%22%237AC4F7%22%7D%2C%22option_instagram%22%3A%7B%22checked%22%3Afalse%2C%22text%22%3A%22%22%2C%22filename%22%3A%22instagram.png%22%2C%22title%22%3A%22Instagram%22%2C%22backgroundcolor%22%3A%22%237F4B30%22%7D%2C%22option_googleplus%22%3A%7B%22checked%22%3Afalse%2C%22text%22%3A%22%22%2C%22filename%22%3A%22google-plus.png%22%2C%22title%22%3A%22Google+%22%2C%22backgroundcolor%22%3A%22%23D44132%22%7D%2C%22option_pinterest%22%3A%7B%22checked%22%3Afalse%2C%22text%22%3A%22%22%2C%22filename%22%3A%22pinterest.png%22%2C%22title%22%3A%22Pinterest%22%2C%22backgroundcolor%22%3A%22%23CB2027%22%7D%2C%22option_linkedin%22%3A%7B%22checked%22%3Atrue%2C%22text%22%3A%22https%3A//www.linkedin.com/company/josh-software-private-limited%22%2C%22filename%22%3A%22linkedin.png%22%2C%22backgroundcolor%22%3A%22%230077B5%22%7D%7D", "data-type" => "social", :role => "module", :style => "table-layout: fixed;", :width => "100%"} %tr %td{:align => "center", :role => "module-content", :style => "font-size:6px;line-height:10px;background-color:;padding: 5px 0px 5px 0px;", :valign => "top"} diff --git a/app/views/layouts/mailer.text.haml b/app/views/layouts/mailer.text.haml new file mode 100644 index 00000000..f1d0cc89 --- /dev/null +++ b/app/views/layouts/mailer.text.haml @@ -0,0 +1 @@ += yield \ No newline at end of file diff --git a/app/views/redeem_mailer/coupon_code.html.haml b/app/views/redeem_mailer/coupon_code.html.haml index 9488b3c9..f3ee9ed6 100644 --- a/app/views/redeem_mailer/coupon_code.html.haml +++ b/app/views/redeem_mailer/coupon_code.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h4= "Hello #{@user.name}," - if @redeem_request.coupon_code.present? %p= "Your coupon code is #{@redeem_request.coupon_code} for #{@redeem_request.retailer}" diff --git a/app/views/redeem_mailer/notify_admin.html.haml b/app/views/redeem_mailer/notify_admin.html.haml index 10224108..f173a57f 100644 --- a/app/views/redeem_mailer/notify_admin.html.haml +++ b/app/views/redeem_mailer/notify_admin.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h4 Hello Admin, %p = @redeem_request.points diff --git a/app/views/redeem_mailer/redeem_request.html.haml b/app/views/redeem_mailer/redeem_request.html.haml index a4a8962e..5689bdbf 100644 --- a/app/views/redeem_mailer/redeem_request.html.haml +++ b/app/views/redeem_mailer/redeem_request.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h4= "Hello #{@user.name}," %p Your redemption request has been received. We will process your request and send you a coupon code as soon as possible. diff --git a/app/views/sponsor_mailer/notify_subscription_details.html.haml b/app/views/sponsor_mailer/notify_subscription_details.html.haml new file mode 100644 index 00000000..ccc40fe2 --- /dev/null +++ b/app/views/sponsor_mailer/notify_subscription_details.html.haml @@ -0,0 +1,15 @@ +- content_for :signature do + %div + %div Keep Sponsoring! + %div - Team CodeCuriosity  + %div   + +%h4= "Hello, #{@user.name}" +%p + Thank you for sponsoring to CodeCuriosity!! +%p + We have received your first payment. +%p + You have subscribed for the + #{@plan} plan and will be charged + #{@amount}$/month. diff --git a/app/views/sponsor_mailer/subscription_payment_failed.html.haml b/app/views/sponsor_mailer/subscription_payment_failed.html.haml new file mode 100644 index 00000000..e71abcc3 --- /dev/null +++ b/app/views/sponsor_mailer/subscription_payment_failed.html.haml @@ -0,0 +1,13 @@ +- content_for :signature do + %div + %div Keep Sponsoring! + %div - Team CodeCuriosity  + %div   + +%h4= "Hello, #{@user.name}" +%p + Unfortunately your most recent invoice payment was declined with the following message: +%p + #{@message} +%p + Please update your payment information as soon as possible by logging in to our site. \ No newline at end of file diff --git a/app/views/sponsorer_details/_individual.html.haml b/app/views/sponsorer_details/_individual.html.haml new file mode 100644 index 00000000..4bd279e0 --- /dev/null +++ b/app/views/sponsorer_details/_individual.html.haml @@ -0,0 +1,15 @@ +/ %script{:src => "https://checkout.stripe.com/checkout.js", :type => "text/javascript", :key => "#{Rails.configuration.stripe[:publishable_key]}"} += form_for(@sponsorer || SponsorerDetail.new, :url => { :controller => "sponsorer_details", :action => 'create' }, :html => { :multipart => true }, remote: true, authenticity_token: true, format: :js ) do |f| + = f.hidden_field :sponsorer_type, value: 'INDIVIDUAL' + .form-group + = f.label :Upload_Profile_Photo + = f.file_field :avatar, accept: 'image/png,image/jpeg,image/jpg', class: 'sponsorer_detail_avatar' + .form-group + = f.check_box :publish_profile, checked_value: "1", unchecked_value: "0" + = f.label :publish_profile, "Allow to publish your profile photo as sponsor" + .form-group + = f.label :Payment_Plan_yearly_subscription + = f.select(:payment_plan, [[SPONSOR['individual'].keys[0]+"("+SPONSOR['individual'].values[0].to_s+"$/month)", SPONSOR['individual'].keys[0]],[SPONSOR['individual'].keys[1]+"("+SPONSOR['individual'].values[1].to_s+"$/month)", SPONSOR['individual'].keys[1]],[SPONSOR['individual'].keys[2]+"("+SPONSOR['individual'].values[2].to_s+"$/month)", SPONSOR['individual'].keys[2]]]) + .actions + %script.stripe-button{ src: "https://checkout.stripe.com/checkout.js", + data: {key: "#{Rails.configuration.stripe[:publishable_key]}", description: "One year subscription", email: current_user.email, image: "https://stripe.com/img/documentation/checkout/marketplace.png", label: "Subscribe"}} diff --git a/app/views/sponsorer_details/_new.html.haml b/app/views/sponsorer_details/_new.html.haml new file mode 100644 index 00000000..85bdd303 --- /dev/null +++ b/app/views/sponsorer_details/_new.html.haml @@ -0,0 +1,22 @@ +.modal-dialog#test + .modal-content + .modal-header + %button.close{"aria-hidden" => "true", "data-dismiss" => "modal", :type => "button"} × + %h3#myModalLabel New Sponsorer + .modal-body + %ul.errors + .nav-tabs-custom + %ul.nav.nav-tabs + %li.active + %a{href: '#individual', data: { toggle: 'tab'} } + %i.fa.fa-money + Individual + %li + %a{href: '#organization', data: { toggle: 'tab'} } + %i.fa.fa-money + Company + .tab-content + .tab-pane.active#individual + = render 'sponsorer_details/individual' + .tab-pane#organization + = render 'sponsorer_details/organization' \ No newline at end of file diff --git a/app/views/sponsorer_details/_organization.html.haml b/app/views/sponsorer_details/_organization.html.haml new file mode 100644 index 00000000..4e244ba2 --- /dev/null +++ b/app/views/sponsorer_details/_organization.html.haml @@ -0,0 +1,15 @@ +/ %script{:src => "https://checkout.stripe.com/checkout.js", :type => "text/javascript", :key => "#{Rails.configuration.stripe[:publishable_key]}"} += form_for(@sponsorer || SponsorerDetail.new, :url => { :controller => "sponsorer_details", :action => 'create' }, :html => { :multipart => true }, remote: true, authenticity_token: true, format: :js) do |f| + = f.hidden_field :sponsorer_type, value: 'ORGANIZATION' + .form-group + = f.label :Upload_Logo + = f.file_field :avatar, accept: 'image/png,image/jpeg,image/jpg', class: 'sponsorer_detail_avatar' + .form-group + = f.check_box :publish_profile, checked_value: "1", unchecked_value: "0" + = f.label :publish_profile, "Allow to publish your organization's logo as sponsor" + .form-group + = f.label :Payment_Plan_yearly_subscription + = f.select(:payment_plan, [[SPONSOR['organization'].keys[0]+"("+SPONSOR['organization'].values[0].to_s+"$/month)", SPONSOR['organization'].keys[0]],[SPONSOR['organization'].keys[1]+"("+SPONSOR['organization'].values[1].to_s+"$/month)", SPONSOR['organization'].keys[1]],[SPONSOR['organization'].keys[2]+"("+SPONSOR['organization'].values[2].to_s+"$/month)", SPONSOR['organization'].keys[2]]]) + .actions + %script.stripe-button{ src: "https://checkout.stripe.com/checkout.js", + data: {key: "#{Rails.configuration.stripe[:publishable_key]}", description: "One year subscription", email: current_user.email, image: "https://stripe.com/img/documentation/checkout/marketplace.png", label: "Subscribe"}} \ No newline at end of file diff --git a/app/views/sponsorer_details/_payment.html.haml b/app/views/sponsorer_details/_payment.html.haml new file mode 100644 index 00000000..3fe64008 --- /dev/null +++ b/app/views/sponsorer_details/_payment.html.haml @@ -0,0 +1,5 @@ +%tr{data: {payment: payment.id.to_s}} + %td= payment_counter + 1 + %td= payment.date.strftime("%d/%b/%Y") + %td= "$#{payment.amount}" + %td= payment.subscription_plan \ No newline at end of file diff --git a/app/views/sponsorer_details/_payments_table.html.haml b/app/views/sponsorer_details/_payments_table.html.haml new file mode 100644 index 00000000..4278b00c --- /dev/null +++ b/app/views/sponsorer_details/_payments_table.html.haml @@ -0,0 +1,11 @@ +%table.table.table-bordered + %thead + %tr + %th.col-xs-3 # + %th.col-xs-3 Date + %th.col-xs-3 Amount Paid + %th.col-xs-3 Plan + %tbody + = render partial: 'payment', collection: @payments +.pagination-container + = paginate @payments, remote: true \ No newline at end of file diff --git a/app/views/sponsorer_details/create.html.haml b/app/views/sponsorer_details/create.html.haml new file mode 100644 index 00000000..ac59a536 --- /dev/null +++ b/app/views/sponsorer_details/create.html.haml @@ -0,0 +1,8 @@ + +- if !@sponsorer.errors.blank? + #modal-window.modal.fade{"aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex =>"-1"} + = render partial: 'new' + +:javascript + $("#modal-window").modal('show') + \ No newline at end of file diff --git a/app/views/sponsorer_details/index.html.haml b/app/views/sponsorer_details/index.html.haml new file mode 100644 index 00000000..0e938e1c --- /dev/null +++ b/app/views/sponsorer_details/index.html.haml @@ -0,0 +1,81 @@ +%section.content-header + %h1 Welcome to sponsor for CodeCuriosity! +%section.content + .row + .col-sm-3 + .box.box-primary + .box-body.box-profile + = image_tag (current_user.sponsorer_detail && current_user.sponsorer_detail.avatar.present?) ? @sponsor.avatar : avatar_url(@user), class: 'profile-user-img img-responsive', alt: @user.name + %h3.profile-username.text-center= @user.name.titleize + %p.text-muted.text-center + = link_to github_url(@user), target: '_blank' do + %i.fa.fa-github + = @user.github_handle + .col-sm-9 + .nav-tabs-custom + %ul.nav.nav-tabs + %li#card_details_tab_link + = link_to 'Credit Card details', '#credit_card', data: { toggle: 'tab'} + %li#subscription_details_tab_link + = link_to 'Subscription Details', '#subscription', data: { toggle: 'tab'} + %li.active#payments_tab_link + = link_to 'Payment Details', '#payments', data: { toggle: 'tab'} + .tab-content + .tab-pane#credit_card + .well + - if @card.nil? + = "You have not added any credit card... please update your payment information!" + - else + %table.table + %tr + %th Card ending in: + %td= @card.last4 + %tr + %th Expiry Month: + %td= @card.exp_month + %tr + %th Expiry year: + %td= @card.exp_year + %tr + %td + = form_tag update_card_sponsorer_detail_path(current_user.id), method: 'post' do + %script.stripe-button{ src: "https://checkout.stripe.com/checkout.js", + 'data-key'=> "#{Rails.configuration.stripe[:publishable_key]}", + 'data-email' => current_user.email, + 'data-panel-label' => 'Change Card', + 'data-label' => 'Change Card', + 'data-name' => 'Change Card', + 'data-description' => 'Change your card', + 'data-billing-address' => 'false'} + .tab-pane#subscription + .well + - if @sponsor.nil? + = "You have not subscribed for any plan yet! Please subscribe by clicking on sponsor button and filling the form!" + - else + %table.table + %tr + %th Payment Plan: + %td= @sponsor.payment_plan + %tr + %th Subscribed at: + %td= @sponsor.subscribed_at.to_date.strftime("%d/%m/%y") + %tr + %th Subscription Amount: + %td= SPONSOR[@sponsor.sponsorer_type.downcase][@sponsor.payment_plan].to_s+"$/month" + %tr + %th Subscription Status: + %td= @sponsor.subscription_status + %tr + %td= link_to "Cancel Subscription", cancel_subscription_sponsorer_detail_path(current_user.id), class: 'btn btn-danger', data: { method: 'get', confirm: 'Are you sure to cancel the subscription?' } unless @sponsor.subscription_status == 'canceled' + .tab-pane.active#payments + - if @payments.present? && @payments.any? + = render 'payments_table' + - else + = render partial: 'callout_box', locals: { type: 'success', title: 'Keep Sponsoring', message: 'No payments yet'} + +:javascript + var sponser_flag = "#{session[:sponsor]}"; + if(sponser_flag) + window.modal = sponser_flag + else + window.modal = "false"; diff --git a/app/views/sponsorer_details/index.js.haml b/app/views/sponsorer_details/index.js.haml new file mode 100644 index 00000000..f0f215a1 --- /dev/null +++ b/app/views/sponsorer_details/index.js.haml @@ -0,0 +1 @@ +$('#payments').html("#{j render 'payments_table'}"); diff --git a/app/views/sponsorer_details/new.js.haml b/app/views/sponsorer_details/new.js.haml new file mode 100644 index 00000000..5cd74936 --- /dev/null +++ b/app/views/sponsorer_details/new.js.haml @@ -0,0 +1,2 @@ +$("#modal-window").html("#{escape_javascript(render 'sponsorer_details/new')}"); +$("#modal-window").modal('show') \ No newline at end of file diff --git a/app/views/subscription_mailer/progress.html.haml b/app/views/subscription_mailer/progress.html.haml index 4227dcb1..b4b43688 100644 --- a/app/views/subscription_mailer/progress.html.haml +++ b/app/views/subscription_mailer/progress.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h4= "Hello, #{@user.name}" %p Your goal for this month is diff --git a/app/views/subscription_mailer/redeem_points.html.haml b/app/views/subscription_mailer/redeem_points.html.haml index 2cf67085..90696474 100644 --- a/app/views/subscription_mailer/redeem_points.html.haml +++ b/app/views/subscription_mailer/redeem_points.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h4= "Hello #{@user.name}," %p = @message diff --git a/app/views/subscription_mailer/subscription_email.html.haml b/app/views/subscription_mailer/subscription_email.html.haml index a184b6f8..09ce0925 100644 --- a/app/views/subscription_mailer/subscription_email.html.haml +++ b/app/views/subscription_mailer/subscription_email.html.haml @@ -1,3 +1,6 @@ +- content_for :signature do + = render 'application/mail_signature' + %h5= "Hello #{@user.name}," =# url_for(host:"http://localhost:3000",controller: 'users', action: 'index', only_path: false) diff --git a/app/views/users/_sponsor_profile.html.haml b/app/views/users/_sponsor_profile.html.haml new file mode 100644 index 00000000..69df72ff --- /dev/null +++ b/app/views/users/_sponsor_profile.html.haml @@ -0,0 +1,13 @@ +.row + .col-md-4 + .table + .well + %tr + %td Payment Plan: + %td @plan[:name] + %tr + %td Subscribed at: + %td @plan[:subscribed_at] + %tr + %td Subscription Amount: + %td @plan[:amount] \ No newline at end of file diff --git a/config/code_curiosity_config.yml b/config/code_curiosity_config.yml index 526379c1..fab78a82 100644 --- a/config/code_curiosity_config.yml +++ b/config/code_curiosity_config.yml @@ -19,6 +19,16 @@ repository: user: :royalty_points_threshold: 50_000 +sponsor: + individual: + basic: 10 + intermediate: 15 + advanced: 20 + organization: + basic: 150 + intermediate: 200 + advanced: 300 + scoring_engine: :repositories: 'repositories' # repositories dir :max_score: 5 diff --git a/config/initializers/globals.rb b/config/initializers/globals.rb index 6507855c..ab2e51a0 100644 --- a/config/initializers/globals.rb +++ b/config/initializers/globals.rb @@ -10,6 +10,7 @@ SCORING_ENGINE_CONFIG = config['scoring_engine'] USER = config['user'] REDEEM = config['redeem'] + SPONSOR = config['sponsor'] end COMMIT_RATINGS = (0..5).to_a diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb new file mode 100644 index 00000000..12e69526 --- /dev/null +++ b/config/initializers/stripe.rb @@ -0,0 +1,6 @@ +Rails.configuration.stripe = { + :publishable_key => ENV['STRIPE_PUBLISHABLE_KEY'], + :secret_key => ENV['STRIPE_SECRET_KEY'] +} + +Stripe.api_key = Rails.configuration.stripe[:secret_key] \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index cfbd23b5..a6dbacdf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,15 @@ resources :repositories, only: [:index] + resources :sponsorer_details do + member do + post 'update_card' + get 'cancel_subscription' + end + end + + post "/stripe/webhooks", to: "stripe#webhooks" + resources :users, only: [:index, :show, :destroy] do member do get 'sync' diff --git a/test/controllers/sponsorer_details_controller_test.rb b/test/controllers/sponsorer_details_controller_test.rb new file mode 100644 index 00000000..dac0849b --- /dev/null +++ b/test/controllers/sponsorer_details_controller_test.rb @@ -0,0 +1,148 @@ +require "test_helper" +require "stripe_mock" + +class SponsorerDetailsControllerTest < ActionController::TestCase + + before(:all) do + round = create(:round, :status => 'open') + @user = create(:user, :auth_token => 'dah123rty') + StripeMock.start + end + + after(:all) do + StripeMock.stop + end + + test "should not render index to not-logged in user" do + get :index + assert_response :redirect + assert_redirected_to new_user_session_path + end + + # No need of this testcase + # test "should not render index to normal user" do + # @user.goal = create(:goal) + # sign_in @user + # get :index + # assert_response :redirect + # end + + test "should render index to logged-in user who is sponsor" do + @user.is_sponsorer = true + role = create(:role, name: 'Sponsorer') + @user.roles << role + @user.save + sign_in @user + get :index + assert_response :success + end + + test "should skip set goal for every action related to sponsor" do + + end + + test "should be compulsory to set goal if sponsor want to access pages other than sponsor" do + @user.is_sponsorer = true + role = create(:role, name: 'Sponsorer') + @user.roles << role + @user.save + sign_in @user + old_controller = @controller + @controller = DashboardController.new + get :index + assert_redirected_to goals_path + @controller = ActivitiesController.new + get :index + assert_redirected_to goals_path + @controller = old_controller + end + + test "creates a valid stripe customer with subscription" do + file = fixture_file_upload("#{Rails.root}/test/fixtures/rails.png", "image/png") + sign_in(@user) + + stripe_helper = StripeMock.create_test_helper + + plan = stripe_helper.create_plan(amount: 15000, name: 'basic', id: 'basic-organization', interval: 'month', currency: 'usd') + + assert_difference 'SponsorerDetail.count' do + post :create, sponsorer_detail: { sponsorer_type: "ORGANIZATION", avatar: file, publish_profile: "1", payment_plan: "basic" }, stripeToken: stripe_helper.generate_card_token(last4: '4242', exp_year: Time.now.year + 1), stripeEmail: @user.email + @sponsor = SponsorerDetail.all[-1] + assert_equal @sponsor.user.email, @user.email + assert_not_nil @sponsor.stripe_customer_id + assert_not_nil @sponsor.stripe_subscription_id + assert_not_nil @sponsor.subscribed_at + assert_not_nil @sponsor.subscription_expires_at + assert_not_nil @sponsor.subscription_status + end + end + + test "does not create subscription if form data is not valid" do + sign_in @user + stripe_helper = StripeMock.create_test_helper + + plan = stripe_helper.create_plan(amount: 15000, name: 'basic', id: 'basic-organization', interval: 'month', currency: 'usd') + + assert_difference 'SponsorerDetail.count', 0 do + post :create, sponsorer_detail: { sponsorer_type: "ORGANIZATION", avatar: nil, publish_profile: "1", payment_plan: "abc" }, stripeToken: stripe_helper.generate_card_token(last4: '4242', exp_year: Time.now.year + 1), stripeEmail: @user.email + end + assert_not_nil flash[:error] + end + + test "does not create sponsorer if error while creating stripe subscription" do + file = fixture_file_upload("#{Rails.root}/test/fixtures/rails.png", "image/png") + sign_in @user + stripe_helper = StripeMock.create_test_helper + + plan = stripe_helper.create_plan(amount: 15000, name: 'basic', id: 'basic-organization', interval: 'month', currency: 'usd') + + assert_difference 'SponsorerDetail.count', 0 do + post :create, sponsorer_detail: { sponsorer_type: "ORGANIZATION", avatar: file, publish_profile: "1", payment_plan: "basic" }, stripeToken: 'invalid_token1', stripeEmail: @user.email + end + assert_not_nil flash[:error] + end + + test "redirect to sponsorer dashboard on save" do + file = fixture_file_upload("#{Rails.root}/test/fixtures/rails.png", "image/png") + sign_in(@user) + stripe_helper = StripeMock.create_test_helper + + plan = stripe_helper.create_plan(amount: 15000, name: 'basic', id: 'basic-organization', interval: 'month', currency: 'usd') + + assert_difference 'SponsorerDetail.count' do + post :create, sponsorer_detail: { sponsorer_type: "ORGANIZATION", avatar: file, publish_profile: "1", payment_plan: "basic" }, stripeToken: stripe_helper.generate_card_token(last4: '4242', exp_year: Time.now.year + 1), stripeEmail: @user.email + end + assert_redirected_to sponsorer_details_path + assert_equal flash[:notice], 'saved sponsorship details successfully' + end + + test "should send a mail after sponsorer is successfully created" do + file = fixture_file_upload("#{Rails.root}/test/fixtures/rails.png", "image/png") + sign_in(@user) + stripe_helper = StripeMock.create_test_helper + + plan = stripe_helper.create_plan(amount: 15000, name: 'basic', id: 'basic-organization', interval: 'month', currency: 'usd') + + assert_enqueued_jobs 1 do + post :create, sponsorer_detail: { sponsorer_type: "ORGANIZATION", avatar: file, publish_profile: "1", payment_plan: "basic" }, stripeToken: stripe_helper.generate_card_token(last4: '4242', exp_year: Time.now.year + 1), stripeEmail: @user.email + end + end + + test 'email is delivered with expected content' do + file = fixture_file_upload("#{Rails.root}/test/fixtures/rails.png", "image/png") + sign_in(@user) + stripe_helper = StripeMock.create_test_helper + + plan = stripe_helper.create_plan(amount: 15000, name: 'basic', id: 'basic-organization', interval: 'month', currency: 'usd') + + perform_enqueued_jobs do + post :create, sponsorer_detail: { sponsorer_type: "ORGANIZATION", avatar: file, publish_profile: "1", payment_plan: "basic" }, stripeToken: stripe_helper.generate_card_token(last4: '4242', exp_year: Time.now.year + 1), stripeEmail: @user.email + + delivered_mail = ActionMailer::Base.deliveries.last + assert_equal delivered_mail.to, [@user.email] + assert_equal delivered_mail.subject, 'Details of subscription as sponsor to CodeCuriosity' + end + end + + #test case for handling unsuccessful form submit +end diff --git a/test/controllers/stripe_controller_test.rb b/test/controllers/stripe_controller_test.rb new file mode 100644 index 00000000..d89c42b2 --- /dev/null +++ b/test/controllers/stripe_controller_test.rb @@ -0,0 +1,43 @@ +require "test_helper" +require "stripe_mock" + +class StripeControllerTest < ActionController::TestCase + + def stripe_helper + StripeMock.create_test_helper + end + + def setup + StripeMock.start + @sponsorer = create(:sponsorer_detail) + end + + def teardown + StripeMock.stop + end + + test "should update the subscription details when subscription is created" do + skip("test case yet to be completed") + end + + test "should update subscription expiry date with new billing period end on payment success" do + skip("test case yet to be completed") + end + + test "should notify sponsor if payment fails for first attempt" do + skip("test case yet to be completed") + end + + test "should deliver mail with proper content on payment failure" do + skip("test case yet to be completed") + end + + # if payment fails for 3 attempts subscription shuld go in unpaid state + test "should update subscription status when subscription updated event occurs" do + skip("test case yet to be completed") + end + + test "should reactivate the subscription when sponsor updates credit card details" do + skip("test case yet to be completed") + end +end diff --git a/test/controllers/users/omniauth_callbacks_controller_test.rb b/test/controllers/users/omniauth_callbacks_controller_test.rb index dbb27d85..44ee19d4 100644 --- a/test/controllers/users/omniauth_callbacks_controller_test.rb +++ b/test/controllers/users/omniauth_callbacks_controller_test.rb @@ -29,9 +29,11 @@ class Users::OmniauthCallbacksControllerTest < ActionController::TestCase OmniAuth.config.add_mock(:github, omniauth_hash) + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:github] + round = create(:round, status: 'open') - + get :github @user = assigns(:user) @@ -45,5 +47,56 @@ class Users::OmniauthCallbacksControllerTest < ActionController::TestCase assert_response :redirect end + test "sponsorer github signup" do + OmniAuth.config.test_mode = true + date = Date.new(2015, 10, 10) + omniauth_hash = { + :provider => 'github', + :uid => '12345', + :info => { + :name => 'test user', + :email => 'test@test.com' + }, + :extra => { + :raw_info => + { + :login => 'hello', + :created_at => date + } + }, + :credentials => { + :token => 'github_omiauth_test' + }, + :user_params => { + :user => 'Sponsorer' + } + } + + OmniAuth.config.add_mock(:github, omniauth_hash) + + request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:github] + request.env['omniauth.params'] = OmniAuth.config.mock_auth[:github][:user_params] + + round = create(:round, status: 'open') + + get :github + + @user = assigns(:user) + + assert @user.valid? + assert_response :redirect + assert_redirected_to sponsorer_details_path + end + + test "existing user sign in as sponsorer" do + # round = create(:round, :status => 'open') + # @user = create(:user, :auth_token => 'dah123rty', goal: create(:goal)) + # @user.last_sign_in_at = Time.zone.now + end + + test "second time login of sponsorer" do + + end + end diff --git a/test/factories/payments.rb b/test/factories/payments.rb new file mode 100644 index 00000000..f3966764 --- /dev/null +++ b/test/factories/payments.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :payment do + + end +end diff --git a/test/factories/sponsorer_details.rb b/test/factories/sponsorer_details.rb new file mode 100644 index 00000000..06a57f6d --- /dev/null +++ b/test/factories/sponsorer_details.rb @@ -0,0 +1,21 @@ +FactoryGirl.define do + factory :sponsorer_detail do + sponsorer_type { "INDIVIDUAL" } + payment_plan { "basic" } + publish_profile { Faker::Boolean.boolean } + avatar { File.new(Rails.root.join('app', 'assets', 'images', 'logo_50pxh.png')) } + association :user + + after(:build) do |sponsor| + helper = StripeMock.create_test_helper + plan = helper.create_plan(amount: 1000, name: 'basic', id: 'basic-individual', interval: 'month', currency: 'usd') + token = helper.generate_card_token(last4: "4242") + customer = Stripe::Customer.create(email: sponsor.user.email, plan: 'basic-individual', source: token) + sponsor.stripe_customer_id = customer.id + sponsor.stripe_subscription_id = customer.subscriptions.data.first.id + sponsor.subscribed_at = Time.at(customer.subscriptions.data.first.created).to_datetime + sponsor.subscription_expires_at = Time.at(customer.subscriptions.data.first.current_period_end).to_datetime + sponsor.subscription_status = customer.subscriptions.data.first.status + end + end +end diff --git a/test/fixtures/rails.png b/test/fixtures/rails.png new file mode 100644 index 0000000000000000000000000000000000000000..b8f16cb7cc7a1fdcf32e1c6e63245e23e04350cb GIT binary patch literal 13729 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 M=$fM6>tJL5A3?9kfdBvi literal 0 HcmV?d00001 diff --git a/test/fixtures/test.csv b/test/fixtures/test.csv new file mode 100644 index 00000000..2d3333d5 --- /dev/null +++ b/test/fixtures/test.csv @@ -0,0 +1,4 @@ +user1, 9988754515, user1@gmail.com +user2, 9856451245, user2@gmail.com +user3, 9565451252, user3@gmail.com +user4, 9754251563, user4@gmail.com diff --git a/test/helpers/sponsorer_details_helper_test.rb b/test/helpers/sponsorer_details_helper_test.rb new file mode 100644 index 00000000..9f9d8be0 --- /dev/null +++ b/test/helpers/sponsorer_details_helper_test.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class SponsorerDetailsHelperTest < ActionView::TestCase + +end diff --git a/test/helpers/stripe_helper_test.rb b/test/helpers/stripe_helper_test.rb new file mode 100644 index 00000000..0466d6ad --- /dev/null +++ b/test/helpers/stripe_helper_test.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class StripeHelperTest < ActionView::TestCase + +end diff --git a/test/mailers/previews/sponsor_mailer_preview.rb b/test/mailers/previews/sponsor_mailer_preview.rb new file mode 100644 index 00000000..d0a79ebd --- /dev/null +++ b/test/mailers/previews/sponsor_mailer_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/sponsor_mailer +class SponsorMailerPreview < ActionMailer::Preview + +end diff --git a/test/mailers/sponsor_mailer_test.rb b/test/mailers/sponsor_mailer_test.rb new file mode 100644 index 00000000..54f13bbd --- /dev/null +++ b/test/mailers/sponsor_mailer_test.rb @@ -0,0 +1,4 @@ +require "test_helper" + +class SponsorMailerTest < ActionMailer::TestCase +end diff --git a/test/models/payment_test.rb b/test/models/payment_test.rb new file mode 100644 index 00000000..f4154b2c --- /dev/null +++ b/test/models/payment_test.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class PaymentTest < ActiveSupport::TestCase + +end diff --git a/test/models/sponsorer_detail_test.rb b/test/models/sponsorer_detail_test.rb new file mode 100644 index 00000000..74e66808 --- /dev/null +++ b/test/models/sponsorer_detail_test.rb @@ -0,0 +1,78 @@ +require "test_helper" +require 'stripe_mock' + +class SponsorerDetailTest < ActiveSupport::TestCase + + def stripe_helper + StripeMock.create_test_helper + end + + def setup + StripeMock.start + end + + def teardown + StripeMock.stop + end + + test "sponsorer type must be present in sponsorer_detail" do + sponsorer_detail = build(:sponsorer_detail, :sponsorer_type => nil) + sponsorer_detail.valid? + assert sponsorer_detail.errors[:sponsorer_type].include?("can't be blank") + end + + test "sponsorer type should be either INDIVIDUAL or ORGANIZATION" do + sponsorer_detail = build(:sponsorer_detail, :sponsorer_type => "individual") + sponsorer_detail.valid? + assert sponsorer_detail.errors[:sponsorer_type].include?("is not included in the list") + end + + test "payment plan must be present" do + sponsorer_detail = build(:sponsorer_detail, :payment_plan => nil) + sponsorer_detail.valid? + assert sponsorer_detail.errors[:payment_plan].include?("can't be blank") + end + + # test "publish profile flag must be boolean" do + # sponsorer_detail = build(:sponsorer_detail, :publish_profile => "string") + # sponsorer_detail.valid? + # binding.pry + # assert sponsorer_detail.errors[:publish_profile].include?("is not included in the list") + # end + + test "sponsorer_detail must belong to user" do + sponsorer_detail = build(:sponsorer_detail) + sponsorer_detail.user = nil + sponsorer_detail.valid? + assert sponsorer_detail.errors[:user].include?("can't be blank") + end + + test "profile photo or organization logo is not compulsory" do + sponsorer_detail = build(:sponsorer_detail, :avatar => nil) + sponsorer_detail.valid? + assert sponsorer_detail.errors[:avatar].blank? + end + + test "user should upload only image as profile photo" do + sponsorer_detail = build(:sponsorer_detail, :avatar => + File.new(Rails.root.join('test', 'fixtures', 'test.csv'))) + sponsorer_detail.valid? + assert sponsorer_detail.errors[:avatar_content_type].include?("is invalid") + assert sponsorer_detail.errors[:avatar_file_name].include?("is invalid") + assert sponsorer_detail.errors[:avatar].include?("is invalid") + end + + test "user must be updated as sponsorer after creating sponsorer details" do + sponsorer_detail = create(:sponsorer_detail) + user = sponsorer_detail.user + assert user.is_sponsorer + assert user.roles.where(name: 'Sponsorer').any? + end + + test "must save a new sponsorer with all params" do + assert_difference 'SponsorerDetail.count' do + sponsorer = create(:sponsorer_detail) + end + end + +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 0ad7ff9e..05507277 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -46,6 +46,10 @@ class UserTest < ActiveSupport::TestCase assert user.able_to_redeem? end + test "sponsor should have one sponsorer_detail" do + + end + def omniauthentication @date = Date.new(2015, 10, 10) OmniAuth.config.test_mode = true diff --git a/test/test_helper.rb b/test/test_helper.rb index fdcc8c8d..433c5577 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -25,6 +25,7 @@ class ActionController::TestCase include Devise::TestHelpers include Warden::Test::Helpers + include ActiveJob::TestHelper WebMock.disable_net_connect!(allow: "codeclimate.com") def stub_get(path, endpoint = Github.endpoint.to_s) From d540e477f835207e8763239c3defec74c952294b Mon Sep 17 00:00:00 2001 From: amitk Date: Mon, 17 Jul 2017 10:39:18 +0530 Subject: [PATCH 04/11] test written for redeem request helper method --- .rake_tasks~ | 58 +++++++++++++++++++ .../admin/redeem_requests_helper_test.rb | 16 +++++ test/models/redeem_request_test.rb | 1 + 3 files changed, 75 insertions(+) create mode 100644 .rake_tasks~ diff --git a/.rake_tasks~ b/.rake_tasks~ new file mode 100644 index 00000000..0d796a73 --- /dev/null +++ b/.rake_tasks~ @@ -0,0 +1,58 @@ +about +assets:clean[keep] +assets:clobber +assets:environment +assets:precompile +auto_score[round] +cache_digests:dependencies +cache_digests:nested_dependencies +db:drop +db:mongoid:create_indexes +db:mongoid:drop +db:mongoid:purge +db:mongoid:remove_indexes +db:mongoid:remove_undefined_indexes +db:purge +db:reset +db:seed +db:setup +doc:app +fetch_data:all_rounds +fetch_data:commits_and_activities[type] +fetch_data:github_user_since +fetch_data:sync_repos +log:clear +middleware +mongoid_slug:set +notes +notes:custom +paperclip:clean +paperclip:find_broken_attachments +paperclip:refresh +paperclip:refresh:metadata +paperclip:refresh:missing_styles +paperclip:refresh:thumbnails +rails:template +rails:update +repo:delete_large_repositories +rollbar:test +round:next +round:update_scores[round] +routes +secret +stats +subscription:redeem_points +subscription:send_email +subscription:send_progress_emails +test +test:all +test:all:db +test:db +time:zones:all +tmp:clear +tmp:create +utils:hackathon[group] +utils:remove_dublicate_repos +utils:restore_repositories +utils:update_user_redemed_points +utils:update_user_total_points diff --git a/test/helpers/admin/redeem_requests_helper_test.rb b/test/helpers/admin/redeem_requests_helper_test.rb index 13db0bcb..ab958744 100644 --- a/test/helpers/admin/redeem_requests_helper_test.rb +++ b/test/helpers/admin/redeem_requests_helper_test.rb @@ -1,4 +1,20 @@ require "test_helper" class Admin::RedeemRequestsHelperTest < ActionView::TestCase + + test "check worth of points" do + create_user + redeem_request = create(:redeem_request,:points => 10, user: @user) + assert_equal redeem_request.points/10, total_capital_of_points + assert_kind_of Fixnum, total_capital_of_points, "Must be a value" + end + + def create_user + round = create(:round, :status => 'open') + role = create(:role, :name => 'Admin') + @user = create(:user, goal: create(:goal)) + @user.roles << role + transaction = create(:transaction, :type => 'credit', :points => 120, user: @user) + end + end diff --git a/test/models/redeem_request_test.rb b/test/models/redeem_request_test.rb index 90bfd398..b10d05be 100644 --- a/test/models/redeem_request_test.rb +++ b/test/models/redeem_request_test.rb @@ -5,6 +5,7 @@ class RedeemRequestTest < ActiveSupport::TestCase def redeem_request @redeem_request ||= build(:redeem_request) + binding.pry end test "validity of redeem_request" do From c138023a99b99e50e96a0c190acd30836d3c0eab Mon Sep 17 00:00:00 2001 From: amitk Date: Mon, 17 Jul 2017 19:01:32 +0530 Subject: [PATCH 05/11] new field status is added to csv file download --- app/controllers/admin/redeem_requests_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/redeem_requests_controller.rb b/app/controllers/admin/redeem_requests_controller.rb index b104b9af..009943b2 100644 --- a/app/controllers/admin/redeem_requests_controller.rb +++ b/app/controllers/admin/redeem_requests_controller.rb @@ -32,14 +32,14 @@ def destroy def download csv_string = CSV.generate do |csv| - csv << ["user","Gift Shop", "Store","Points","cost","Date","coupon Code","Address"] + csv << ["User","Gift Shop", "Store","Points","Cost","Date","Coupon Code","Address","Status"] @redeem_requests.each do |redeem_request| - csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at.strftime(fmt='%F %T'),redeem_request.coupon_code,redeem_request.address] + csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at.strftime(fmt='%F %T'),redeem_request.coupon_code,redeem_request.address,redeem_request.status] end end send_data csv_string, - :type => 'text/csv; header=present;', - :disposition => "filename=requests.csv" + :type => 'text/csv; header = present;', + :disposition => "filename = requests.csv" end private From 1b9c880d1c12ed213a02ed02f287cc209da95728 Mon Sep 17 00:00:00 2001 From: amitk Date: Mon, 17 Jul 2017 19:01:45 +0530 Subject: [PATCH 06/11] Test cases written for csv file download --- .../admin/redeem_requests_controller_test.rb | 39 ++++++++++++++++++- .../admin/redeem_requests_helper_test.rb | 10 ++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/test/controllers/admin/redeem_requests_controller_test.rb b/test/controllers/admin/redeem_requests_controller_test.rb index fcb8cb1e..6d51c7e2 100644 --- a/test/controllers/admin/redeem_requests_controller_test.rb +++ b/test/controllers/admin/redeem_requests_controller_test.rb @@ -80,7 +80,44 @@ class Admin::RedeemRequestsControllerTest < ActionController::TestCase assert_not_nil assigns(:status) assert_equal redeem_request.count, 3 end - + + test "should generate a csv file" do + seed_data + redeem_request = create(:redeem_request, :points => 100, user: @user) + get :download, params: { :status => "false" } + assert_response :success + assert_equal "text/csv; header = present;", response.content_type + get :download, params: { :status => "true" } + assert_response :success + assert_equal "text/csv; header = present;", response.content_type + end + + test "check header of csv file" do + seed_data + redeem_request = create(:redeem_request, :points => 100, user: @user) + get :download, params: { :status => "false" } || { :status => "true" } + assert_response :success + attr = "User,Gift Shop,Store,Points,Cost,Date,Coupon Code,Address,Status".split(',') + csv = CSV.parse response.body + assert_equal csv[0],attr + end + + test "check fields of csv file" do + seed_data + gift_shop = ["github","amazon","other"] + store = [nil,"amazon.com","amazon.in","amazon.uk"] + status = ["false","true"] + redeem_request = create(:redeem_request, :points => 100, user: @user) + get :download, params: { :status => "false" } || {:status => "true"} + assert_response :success + csv = CSV.parse response.body + assert_includes gift_shop, csv[1][1] + assert_includes store, csv[1][2] + assert_kind_of Fixnum, csv[1][3].to_i + assert_not_equal csv[1][3].to_i, csv[1][4].to_i + assert_includes status, csv[1][8] + end + def seed_data round = create(:round, :status => 'open') role = create(:role, :name => 'Admin') diff --git a/test/helpers/admin/redeem_requests_helper_test.rb b/test/helpers/admin/redeem_requests_helper_test.rb index ab958744..a4b2894f 100644 --- a/test/helpers/admin/redeem_requests_helper_test.rb +++ b/test/helpers/admin/redeem_requests_helper_test.rb @@ -3,13 +3,13 @@ class Admin::RedeemRequestsHelperTest < ActionView::TestCase test "check worth of points" do - create_user - redeem_request = create(:redeem_request,:points => 10, user: @user) - assert_equal redeem_request.points/10, total_capital_of_points - assert_kind_of Fixnum, total_capital_of_points, "Must be a value" + seed_data + redeem_request = create(:redeem_request,:points => 100, user: @user) + total_capital = redeem_request.points/10 + assert_equal total_capital, total_capital_of_points end - def create_user + def seed_data round = create(:round, :status => 'open') role = create(:role, :name => 'Admin') @user = create(:user, goal: create(:goal)) From 8a322069349a073015af9fe5494d30817233e143 Mon Sep 17 00:00:00 2001 From: amitk Date: Thu, 20 Jul 2017 14:42:57 +0530 Subject: [PATCH 07/11] unwanted files removed[#296] --- .rake_tasks~ | 58 ------------------------------ test/models/redeem_request_test.rb | 1 - 2 files changed, 59 deletions(-) delete mode 100644 .rake_tasks~ diff --git a/.rake_tasks~ b/.rake_tasks~ deleted file mode 100644 index 0d796a73..00000000 --- a/.rake_tasks~ +++ /dev/null @@ -1,58 +0,0 @@ -about -assets:clean[keep] -assets:clobber -assets:environment -assets:precompile -auto_score[round] -cache_digests:dependencies -cache_digests:nested_dependencies -db:drop -db:mongoid:create_indexes -db:mongoid:drop -db:mongoid:purge -db:mongoid:remove_indexes -db:mongoid:remove_undefined_indexes -db:purge -db:reset -db:seed -db:setup -doc:app -fetch_data:all_rounds -fetch_data:commits_and_activities[type] -fetch_data:github_user_since -fetch_data:sync_repos -log:clear -middleware -mongoid_slug:set -notes -notes:custom -paperclip:clean -paperclip:find_broken_attachments -paperclip:refresh -paperclip:refresh:metadata -paperclip:refresh:missing_styles -paperclip:refresh:thumbnails -rails:template -rails:update -repo:delete_large_repositories -rollbar:test -round:next -round:update_scores[round] -routes -secret -stats -subscription:redeem_points -subscription:send_email -subscription:send_progress_emails -test -test:all -test:all:db -test:db -time:zones:all -tmp:clear -tmp:create -utils:hackathon[group] -utils:remove_dublicate_repos -utils:restore_repositories -utils:update_user_redemed_points -utils:update_user_total_points diff --git a/test/models/redeem_request_test.rb b/test/models/redeem_request_test.rb index b10d05be..90bfd398 100644 --- a/test/models/redeem_request_test.rb +++ b/test/models/redeem_request_test.rb @@ -5,7 +5,6 @@ class RedeemRequestTest < ActiveSupport::TestCase def redeem_request @redeem_request ||= build(:redeem_request) - binding.pry end test "validity of redeem_request" do From f70c9c6d073ec5c04fbabec1f8454020eaf7cbe4 Mon Sep 17 00:00:00 2001 From: amitk Date: Thu, 20 Jul 2017 14:47:14 +0530 Subject: [PATCH 08/11] Modifications are done as per conventional syntax and removed unwanted block of code --- app/assets/stylesheets/admin/redeem_requests.scss | 2 +- app/controllers/admin/redeem_requests_controller.rb | 6 ++---- app/helpers/admin/repositories_helper.rb | 6 ++++++ app/views/admin/redeem_requests/index.html.haml | 8 +++++--- config/routes.rb | 2 +- test/helpers/admin/repositories_helper_test.rb | 13 +++++++++++++ 6 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 app/helpers/admin/repositories_helper.rb create mode 100644 test/helpers/admin/repositories_helper_test.rb diff --git a/app/assets/stylesheets/admin/redeem_requests.scss b/app/assets/stylesheets/admin/redeem_requests.scss index a3e8e012..7c07fa71 100644 --- a/app/assets/stylesheets/admin/redeem_requests.scss +++ b/app/assets/stylesheets/admin/redeem_requests.scss @@ -5,6 +5,6 @@ float: right; } -.btn-group{ +.btn.btn-primary.glyphicon.glyphicon-download{ float: right; } \ No newline at end of file diff --git a/app/controllers/admin/redeem_requests_controller.rb b/app/controllers/admin/redeem_requests_controller.rb index 009943b2..250069cb 100644 --- a/app/controllers/admin/redeem_requests_controller.rb +++ b/app/controllers/admin/redeem_requests_controller.rb @@ -32,14 +32,12 @@ def destroy def download csv_string = CSV.generate do |csv| - csv << ["User","Gift Shop", "Store","Points","Cost","Date","Coupon Code","Address","Status"] + csv << ["User", "Gift Shop", "Store", "Points", "Cost", "Date", "Coupon Code", "Address", "Status"] @redeem_requests.each do |redeem_request| csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at.strftime(fmt='%F %T'),redeem_request.coupon_code,redeem_request.address,redeem_request.status] end end - send_data csv_string, - :type => 'text/csv; header = present;', - :disposition => "filename = requests.csv" + send_data csv_string, type: 'text/csv; header = present;', disposition: "filename = requests.csv" end private diff --git a/app/helpers/admin/repositories_helper.rb b/app/helpers/admin/repositories_helper.rb new file mode 100644 index 00000000..880d897f --- /dev/null +++ b/app/helpers/admin/repositories_helper.rb @@ -0,0 +1,6 @@ +module Admin::RepositoriesHelper + + def check_boolean(str) + str == "true" + end +end diff --git a/app/views/admin/redeem_requests/index.html.haml b/app/views/admin/redeem_requests/index.html.haml index 7a97026e..31838a04 100644 --- a/app/views/admin/redeem_requests/index.html.haml +++ b/app/views/admin/redeem_requests/index.html.haml @@ -5,9 +5,11 @@ %label.slide %input.check#redeem{checked: 'checked', name: 'status', type: 'checkbox', data: {toggle: 'toggle', width: '100', height: '40', on: 'Status Open', off: 'Status Close'}} #console-event - .btn-group - %a.btn.btn-primary.glyphicon.glyphicon-download{:href => download_admin_redeem_requests_path(:status => "false")} Active - %a.btn.btn-primary.glyphicon.glyphicon-download{:href => download_admin_redeem_requests_path(:status => "true") } Completed + = link_to download_admin_redeem_requests_path(:status => "true"), class: "btn btn-primary glyphicon glyphicon-download" do + %b Completed + = link_to download_admin_redeem_requests_path(:status => "false"), class: "btn btn-primary glyphicon glyphicon-download" do + %b Active + %section.content .row .col-xs-12 diff --git a/config/routes.rb b/config/routes.rb index a6dbacdf..9e89771b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -62,7 +62,7 @@ resources :redeem_requests, only: [:index, :update, :destroy] do collection do - get 'download' + get :download end end diff --git a/test/helpers/admin/repositories_helper_test.rb b/test/helpers/admin/repositories_helper_test.rb new file mode 100644 index 00000000..d7a97452 --- /dev/null +++ b/test/helpers/admin/repositories_helper_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +class Admin::RepositoriesHelperTest < ActionView::TestCase + + test "should return true of string true and vice versa" do + assert_equal check_boolean("true"), true + assert_equal check_boolean("false"), false + end + + def test_sanity + flunk "Need real tests" + end +end From 204c2044d668629e9a9a3004c9e12ec8fbc430c9 Mon Sep 17 00:00:00 2001 From: amitk Date: Thu, 20 Jul 2017 19:13:39 +0530 Subject: [PATCH 09/11] Updated files as per comments --- .../admin/redeem_requests_controller.rb | 9 +++-- app/helpers/admin/repositories_helper.rb | 6 ---- .../admin/redeem_requests_controller_test.rb | 34 ++++++++++++++++--- .../helpers/admin/repositories_helper_test.rb | 13 ------- 4 files changed, 36 insertions(+), 26 deletions(-) delete mode 100644 app/helpers/admin/repositories_helper.rb delete mode 100644 test/helpers/admin/repositories_helper_test.rb diff --git a/app/controllers/admin/redeem_requests_controller.rb b/app/controllers/admin/redeem_requests_controller.rb index 250069cb..00f09a41 100644 --- a/app/controllers/admin/redeem_requests_controller.rb +++ b/app/controllers/admin/redeem_requests_controller.rb @@ -34,7 +34,10 @@ def download csv_string = CSV.generate do |csv| csv << ["User", "Gift Shop", "Store", "Points", "Cost", "Date", "Coupon Code", "Address", "Status"] @redeem_requests.each do |redeem_request| - csv << [redeem_request.user.email,redeem_request.retailer,redeem_request.store,redeem_request.points,redeem_request.points/10,redeem_request.updated_at.strftime(fmt='%F %T'),redeem_request.coupon_code,redeem_request.address,redeem_request.status] + csv << [redeem_request.user.email, redeem_request.retailer, redeem_request.store, + redeem_request.points, redeem_request.points/10, + redeem_request.updated_at.strftime(fmt='%F %T'), redeem_request.coupon_code, + redeem_request.address, redeem_request.status] end end send_data csv_string, type: 'text/csv; header = present;', disposition: "filename = requests.csv" @@ -47,8 +50,8 @@ def redeem_params end def load_redeem_request - @status = params[:status] ? params[:status] : false - @redeem_requests = RedeemRequest.where(:status => @status).desc(:created_at) + @status = params[:status] || false + @redeem_requests = RedeemRequest.where(status: @status).desc(:created_at) end end diff --git a/app/helpers/admin/repositories_helper.rb b/app/helpers/admin/repositories_helper.rb deleted file mode 100644 index 880d897f..00000000 --- a/app/helpers/admin/repositories_helper.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Admin::RepositoriesHelper - - def check_boolean(str) - str == "true" - end -end diff --git a/test/controllers/admin/redeem_requests_controller_test.rb b/test/controllers/admin/redeem_requests_controller_test.rb index 6d51c7e2..683a885f 100644 --- a/test/controllers/admin/redeem_requests_controller_test.rb +++ b/test/controllers/admin/redeem_requests_controller_test.rb @@ -92,23 +92,49 @@ class Admin::RedeemRequestsControllerTest < ActionController::TestCase assert_equal "text/csv; header = present;", response.content_type end - test "check header of csv file" do + test "check header of csv file for status false" do seed_data redeem_request = create(:redeem_request, :points => 100, user: @user) - get :download, params: { :status => "false" } || { :status => "true" } + get :download, params: { :status => "false" } assert_response :success attr = "User,Gift Shop,Store,Points,Cost,Date,Coupon Code,Address,Status".split(',') csv = CSV.parse response.body assert_equal csv[0],attr end - test "check fields of csv file" do + test "check header of csv file for status true" do + seed_data + redeem_request = create(:redeem_request, :points => 100, user: @user) + get :download, params: { :status => "true" } + assert_response :success + attr = "User,Gift Shop,Store,Points,Cost,Date,Coupon Code,Address,Status".split(',') + csv = CSV.parse response.body + assert_equal csv[0],attr + end + + test "check fields of csv file for status true" do + seed_data + gift_shop = ["github","amazon","other"] + store = [nil,"amazon.com","amazon.in","amazon.uk"] + status = ["false","true"] + redeem_request = create(:redeem_request, :points => 100, user: @user) + get :download, params: { :status => "true" } + assert_response :success + csv = CSV.parse response.body + assert_includes gift_shop, csv[1][1] + assert_includes store, csv[1][2] + assert_kind_of Fixnum, csv[1][3].to_i + assert_not_equal csv[1][3].to_i, csv[1][4].to_i + assert_includes status, csv[1][8] + end + + test "check fields of csv file for status false" do seed_data gift_shop = ["github","amazon","other"] store = [nil,"amazon.com","amazon.in","amazon.uk"] status = ["false","true"] redeem_request = create(:redeem_request, :points => 100, user: @user) - get :download, params: { :status => "false" } || {:status => "true"} + get :download, params: {:status => "false"} assert_response :success csv = CSV.parse response.body assert_includes gift_shop, csv[1][1] diff --git a/test/helpers/admin/repositories_helper_test.rb b/test/helpers/admin/repositories_helper_test.rb deleted file mode 100644 index d7a97452..00000000 --- a/test/helpers/admin/repositories_helper_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "test_helper" - -class Admin::RepositoriesHelperTest < ActionView::TestCase - - test "should return true of string true and vice versa" do - assert_equal check_boolean("true"), true - assert_equal check_boolean("false"), false - end - - def test_sanity - flunk "Need real tests" - end -end From 83d81e42250a5000ad775ecc43c52bc6b7116c90 Mon Sep 17 00:00:00 2001 From: amitk Date: Mon, 24 Jul 2017 17:55:16 +0530 Subject: [PATCH 10/11] constant value replaced with initializers constant --- app/controllers/admin/redeem_requests_controller.rb | 2 +- app/helpers/admin/redeem_requests_helper.rb | 2 +- config/mongoid.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/redeem_requests_controller.rb b/app/controllers/admin/redeem_requests_controller.rb index 00f09a41..82ffd81b 100644 --- a/app/controllers/admin/redeem_requests_controller.rb +++ b/app/controllers/admin/redeem_requests_controller.rb @@ -35,7 +35,7 @@ def download csv << ["User", "Gift Shop", "Store", "Points", "Cost", "Date", "Coupon Code", "Address", "Status"] @redeem_requests.each do |redeem_request| csv << [redeem_request.user.email, redeem_request.retailer, redeem_request.store, - redeem_request.points, redeem_request.points/10, + redeem_request.points, redeem_request.points/REDEEM['one_dollar_to_points'], redeem_request.updated_at.strftime(fmt='%F %T'), redeem_request.coupon_code, redeem_request.address, redeem_request.status] end diff --git a/app/helpers/admin/redeem_requests_helper.rb b/app/helpers/admin/redeem_requests_helper.rb index 8d5bd72e..620cc23f 100644 --- a/app/helpers/admin/redeem_requests_helper.rb +++ b/app/helpers/admin/redeem_requests_helper.rb @@ -1,7 +1,7 @@ module Admin::RedeemRequestsHelper def total_capital_of_points - RedeemRequest.where(status: false).sum(:points)/10 + RedeemRequest.where(status: false).sum(:points)/REDEEM['one_dollar_to_points'] end end diff --git a/config/mongoid.yml b/config/mongoid.yml index f0b68c30..e9b807cc 100644 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -5,7 +5,7 @@ development: default: # Defines the name of the default database that Mongoid can connect to. # (required). - database: code_curiosity_development + database: code_curiosity_dev # Provides the hosts the default client can connect to. Must be an array # of host:port pairs. (required) hosts: From 3500560b670fbb0353c266fdf71277c25446c23c Mon Sep 17 00:00:00 2001 From: amitk Date: Tue, 25 Jul 2017 12:11:22 +0530 Subject: [PATCH 11/11] reverted changes --- config/mongoid.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/mongoid.yml b/config/mongoid.yml index e9b807cc..f0b68c30 100644 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -5,7 +5,7 @@ development: default: # Defines the name of the default database that Mongoid can connect to. # (required). - database: code_curiosity_dev + database: code_curiosity_development # Provides the hosts the default client can connect to. Must be an array # of host:port pairs. (required) hosts: