From 6205c7266a5e23df81284ae2d8da49d8cd206df6 Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Thu, 25 Jun 2015 00:51:08 +0200 Subject: [PATCH 1/8] Adding creditcard payment --- Gemfile | 1 + Gemfile.lock | 15 ++++- app/controllers/charges_controller.rb | 17 ++++++ app/views/charges/create.html.erb | 1 + app/views/charges/new.html.erb | 65 +++++++++++++++++++++ config/initializers/stripe.rb | 6 ++ config/routes/subdomain_present.rb | 1 + spec/controllers/charges_controller_spec.rb | 5 ++ 8 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 app/controllers/charges_controller.rb create mode 100644 app/views/charges/create.html.erb create mode 100644 app/views/charges/new.html.erb create mode 100644 config/initializers/stripe.rb create mode 100644 spec/controllers/charges_controller_spec.rb diff --git a/Gemfile b/Gemfile index 6ed8d832..614d3022 100644 --- a/Gemfile +++ b/Gemfile @@ -41,6 +41,7 @@ gem "paperclip", "~> 4.2" gem "aws-sdk", "< 2.0" gem "redcarpet" gem "holidays" +gem "stripe" source "https://rails-assets.org" do gem "rails-assets-chartjs" diff --git a/Gemfile.lock b/Gemfile.lock index 3d2ede64..83c3ca87 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -128,6 +128,8 @@ GEM devise (>= 3.2.0) diff-lcs (1.2.5) docile (1.1.5) + domain_name (0.5.24) + unf (>= 0.0.5, < 1.0.0) dotenv (0.11.1) dotenv-deployment (~> 0.0.2) dotenv-deployment (0.0.2) @@ -164,6 +166,8 @@ GEM high_voltage (2.2.0) highline (1.6.21) holidays (1.2.0) + http-cookie (1.0.2) + domain_name (~> 0.5) http_accept_language (2.0.1) i18n (0.7.0) jquery-atwho-rails (1.0.0) @@ -194,6 +198,7 @@ GEM neat (1.5.1) bourbon (>= 3.1) sass (~> 3.2.19) + netrc (0.10.3) newrelic_rpm (3.9.0.229) nokogiri (1.6.6.2) mini_portile (~> 0.6.0) @@ -256,6 +261,10 @@ GEM redcarpet (3.2.2) responders (2.0.2) railties (>= 4.2.0.alpha, < 5) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) rspec-core (3.1.7) rspec-support (~> 3.1.0) rspec-expectations (3.1.2) @@ -311,6 +320,9 @@ GEM actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) + stripe (1.22.0) + json (~> 1.8.1) + rest-client (~> 1.4) temple (0.6.7) terminal-table (1.4.5) thor (0.19.1) @@ -406,6 +418,7 @@ DEPENDENCIES simplecov spring spring-commands-rspec + stripe timecop title twitter-text @@ -414,4 +427,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.10.3 + 1.10.4 diff --git a/app/controllers/charges_controller.rb b/app/controllers/charges_controller.rb new file mode 100644 index 00000000..9e068f37 --- /dev/null +++ b/app/controllers/charges_controller.rb @@ -0,0 +1,17 @@ +class ChargesController < ApplicationController + def new + end + + def create + # Get the credit card details submitted by the form + token = params[:stripeToken] + + # Create a Customer + customer = Stripe::Customer.create( + :source => token, + :plan => "value", + :email => current_user.email, + :quantity => User.count + ) + end +end diff --git a/app/views/charges/create.html.erb b/app/views/charges/create.html.erb new file mode 100644 index 00000000..7d9db941 --- /dev/null +++ b/app/views/charges/create.html.erb @@ -0,0 +1 @@ +

Thanks, you paid $5.00!

diff --git a/app/views/charges/new.html.erb b/app/views/charges/new.html.erb new file mode 100644 index 00000000..947a5b30 --- /dev/null +++ b/app/views/charges/new.html.erb @@ -0,0 +1,65 @@ + +<%= form_tag charges_path, method: "POST", id: "payment-form" do %> + + +
+ +
+ +
+ +
+ +
+ + / + +
+ + +<% end %> + + diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb new file mode 100644 index 00000000..37b5d115 --- /dev/null +++ b/config/initializers/stripe.rb @@ -0,0 +1,6 @@ +Rails.configuration.stripe = { + :publishable_key => ENV['STRIPE_PUBLIC_KEY'], + :secret_key => ENV['STRIPE_SECRET_KEY'] +} + +Stripe.api_key = Rails.configuration.stripe[:secret_key] diff --git a/config/routes/subdomain_present.rb b/config/routes/subdomain_present.rb index 858af6f6..c2403eda 100644 --- a/config/routes/subdomain_present.rb +++ b/config/routes/subdomain_present.rb @@ -20,6 +20,7 @@ resources :tags, only: [:show] resources :clients, only: [:show, :index, :edit, :update, :create] +resources :charges get "user/edit" => "users#edit", as: :edit_user get "account/edit" => "accounts#edit", as: :edit_account diff --git a/spec/controllers/charges_controller_spec.rb b/spec/controllers/charges_controller_spec.rb new file mode 100644 index 00000000..bcc03687 --- /dev/null +++ b/spec/controllers/charges_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ChargesController, :type => :controller do + +end From 1730d5ac2d95723e96b328e76a2c5d8e471c8012 Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Thu, 25 Jun 2015 22:50:08 +0200 Subject: [PATCH 2/8] Clean code up and save the customer.id --- .sample.env | 3 + app/controllers/charges_controller.rb | 16 +++-- app/views/charges/create.html.erb | 1 - app/views/charges/create.html.haml | 3 + app/views/charges/new.html.erb | 65 ------------------- app/views/charges/new.html.haml | 52 +++++++++++++++ config/initializers/stripe.rb | 4 +- config/locales/en.yml | 6 ++ config/locales/nl.yml | 6 ++ ...20150625203904_add_stripe_id_to_account.rb | 5 ++ db/schema.rb | 3 +- spec/controllers/charges_controller_spec.rb | 5 -- 12 files changed, 91 insertions(+), 78 deletions(-) delete mode 100644 app/views/charges/create.html.erb create mode 100644 app/views/charges/create.html.haml delete mode 100644 app/views/charges/new.html.erb create mode 100644 app/views/charges/new.html.haml create mode 100644 db/migrate/20150625203904_add_stripe_id_to_account.rb delete mode 100644 spec/controllers/charges_controller_spec.rb diff --git a/.sample.env b/.sample.env index 281ad04b..13a9c318 100644 --- a/.sample.env +++ b/.sample.env @@ -9,3 +9,6 @@ SINGLE_TENANT_MODE=false S3_BUCKET_NAME="s3_bucket_name" AWS_ACCESS_KEY_ID="aws_access_key_id" AWS_SECRET_ACCESS_KEY="aws_secret_access_key" +SUBSCRIPTIONS_PRICE="2.00" +STRIPE_PUBLIC_KEY=pk_test_DqOJ0VeQaE9LlQjm4xi4Qig4 +STRIPE_SECRET_KEY=sk_test_FhdIi5AuJfYvmjLT6xDzb28w diff --git a/app/controllers/charges_controller.rb b/app/controllers/charges_controller.rb index 9e068f37..8c2d97fa 100644 --- a/app/controllers/charges_controller.rb +++ b/app/controllers/charges_controller.rb @@ -8,10 +8,18 @@ def create # Create a Customer customer = Stripe::Customer.create( - :source => token, - :plan => "value", - :email => current_user.email, - :quantity => User.count + source: token, + plan: "value", + email: current_user.email, + quantity: user_count ) + current_account.update(stripe_id: customer.id) + end + + private + + def user_count + @user_count ||= User.count end end + diff --git a/app/views/charges/create.html.erb b/app/views/charges/create.html.erb deleted file mode 100644 index 7d9db941..00000000 --- a/app/views/charges/create.html.erb +++ /dev/null @@ -1 +0,0 @@ -

Thanks, you paid $5.00!

diff --git a/app/views/charges/create.html.haml b/app/views/charges/create.html.haml new file mode 100644 index 00000000..00d02a6b --- /dev/null +++ b/app/views/charges/create.html.haml @@ -0,0 +1,3 @@ +%h2 + Thanks, you paid + %strong= number_to_currency(ENV["SUBSCRIPTIONS_PRICE"].to_f * @user_count.to_f, precision: 2, unit: "€") diff --git a/app/views/charges/new.html.erb b/app/views/charges/new.html.erb deleted file mode 100644 index 947a5b30..00000000 --- a/app/views/charges/new.html.erb +++ /dev/null @@ -1,65 +0,0 @@ - -<%= form_tag charges_path, method: "POST", id: "payment-form" do %> - - -
- -
- -
- -
- -
- - / - -
- - -<% end %> - - diff --git a/app/views/charges/new.html.haml b/app/views/charges/new.html.haml new file mode 100644 index 00000000..baeae289 --- /dev/null +++ b/app/views/charges/new.html.haml @@ -0,0 +1,52 @@ +%script{:src => "https://js.stripe.com/v2/", :type => "text/javascript"} += form_tag charges_path, method: "POST", id: "payment-form" do + %span.payment-errors + .form-row + %label + %span= t "payments.labels.card_number" + %input{"data-stripe" => "number", :size => "20", :type => "text"}/ + .form-row + %label + %span= t "payments.labels.cvc" + %input{"data-stripe" => "cvc", :size => "4", :type => "text"}/ + .form-row + %label + %span= t "payments.labels.expiration_date" + %input{"data-stripe" => "exp-month", :size => "2", :type => "text"}/ + %span / + %input{"data-stripe" => "exp-year", :size => "4", :type => "text"}/ + %button{:type => "submit"}= t "payments.pay_button" +%script{:src => "https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"} +:javascript + // This identifies your website in the createToken call below + Stripe.setPublishableKey('#{ENV["STRIPE_PUBLIC_KEY"]}'); + jQuery(function($) { + $('#payment-form').submit(function(event) { + var $form = $(this); + + // Disable the submit button to prevent repeated clicks + $form.find('button').prop('disabled', true); + + Stripe.card.createToken($form, stripeResponseHandler); + + // Prevent the form from submitting with the default action + return false; + }); + }); + + function stripeResponseHandler(status, response) { + var $form = $('#payment-form'); + + if (response.error) { + // Show the errors on the form + $form.find('.payment-errors').text(response.error.message); + $form.find('button').prop('disabled', false); + } else { + // response contains id and card, which contains additional card details + var token = response.id; + // Insert the token into the form so it gets submitted to the server + $form.append($('').val(token)); + // and submit + $form.get(0).submit(); + } + }; diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb index 37b5d115..858fea30 100644 --- a/config/initializers/stripe.rb +++ b/config/initializers/stripe.rb @@ -1,6 +1,6 @@ Rails.configuration.stripe = { - :publishable_key => ENV['STRIPE_PUBLIC_KEY'], - :secret_key => ENV['STRIPE_SECRET_KEY'] + publishable_key: ENV["STRIPE_PUBLIC_KEY"], + secret_key: ENV["STRIPE_SECRET_KEY"] } Stripe.api_key = Rails.configuration.stripe[:secret_key] diff --git a/config/locales/en.yml b/config/locales/en.yml index 9824adcb..77a63c08 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -174,6 +174,12 @@ en: edit_user: Edit profile entries: My Entries no_hours_registered: Nobody spent any time on %{project} yet + payments: + pay_button: Submit Payment + labels: + card_number: Card Number + cvc: CVC + expiration_date: Expiration (MM/YYYY) project: errors: client_missing: If the project is billable it needs a client diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 8f35d206..1c7a86fd 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -231,6 +231,12 @@ nl: edit_user: Gegevens aanpassen entries: Mijn Uren no_hours_registered: Niemand heeft nog tijd aan %{project} besteed + payments: + pay_button: Betalen + labels: + card_number: Creditcard nummer + cvc: CVC + expiration_date: Einddatum (MM/YYYY) project: errors: client_missing: Als het project facturabel is moet er een klant geselecteerd worden diff --git a/db/migrate/20150625203904_add_stripe_id_to_account.rb b/db/migrate/20150625203904_add_stripe_id_to_account.rb new file mode 100644 index 00000000..cfa3fe52 --- /dev/null +++ b/db/migrate/20150625203904_add_stripe_id_to_account.rb @@ -0,0 +1,5 @@ +class AddStripeIdToAccount < ActiveRecord::Migration + def change + add_column :accounts, :stripe_id, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 13fb65b5..245e5fb8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150224115957) do +ActiveRecord::Schema.define(version: 20150625203904) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -21,6 +21,7 @@ t.integer "owner_id", default: 0, null: false t.datetime "created_at" t.datetime "updated_at" + t.string "stripe_id" end create_table "audits", force: :cascade do |t| diff --git a/spec/controllers/charges_controller_spec.rb b/spec/controllers/charges_controller_spec.rb deleted file mode 100644 index bcc03687..00000000 --- a/spec/controllers/charges_controller_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe ChargesController, :type => :controller do - -end From 88824bce7f65e83d350a1bbb87fe95ac6102cfad Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Fri, 26 Jun 2015 10:44:24 +0200 Subject: [PATCH 3/8] Do not work when in single tenant mode or without stripe setup --- Gemfile.lock | 2 +- app/controllers/charges_controller.rb | 12 +++++++++--- app/views/accounts/edit.html.haml | 1 + config/initializers/stripe.rb | 14 +++++++++----- config/locales/en.yml | 1 + config/locales/nl.yml | 1 + 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 83c3ca87..43665bbd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -427,4 +427,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.10.4 + 1.10.5 diff --git a/app/controllers/charges_controller.rb b/app/controllers/charges_controller.rb index 8c2d97fa..d38e246c 100644 --- a/app/controllers/charges_controller.rb +++ b/app/controllers/charges_controller.rb @@ -1,18 +1,19 @@ class ChargesController < ApplicationController + before_action :chargin_set? + def new end def create - # Get the credit card details submitted by the form token = params[:stripeToken] - # Create a Customer customer = Stripe::Customer.create( source: token, plan: "value", email: current_user.email, quantity: user_count ) + pp customer.instance_methods(false) current_account.update(stripe_id: customer.id) end @@ -21,5 +22,10 @@ def create def user_count @user_count ||= User.count end -end + def chargin_set? + Hours.single_tenant_mode? == false && + ENV["STRIPE_PUBLIC_KEY"] && + ENV["STRIPE_SECRET_KEY"] + end +end diff --git a/app/views/accounts/edit.html.haml b/app/views/accounts/edit.html.haml index 0cad6dba..153dc722 100644 --- a/app/views/accounts/edit.html.haml +++ b/app/views/accounts/edit.html.haml @@ -1,5 +1,6 @@ .outer .container + = link_to t("payment_link"), new_charge_path %h1= title .danger-zone %h2= t("account.danger_zone") diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb index 858fea30..96c493cd 100644 --- a/config/initializers/stripe.rb +++ b/config/initializers/stripe.rb @@ -1,6 +1,10 @@ -Rails.configuration.stripe = { - publishable_key: ENV["STRIPE_PUBLIC_KEY"], - secret_key: ENV["STRIPE_SECRET_KEY"] -} +if Hours.single_tenant_mode? == false && + ENV["STRIPE_PUBLIC_KEY"] && + ENV["STRIPE_SECRET_KEY"] + Rails.configuration.stripe = { + publishable_key: ENV["STRIPE_PUBLIC_KEY"], + secret_key: ENV["STRIPE_SECRET_KEY"] + } -Stripe.api_key = Rails.configuration.stripe[:secret_key] + Stripe.api_key = Rails.configuration.stripe[:secret_key] +end diff --git a/config/locales/en.yml b/config/locales/en.yml index 77a63c08..a0820e0b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -42,6 +42,7 @@ en: invalid_characters: contains invalid characters last_name: Last Name password: Password + payment_link: Payments repeat_password: Repeat Password subdomain: Subdomain warning: Deleting your account will remove you and everyone else's data from %{subdomain} diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 1c7a86fd..cae783f8 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -41,6 +41,7 @@ nl: invalid_characters: bevat invalide karakters last_name: Achternaam password: Wachtwoord + payment_link: Betalen repeat_password: Bevesting wachtwoord subdomain: subdomein warning: Het verwijderen van je account zal jouw en iedereens gegevens op %{subdomain} From cd788511d79db2f2960d6f3ac1115be413a9a67a Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Mon, 29 Jun 2015 12:52:50 +0200 Subject: [PATCH 4/8] Show and delete subscriptions --- .rubocop.yml | 17 ++++++++ app/controllers/charges_controller.rb | 41 +++++++++++++++---- app/models/subscription.rb | 20 +++++++++ app/views/charges/show.html.haml | 9 ++++ config/locales/en.yml | 6 +++ config/locales/nl.yml | 1 + config/routes/subdomain_present.rb | 4 +- ...26100838_add_subscription_id_to_account.rb | 5 +++ db/schema.rb | 8 ++-- 9 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 .rubocop.yml create mode 100644 app/models/subscription.rb create mode 100644 app/views/charges/show.html.haml create mode 100644 db/migrate/20150626100838_add_subscription_id_to_account.rb diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..9c315123 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,17 @@ +AllCops: + Exclude: + - "vendor/**/*" + - "db/**/*" +Style/StringLiterals: + EnforcedStyle: double_quotes + Enabled: true +Style/FileName: + Enabled: false +Metrics/AbcSize: + Description: A calculated magnitude based on number of assignments, branches, and + conditions. + Enabled: true + Max: 15 +Style/DotPosition: + EnforcedStyle: trailing + Enabled: true diff --git a/app/controllers/charges_controller.rb b/app/controllers/charges_controller.rb index d38e246c..d2a6856b 100644 --- a/app/controllers/charges_controller.rb +++ b/app/controllers/charges_controller.rb @@ -1,5 +1,9 @@ class ChargesController < ApplicationController before_action :chargin_set? + before_action :set_user_count + + def show + end def new end @@ -7,19 +11,38 @@ def new def create token = params[:stripeToken] - customer = Stripe::Customer.create( - source: token, - plan: "value", - email: current_user.email, - quantity: user_count - ) - pp customer.instance_methods(false) - current_account.update(stripe_id: customer.id) + if token + customer = Stripe::Customer.create( + source: token, + plan: "value", + email: current_user.email, + quantity: @user_count + ) + + current_account.update( + stripe_id: customer.id, + subscription_id: customer.subscriptions.data[0].id + ) + else + render :new, notice: t("payments.went_wrong_message") + end + end + + def destroy + cu = Stripe::Customer.retrieve(current_account.stripe_id) + + if cu.delete.deleted + current_account.update(stripe_id: nil, + subscription_id: nil) + render :show, success: t("payments.delete.success") + else + render :show, error: t("payments.delete.fails") + end end private - def user_count + def set_user_count @user_count ||= User.count end diff --git a/app/models/subscription.rb b/app/models/subscription.rb new file mode 100644 index 00000000..61e6ee5f --- /dev/null +++ b/app/models/subscription.rb @@ -0,0 +1,20 @@ +class Subscription + + def initialize + account ||= Account.find_by(subdomain: Apartment::tennant.current) + + @stripe_id = account.stripe_id + @subscription_id = account.subscription_id + @price = ENV["SUBSCRIPTIONS_PRICE"].to_f + @number_of_users = User.count + def + + def costs + @number_of_users * price + end + + def enabled? + stripe_id && subscription_id + end + +end diff --git a/app/views/charges/show.html.haml b/app/views/charges/show.html.haml new file mode 100644 index 00000000..81058a96 --- /dev/null +++ b/app/views/charges/show.html.haml @@ -0,0 +1,9 @@ +.outer + .container + %h2 + = t("payment.show.subscription") + .current-subscription + = t("payment.current_subscription") + = number_to_currency(@user_count * ENV["SUBSCRIPTIONS_PRICE"].to_f ) + + = link_to "remove subscription", destroy_charge_path, method: "DELETE" diff --git a/config/locales/en.yml b/config/locales/en.yml index a0820e0b..c35100d5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -181,6 +181,12 @@ en: card_number: Card Number cvc: CVC expiration_date: Expiration (MM/YYYY) + went_wrong_message: Something went wrong + edit: + header: Subscription + delete: + success: Subscription successful deleted + fail: Could not delete you're subscription project: errors: client_missing: If the project is billable it needs a client diff --git a/config/locales/nl.yml b/config/locales/nl.yml index cae783f8..ab9de1c9 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -238,6 +238,7 @@ nl: card_number: Creditcard nummer cvc: CVC expiration_date: Einddatum (MM/YYYY) + went_wrong_message: Er ging iets mis project: errors: client_missing: Als het project facturabel is moet er een klant geselecteerd worden diff --git a/config/routes/subdomain_present.rb b/config/routes/subdomain_present.rb index c2403eda..de8aa20c 100644 --- a/config/routes/subdomain_present.rb +++ b/config/routes/subdomain_present.rb @@ -20,7 +20,9 @@ resources :tags, only: [:show] resources :clients, only: [:show, :index, :edit, :update, :create] -resources :charges +resources :charges, only: [:new, :create] +delete "charges" => "charges#destroy", as: :destroy_charge +get "charges" => "charges#show", as: :show_charge get "user/edit" => "users#edit", as: :edit_user get "account/edit" => "accounts#edit", as: :edit_account diff --git a/db/migrate/20150626100838_add_subscription_id_to_account.rb b/db/migrate/20150626100838_add_subscription_id_to_account.rb new file mode 100644 index 00000000..f64214fe --- /dev/null +++ b/db/migrate/20150626100838_add_subscription_id_to_account.rb @@ -0,0 +1,5 @@ +class AddSubscriptionIdToAccount < ActiveRecord::Migration + def change + add_column :accounts, :subscription_id, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 245e5fb8..0e2ce9b4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,17 +11,19 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150625203904) do +ActiveRecord::Schema.define(version: 20150626100838) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + enable_extension "hstore" create_table "accounts", force: :cascade do |t| - t.string "subdomain", default: "", null: false - t.integer "owner_id", default: 0, null: false + t.string "subdomain", default: "", null: false + t.integer "owner_id", default: 0, null: false t.datetime "created_at" t.datetime "updated_at" t.string "stripe_id" + t.string "subscription_id" end create_table "audits", force: :cascade do |t| From f99a26bbb6029460e1b0cbea75833a39fa849c77 Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Mon, 29 Jun 2015 15:03:00 +0200 Subject: [PATCH 5/8] [ci skip] wip only delete when subscription is set --- app/controllers/charges_controller.rb | 8 +++++--- app/models/subscription.rb | 11 ++++++----- app/views/charges/show.html.haml | 6 ++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/controllers/charges_controller.rb b/app/controllers/charges_controller.rb index d2a6856b..24a949b8 100644 --- a/app/controllers/charges_controller.rb +++ b/app/controllers/charges_controller.rb @@ -1,6 +1,6 @@ class ChargesController < ApplicationController before_action :chargin_set? - before_action :set_user_count + before_action :set_subscription def show end @@ -34,6 +34,8 @@ def destroy if cu.delete.deleted current_account.update(stripe_id: nil, subscription_id: nil) + @subscription = Subscription.new(current_account) + render :show, success: t("payments.delete.success") else render :show, error: t("payments.delete.fails") @@ -42,8 +44,8 @@ def destroy private - def set_user_count - @user_count ||= User.count + def set_subscription + @subscription ||= Subscription.new(current_account) end def chargin_set? diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 61e6ee5f..d9535032 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -1,16 +1,17 @@ class Subscription + include ActiveModel::Model + include ActiveModel::Validations + attr_reader :number_of_users, :price, :stripe_id, :subscription_id - def initialize - account ||= Account.find_by(subdomain: Apartment::tennant.current) - + def initialize(account) @stripe_id = account.stripe_id @subscription_id = account.subscription_id @price = ENV["SUBSCRIPTIONS_PRICE"].to_f @number_of_users = User.count - def + end def costs - @number_of_users * price + enabled? ? @number_of_users * price : 0 end def enabled? diff --git a/app/views/charges/show.html.haml b/app/views/charges/show.html.haml index 81058a96..030390e4 100644 --- a/app/views/charges/show.html.haml +++ b/app/views/charges/show.html.haml @@ -1,9 +1,11 @@ .outer .container + = link_to "new charges", new_charge_path %h2 = t("payment.show.subscription") .current-subscription = t("payment.current_subscription") - = number_to_currency(@user_count * ENV["SUBSCRIPTIONS_PRICE"].to_f ) + = number_to_currency(@subscription.costs, unit: "€") - = link_to "remove subscription", destroy_charge_path, method: "DELETE" + - if @subscription.enabled? + = link_to "remove subscription", destroy_charge_path, method: "DELETE" From 5ee1b55858c041d38ec4c3d2fdc033051736c3fd Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Tue, 30 Jun 2015 11:31:03 +0200 Subject: [PATCH 6/8] only delete when subscription is set --- app/models/subscription.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/models/subscription.rb b/app/models/subscription.rb index d9535032..88833c14 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -4,18 +4,17 @@ class Subscription attr_reader :number_of_users, :price, :stripe_id, :subscription_id def initialize(account) - @stripe_id = account.stripe_id - @subscription_id = account.subscription_id + @stripe_id = account.stripe_id + @subscription_id = account.subscription_id @price = ENV["SUBSCRIPTIONS_PRICE"].to_f @number_of_users = User.count end def costs - enabled? ? @number_of_users * price : 0 + enabled? ? @number_of_users * price : 0 end def enabled? stripe_id && subscription_id end - end From 6a47ded4e3c2094507dc327f30ec0d617af26c00 Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Tue, 30 Jun 2015 18:18:35 +0200 Subject: [PATCH 7/8] [ci skip] de-activate and activate wip --- Gemfile.lock | 33 ++++----- app/controllers/users_controller.rb | 5 ++ app/models/subscription.rb | 2 +- app/views/charges/create.html.haml | 4 +- app/views/users/index.html.haml | 1 + config/locales/en.yml | 4 ++ config/locales/nl.yml | 8 +++ config/routes/subdomain_present.rb | 2 +- lib/hours.rb | 6 +- .../features/owner_soft_deletes_users_spec.rb | 23 ++++++ spec/models/subscription_spec.rb | 18 +++++ spec/models/user_spec.rb | 70 +++++++++---------- 12 files changed, 120 insertions(+), 56 deletions(-) create mode 100644 spec/features/owner_soft_deletes_users_spec.rb create mode 100644 spec/models/subscription_spec.rb diff --git a/Gemfile.lock b/Gemfile.lock index 43665bbd..6cc4e1f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -218,7 +218,7 @@ GEM slop (~> 3.4) pry-rails (0.3.2) pry (>= 0.9.10) - rack (1.6.2) + rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) rack-timeout (0.0.4) @@ -265,22 +265,23 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) - rspec-core (3.1.7) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) + rspec-core (3.3.1) + rspec-support (~> 3.3.0) + rspec-expectations (3.3.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-rails (3.1.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-support (~> 3.1.0) - rspec-support (3.1.2) + rspec-support (~> 3.3.0) + rspec-mocks (3.3.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.3.0) + rspec-rails (3.3.2) + actionpack (>= 3.0, < 4.3) + activesupport (>= 3.0, < 4.3) + railties (>= 3.0, < 4.3) + rspec-core (~> 3.3.0) + rspec-expectations (~> 3.3.0) + rspec-mocks (~> 3.3.0) + rspec-support (~> 3.3.0) + rspec-support (3.3.0) ruby2ruby (2.0.7) ruby_parser (~> 3.1) sexp_processor (~> 4.0) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e378d140..2dbc226b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -22,6 +22,11 @@ def update end end + def destroy + @user = current_user + @user.update(active: true) + end + private def resource diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 88833c14..0b341969 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -6,7 +6,7 @@ class Subscription def initialize(account) @stripe_id = account.stripe_id @subscription_id = account.subscription_id - @price = ENV["SUBSCRIPTIONS_PRICE"].to_f + @price = Hours.subscriptions_price @number_of_users = User.count end diff --git a/app/views/charges/create.html.haml b/app/views/charges/create.html.haml index 00d02a6b..466521db 100644 --- a/app/views/charges/create.html.haml +++ b/app/views/charges/create.html.haml @@ -1,3 +1,3 @@ %h2 - Thanks, you paid - %strong= number_to_currency(ENV["SUBSCRIPTIONS_PRICE"].to_f * @user_count.to_f, precision: 2, unit: "€") + = t("payments.thanks") + %strong= number_to_currency(@subscription.costs, precision: 2, unit: "€") diff --git a/app/views/users/index.html.haml b/app/views/users/index.html.haml index 326a3058..1d231519 100644 --- a/app/views/users/index.html.haml +++ b/app/views/users/index.html.haml @@ -9,6 +9,7 @@ %td = link_to user.full_name, user_path(user) if user.confirmed? %td= user.email + %td= button_to t("users.de_archive"), user_path(user), method: :delete %td - unless user.accepted_or_not_invited? = t("users.invitation_sent_at", | diff --git a/config/locales/en.yml b/config/locales/en.yml index c35100d5..f615386d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -187,6 +187,7 @@ en: delete: success: Subscription successful deleted fail: Could not delete you're subscription + thanks: Thanks, you paid project: errors: client_missing: If the project is billable it needs a client @@ -203,6 +204,7 @@ en: edit: archive_link: Archive un_archive_link: Un-archive + project_activity_html: one: "%{full_name} spent %{hours} hours working on %{project}" other: "%{count} people spent %{hours} hours working on %{project}" @@ -274,6 +276,8 @@ en: invite: Invite User invitation_sent_at: Invited %{time_ago} ago confirm: Confirm + activate: Activate + de_activate: De-Activate entry_filters: title: Filters clients: All Clients diff --git a/config/locales/nl.yml b/config/locales/nl.yml index ab9de1c9..04d91884 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -239,6 +239,12 @@ nl: cvc: CVC expiration_date: Einddatum (MM/YYYY) went_wrong_message: Er ging iets mis + edit: + header: Abbonoment + delete: + success: Abbonoment is verwijderd + fail: Uw abbonoment kon niet verwijderd worden. + thanks: Bedankt, u betaalde project: errors: client_missing: Als het project facturabel is moet er een klant geselecteerd worden @@ -349,6 +355,8 @@ nl: email: Email invitation_sent_at: "%{time_ago} geleden uitgenodigd" invite: Nodig uit + activate: Activeren + de_activate: De-activeren views: pagination: truncate: ... diff --git a/config/routes/subdomain_present.rb b/config/routes/subdomain_present.rb index de8aa20c..4646309f 100644 --- a/config/routes/subdomain_present.rb +++ b/config/routes/subdomain_present.rb @@ -14,7 +14,7 @@ resources :billables, only: [:index] -resources :users, only: [:index, :update, :show] do +resources :users, only: [:index, :update, :show, :destroy] do resources :entries, only: [:index] end diff --git a/lib/hours.rb b/lib/hours.rb index cb754649..b262d55c 100644 --- a/lib/hours.rb +++ b/lib/hours.rb @@ -2,7 +2,7 @@ module Hours def self.google_analytics_id ENV["GOOGLE_ANALYTICS_KEY"] end - + def self.helpful_url ENV["HELPFUL_URL"] end @@ -33,4 +33,8 @@ def self.single_tenant_mode? def self.cache_id @@cache_id ||= Time.current.to_s end + + def self.subscriptions_price + ENV["SUBSCRIPTIONS_PRICE"].to_f + end end diff --git a/spec/features/owner_soft_deletes_users_spec.rb b/spec/features/owner_soft_deletes_users_spec.rb new file mode 100644 index 00000000..817dba78 --- /dev/null +++ b/spec/features/owner_soft_deletes_users_spec.rb @@ -0,0 +1,23 @@ +require "spec_helper" + +feature "Soft Delete Users" do + let(:subdomain) { generate(:subdomain) } + let(:owner) { build(:user) } + let(:user) { build(:user) } + + before(:each) do + create(:account_with_schema, subdomain: subdomain, owner: owner) + end + + context "as the owner of an account" do + scenario "deleting an user" do + sign_in_user(owner, subdomain: subdomain) + + visit users_url(subdomain: subdomain) + within "tr", text: user.name do + click_button I18n.t("users.de_activate") + expect(page).to have_content(I18n.t("users.activate")) + end + end + end +end diff --git a/spec/models/subscription_spec.rb b/spec/models/subscription_spec.rb new file mode 100644 index 00000000..652c94c5 --- /dev/null +++ b/spec/models/subscription_spec.rb @@ -0,0 +1,18 @@ +require "spec_helper" + +describe Subscription do + describe "#costs" do + it "returns the costs of a subscription" do + ENV["SUBSCRIPTIONS_PRICE"] = "2.00" + account = create(:account, stripe_id: "set", subscription_id: "set") + subscription = Subscription.new(account) + expect(subscription.costs).to eq(2.0) + end + + it "return 0 if subscription is not enabled" do + account = create(:account) + subscription = Subscription.new(account) + expect(subscription.costs).to eq(0) + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 3226e279..7282972e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,38 +1,3 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# first_name :string default(""), not null -# last_name :string default(""), not null -# email :string default(""), not null -# encrypted_password :string default("") -# reset_password_token :string -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default("0"), not null -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string -# last_sign_in_ip :string -# confirmation_token :string -# confirmed_at :datetime -# confirmation_sent_at :datetime -# unconfirmed_email :string -# created_at :datetime -# updated_at :datetime -# organization_id :integer -# slug :string -# invitation_token :string -# invitation_created_at :datetime -# invitation_sent_at :datetime -# invitation_accepted_at :datetime -# invitation_limit :integer -# invited_by_id :integer -# invited_by_type :string -# invitations_count :integer default("0") -# - require "spec_helper" describe User do @@ -86,3 +51,38 @@ end end end + +# == Schema Information +# +# Table name: users +# +# id :integer not null, primary key +# first_name :string default(""), not null +# last_name :string default(""), not null +# email :string default(""), not null +# encrypted_password :string default("") +# reset_password_token :string +# reset_password_sent_at :datetime +# remember_created_at :datetime +# sign_in_count :integer default("0"), not null +# current_sign_in_at :datetime +# last_sign_in_at :datetime +# current_sign_in_ip :string +# last_sign_in_ip :string +# confirmation_token :string +# confirmed_at :datetime +# confirmation_sent_at :datetime +# unconfirmed_email :string +# created_at :datetime +# updated_at :datetime +# organization_id :integer +# slug :string +# invitation_token :string +# invitation_created_at :datetime +# invitation_sent_at :datetime +# invitation_accepted_at :datetime +# invitation_limit :integer +# invited_by_id :integer +# invited_by_type :string +# invitations_count :integer default("0") +# From 31aab64012360667cc4caa26caf3e0f9ad7e1f22 Mon Sep 17 00:00:00 2001 From: Marcel Horlings Date: Fri, 3 Jul 2015 16:15:01 +0200 Subject: [PATCH 8/8] De-activate and reactivate users as an owner --- app/assets/stylesheets/base/_buttons.scss | 5 ++ app/controllers/users_controller.rb | 13 ++- app/models/account.rb | 12 +-- app/models/user.rb | 81 +++++++++++-------- app/views/users/_users.html.haml | 16 ++++ app/views/users/index.html.haml | 11 +-- config/routes/subdomain_present.rb | 3 + .../20150701093133_add_active_to_users.rb | 5 ++ db/schema.rb | 11 +-- spec/factories/users.rb | 31 +++---- .../features/owner_soft_deletes_users_spec.rb | 30 ++++++- spec/models/account_spec.rb | 12 +-- spec/models/user_spec.rb | 1 + 13 files changed, 150 insertions(+), 81 deletions(-) create mode 100644 app/views/users/_users.html.haml create mode 100644 db/migrate/20150701093133_add_active_to_users.rb diff --git a/app/assets/stylesheets/base/_buttons.scss b/app/assets/stylesheets/base/_buttons.scss index 3319426e..accffda6 100644 --- a/app/assets/stylesheets/base/_buttons.scss +++ b/app/assets/stylesheets/base/_buttons.scss @@ -8,3 +8,8 @@ input[type="submit"] { vertical-align: middle; white-space: nowrap; } + +.button-grey { + @extend %button; + background-color: grey !important; +} diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 2dbc226b..2d11bf60 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,12 +1,13 @@ include TimeSeriesInitializer class UsersController < ApplicationController + before_action :set_users, only: [:index, :toggle_active] + def show @time_series = time_series_for(resource) end def index - @users = User.all end def edit @@ -22,13 +23,17 @@ def update end end - def destroy - @user = current_user - @user.update(active: true) + def toggle_active + resource.toggle!(:active) + redirect_to users_path end private + def set_users + @users ||= User.all + end + def resource @user ||= User.find_by_slug(params[:id]) end diff --git a/app/models/account.rb b/app/models/account.rb index ee35dae3..1651e9e2 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -2,11 +2,13 @@ # # Table name: public.accounts # -# id :integer not null, primary key -# subdomain :string default(""), not null -# owner_id :integer default("0"), not null -# created_at :datetime -# updated_at :datetime +# id :integer not null, primary key +# subdomain :string default(""), not null +# owner_id :integer default("0"), not null +# created_at :datetime +# updated_at :datetime +# stripe_id :string +# subscription_id :string # class Account < ActiveRecord::Base diff --git a/app/models/user.rb b/app/models/user.rb index d3a05cd4..04d47663 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,38 +1,3 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# first_name :string default(""), not null -# last_name :string default(""), not null -# email :string default(""), not null -# encrypted_password :string default("") -# reset_password_token :string -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default("0"), not null -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string -# last_sign_in_ip :string -# confirmation_token :string -# confirmed_at :datetime -# confirmation_sent_at :datetime -# unconfirmed_email :string -# created_at :datetime -# updated_at :datetime -# organization_id :integer -# slug :string -# invitation_token :string -# invitation_created_at :datetime -# invitation_sent_at :datetime -# invitation_accepted_at :datetime -# invitation_limit :integer -# invited_by_id :integer -# invited_by_type :string -# invitations_count :integer default("0") -# - class User < ActiveRecord::Base include Sluggable @@ -53,6 +18,7 @@ class User < ActiveRecord::Base has_many :projects, -> { uniq }, through: :hours scope :by_name, -> { order("lower(last_name)") } + scope :active, -> { where(active: true) } def full_name "#{first_name} #{last_name}" @@ -72,4 +38,49 @@ def color def acronyms first_name[0] + last_name[0] end + + # devise + def active_for_authentication? + super && active + end + + def inactive_message + I18n.t("devise.failure.inactive") + end end + +# == Schema Information +# +# Table name: users +# +# id :integer not null, primary key +# first_name :string default(""), not null +# last_name :string default(""), not null +# email :string default(""), not null +# encrypted_password :string default("") +# reset_password_token :string +# reset_password_sent_at :datetime +# remember_created_at :datetime +# sign_in_count :integer default("0"), not null +# current_sign_in_at :datetime +# last_sign_in_at :datetime +# current_sign_in_ip :string +# last_sign_in_ip :string +# confirmation_token :string +# confirmed_at :datetime +# confirmation_sent_at :datetime +# unconfirmed_email :string +# created_at :datetime +# updated_at :datetime +# organization_id :integer +# slug :string +# invitation_token :string +# invitation_created_at :datetime +# invitation_sent_at :datetime +# invitation_accepted_at :datetime +# invitation_limit :integer +# invited_by_id :integer +# invited_by_type :string +# invitations_count :integer default("0") +# active :boolean default("true") +# diff --git a/app/views/users/_users.html.haml b/app/views/users/_users.html.haml new file mode 100644 index 00000000..112b5ba9 --- /dev/null +++ b/app/views/users/_users.html.haml @@ -0,0 +1,16 @@ +- @users.each do |user| + %tr + %td + = link_to user.full_name, user_path(user) if user.confirmed? + %td= user.email + - if current_user.account + %td + - unless user.account + - if user.active + = button_to t("users.de_activate"), toggle_active_user_path(user), method: :put, class: "button-grey" + - else + = button_to t("users.activate"), toggle_active_user_path(user), method: :put, class: "button-grey" + - unless user.accepted_or_not_invited? + %td + = t("users.invitation_sent_at", | + time_ago: time_ago_in_words(user.invitation_created_at)) | diff --git a/app/views/users/index.html.haml b/app/views/users/index.html.haml index 1d231519..b292a4c1 100644 --- a/app/views/users/index.html.haml +++ b/app/views/users/index.html.haml @@ -4,16 +4,7 @@ .users-overview %table %tbody - - @users.each do |user| - %tr - %td - = link_to user.full_name, user_path(user) if user.confirmed? - %td= user.email - %td= button_to t("users.de_archive"), user_path(user), method: :delete - %td - - unless user.accepted_or_not_invited? - = t("users.invitation_sent_at", | - time_ago: time_ago_in_words(user.invitation_created_at)) | + = render "users/users", locals: { users: @users } .invitation-form = simple_form_for(User.new, url: user_invitation_path) do |f| = f.input :email, placeholder: t("users.email"), label: false, required: true diff --git a/config/routes/subdomain_present.rb b/config/routes/subdomain_present.rb index 4646309f..3c58b725 100644 --- a/config/routes/subdomain_present.rb +++ b/config/routes/subdomain_present.rb @@ -15,6 +15,9 @@ resources :billables, only: [:index] resources :users, only: [:index, :update, :show, :destroy] do + member do + put :toggle_active + end resources :entries, only: [:index] end diff --git a/db/migrate/20150701093133_add_active_to_users.rb b/db/migrate/20150701093133_add_active_to_users.rb new file mode 100644 index 00000000..90276b60 --- /dev/null +++ b/db/migrate/20150701093133_add_active_to_users.rb @@ -0,0 +1,5 @@ +class AddActiveToUsers < ActiveRecord::Migration + def change + add_column :users, :active, :boolean, default: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 0e2ce9b4..f5b3715b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150626100838) do +ActiveRecord::Schema.define(version: 20150701093133) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -151,14 +151,14 @@ add_index "tags", ["slug"], name: "index_tags_on_slug", using: :btree create_table "users", force: :cascade do |t| - t.string "first_name", default: "", null: false - t.string "last_name", default: "", null: false - t.string "email", default: "", null: false + t.string "first_name", default: "", null: false + t.string "last_name", default: "", null: false + t.string "email", default: "", null: false t.string "encrypted_password", default: "" t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0, null: false + t.integer "sign_in_count", default: 0, null: false t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" @@ -179,6 +179,7 @@ t.integer "invited_by_id" t.string "invited_by_type" t.integer "invitations_count", default: 0 + t.boolean "active", default: true end add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 94b5d614..eeb649df 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -1,3 +1,19 @@ + +FactoryGirl.define do + sequence :email do |n| + "test#{n}@example.com" + end + + factory :user do + first_name "John" + last_name "Doe" + email + password "password" + password_confirmation "password" + confirmed_at 2.hours.ago + active true + end +end # == Schema Information # # Table name: users @@ -31,21 +47,8 @@ # invited_by_id :integer # invited_by_type :string # invitations_count :integer default("0") +# active :boolean default("true") # # Read about factories at https://github.com/thoughtbot/factory_girl -FactoryGirl.define do - sequence :email do |n| - "test#{n}@example.com" - end - - factory :user do - first_name "John" - last_name "Doe" - email - password "password" - password_confirmation "password" - confirmed_at 2.hours.ago - end -end diff --git a/spec/features/owner_soft_deletes_users_spec.rb b/spec/features/owner_soft_deletes_users_spec.rb index 817dba78..7ea85a5d 100644 --- a/spec/features/owner_soft_deletes_users_spec.rb +++ b/spec/features/owner_soft_deletes_users_spec.rb @@ -1,9 +1,9 @@ require "spec_helper" -feature "Soft Delete Users" do +feature "De-activate Users" do let(:subdomain) { generate(:subdomain) } let(:owner) { build(:user) } - let(:user) { build(:user) } + let(:user) { create(:user, first_name: "Tim", last_name: "Trump") } before(:each) do create(:account_with_schema, subdomain: subdomain, owner: owner) @@ -12,12 +12,36 @@ context "as the owner of an account" do scenario "deleting an user" do sign_in_user(owner, subdomain: subdomain) + user visit users_url(subdomain: subdomain) within "tr", text: user.name do click_button I18n.t("users.de_activate") - expect(page).to have_content(I18n.t("users.activate")) + expect(find_button(I18n.t("users.activate")).visible?).to eq(true) end + + expect(User.where(active: false).count).to eq(1) + end + + scenario "can't delete an owner" do + sign_in_user(owner, subdomain: subdomain) + + visit users_url(subdomain: subdomain) + within "tr", text: owner.name do + expect(page).to_not have_content(I18n.t("users.de_activate")) + end + end + + scenario "can't de-activate users as an other user " do + Apartment::Tenant.switch(subdomain) + user + sign_in_user(user, subdomain: subdomain) + + visit users_url(subdomain: subdomain) + de_activate = I18n.t("users.de_activate") + expect(page).not_to( + have_selector("input[type=submit][value='#{de_activate}']") + ) end end end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index cfb56576..ff613ccc 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -2,11 +2,13 @@ # # Table name: public.accounts # -# id :integer not null, primary key -# subdomain :string default(""), not null -# owner_id :integer default("0"), not null -# created_at :datetime -# updated_at :datetime +# id :integer not null, primary key +# subdomain :string default(""), not null +# owner_id :integer default("0"), not null +# created_at :datetime +# updated_at :datetime +# stripe_id :string +# subscription_id :string # require "spec_helper" diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7282972e..bf93c9dc 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -85,4 +85,5 @@ # invited_by_id :integer # invited_by_type :string # invitations_count :integer default("0") +# active :boolean default("true") #