From dbc533a1cb101b6c7f642ac944402b5781a0ef28 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 11:56:13 +0200 Subject: [PATCH 01/16] mess around with api params --- app/controllers/transactions_controller.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 5257ce8..dbe77c7 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -22,7 +22,13 @@ class TransactionsController < ApplicationController private - def transaction_params - params.require(:transaction).permit(:creditor_id, :amount, :message) + def set_params + t = params.require(:transaction) + .permit(:debtor, :creditor, :amount, :message) + + t.update { + debtor: User.find_by(name: t[:debtor]) || User.zeus, + creditor: User.find_by(name: t[:creditor]) || User.zeus + } end end From 6229556e38c5c45cfe054f137865cde45f884649 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 12:58:44 +0200 Subject: [PATCH 02/16] Make create in transactions work --- app/controllers/transactions_controller.rb | 12 +++++++----- app/models/client.rb | 1 - app/views/transactions/new.html.haml | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index dbe77c7..74f33a3 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -10,11 +10,13 @@ class TransactionsController < ApplicationController end def create - @transaction = current_user.outgoing_transactions.build( - transaction_params.merge(origin: I18n.t('origin.created_by_user')) + @transaction = Transaction.new(set_params.merge(origin: I18n.t('origin.created_by_user'))) if @transaction.save - redirect_to current_user + respond_to do |format| + format.html { redirect_to root_path } + format.json { head :created } + end else render 'new' end @@ -26,9 +28,9 @@ class TransactionsController < ApplicationController t = params.require(:transaction) .permit(:debtor, :creditor, :amount, :message) - t.update { + t.update({ debtor: User.find_by(name: t[:debtor]) || User.zeus, creditor: User.find_by(name: t[:creditor]) || User.zeus - } + }) end end diff --git a/app/models/client.rb b/app/models/client.rb index bb674c5..cfc2a18 100644 --- a/app/models/client.rb +++ b/app/models/client.rb @@ -13,7 +13,6 @@ class Client < ActiveRecord::Base before_create :generate_key validates :name, presence: true, uniqueness: true - validates :key, presence: true, uniqueness: true def transactions Transaction.where(origin: name) diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index 68d35f0..35defe4 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -1,6 +1,7 @@ = @transaction.errors.full_messages.join(", ") = simple_form_for @transaction do |f| - = f.collection_select :creditor_id, User.all, :id, :name, {}, { class: 'select2-selector' } + = f.hidden_field :debtor, value: current_user.name + = f.collection_select :creditor, User.all, :name, :name, {}, { class: 'select2-selector' } = f.input :amount = f.input :message, required: true = f.submit "Send it!" From 3d8b1e9c602fa02062307aa0c299d3fc9ffdf6e5 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 13:33:55 +0200 Subject: [PATCH 03/16] fix transactions cretate --- app/controllers/transactions_controller.rb | 26 +++++++++++++--------- app/views/layouts/application.html.haml | 4 +++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 72128f6..bf3ba5f 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -8,27 +8,33 @@ class TransactionsController < ApplicationController end def create - @transaction = Transaction.new(set_params.merge(origin: I18n.t('origin.created_by_user'))) - - if @transaction.save - respond_to do |format| - format.html { redirect_to root_path } - format.json { head :created } + @transaction = Transaction.new(transaction_params) + respond_to do |format| + format.html do + if @transaction.save + flash[:success] = "Transaction created" + redirect_to new_transaction_path + else + render 'new' + end + end + + format.json do + head(@transaction.save ? :created : :unprocessable_entity) end - else - render 'new' end end private - def set_params + def transaction_params t = params.require(:transaction) .permit(:debtor, :creditor, :amount, :message) t.update({ debtor: User.find_by(name: t[:debtor]) || User.zeus, - creditor: User.find_by(name: t[:creditor]) || User.zeus + creditor: User.find_by(name: t[:creditor]) || User.zeus, + issuer: current_client || current_user }) end end diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 41f8d44..20d7dea 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -7,5 +7,7 @@ = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags %body - = content_tag :div, flash[:alert] if flash[:alert] + - flash.each do |key, value| + .alert{ :class => "alert-#{key}" } + = value = yield From d948071e49a6b3aef16cd7a43ec1b2fbe418ce70 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 14:08:40 +0200 Subject: [PATCH 04/16] Put authentication on api --- app/controllers/application_controller.rb | 9 ++++++--- app/controllers/transactions_controller.rb | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index dd697e4..deb151c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,12 +1,16 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. - protect_from_forgery with: :null_session + protect_from_forgery with: :exception rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, alert: exception.message end + def authenticate_user_or_client! + current_user || current_client || raise(Exception.new) + end + def current_client @current_client ||= identify_client end @@ -15,7 +19,7 @@ class ApplicationController < ActionController::Base if current_user @current_ability ||= Ability.new(current_user) elsif current_client - @current_ability ||= ClientAbility.new(current_account) + @current_ability ||= ClientAbility.new(current_client) end end @@ -25,5 +29,4 @@ class ApplicationController < ActionController::Base key = request.headers["X-API-KEY"] Client.find_by key: key if key end - end diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 72128f6..7a53d30 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -1,4 +1,9 @@ class TransactionsController < ApplicationController + skip_before_filter :verify_authenticity_token, only: :create + + before_action :authenticate_user!, except: :create + before_action :authenticate_user_or_client!, only: :create + def index @transactions = Transaction.all end From 5d97041e296451fa504d3cb93f3a9544a37bc0f5 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 14:37:40 +0200 Subject: [PATCH 05/16] add transaction controller spec --- spec/controllers/transactions_controller_spec.rb | 16 ++++++++++++++++ spec/spec_helper.rb | 2 ++ 2 files changed, 18 insertions(+) diff --git a/spec/controllers/transactions_controller_spec.rb b/spec/controllers/transactions_controller_spec.rb index c95f401..7ba1232 100644 --- a/spec/controllers/transactions_controller_spec.rb +++ b/spec/controllers/transactions_controller_spec.rb @@ -1,5 +1,21 @@ require 'rails_helper' RSpec.describe TransactionsController, type: :controller do + describe "creating transaction" do + before :each do + @debtor = create(:user) + @creditor = create(:user) + sign_in @debtor + end + it "should create a valid transaction" do + expect do + put :create, { transaction: { + creditor: @creditor.name, + amount: 20, + message: "hoi" + }} + end.to change {Transaction.count}.by(1) + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 87ddb8c..fa3ad6a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,8 +17,10 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration require 'factory_girl' +require 'devise' RSpec.configure do |config| config.include FactoryGirl::Syntax::Methods + config.include Devise::TestHelpers, type: :controller # rspec-expectations config goes here. You can use an alternate # assertion/expectation library such as wrong or the stdlib/minitest # assertions if you prefer. From c20c30297b799015d003c9a7326bafa1024411db Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 14:59:13 +0200 Subject: [PATCH 06/16] Install simple form --- app/controllers/application_controller.rb | 11 +- config/initializers/simple_form.rb | 165 ++++++++++++++++++++ config/locales/simple_form.en.yml | 31 ++++ lib/templates/haml/scaffold/_form.html.haml | 10 ++ 4 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 config/initializers/simple_form.rb create mode 100644 config/locales/simple_form.en.yml create mode 100644 lib/templates/haml/scaffold/_form.html.haml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index deb151c..36957b0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -8,11 +8,11 @@ class ApplicationController < ActionController::Base end def authenticate_user_or_client! - current_user || current_client || raise(Exception.new) + current_user || current_client || head(:unauthorized) end def current_client - @current_client ||= identify_client + @current_client ||= Client.find_by key: request.headers["X-API-KEY"] end def current_ability @@ -22,11 +22,4 @@ class ApplicationController < ActionController::Base @current_ability ||= ClientAbility.new(current_client) end end - - private - - def identify_client - key = request.headers["X-API-KEY"] - Client.find_by key: key if key - end end diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb new file mode 100644 index 0000000..934487a --- /dev/null +++ b/config/initializers/simple_form.rb @@ -0,0 +1,165 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + # Wrappers are used by the form builder to generate a + # complete input. You can remove any component from the + # wrapper, change the order or even add your own to the + # stack. The options given below are used to wrap the + # whole input. + config.wrappers :default, class: :input, + hint_class: :field_with_hint, error_class: :field_with_errors do |b| + ## Extensions enabled by default + # Any of these extensions can be disabled for a + # given input by passing: `f.input EXTENSION_NAME => false`. + # You can make any of these extensions optional by + # renaming `b.use` to `b.optional`. + + # Determines whether to use HTML5 (:email, :url, ...) + # and required attributes + b.use :html5 + + # Calculates placeholders automatically from I18n + # You can also pass a string as f.input placeholder: "Placeholder" + b.use :placeholder + + ## Optional extensions + # They are disabled unless you pass `f.input EXTENSION_NAME => true` + # to the input. If so, they will retrieve the values from the model + # if any exists. If you want to enable any of those + # extensions by default, you can change `b.optional` to `b.use`. + + # Calculates maxlength from length validations for string inputs + b.optional :maxlength + + # Calculates pattern from format validations for string inputs + b.optional :pattern + + # Calculates min and max from length validations for numeric inputs + b.optional :min_max + + # Calculates readonly automatically from readonly attributes + b.optional :readonly + + ## Inputs + b.use :label_input + b.use :hint, wrap_with: { tag: :span, class: :hint } + b.use :error, wrap_with: { tag: :span, class: :error } + + ## full_messages_for + # If you want to display the full error message for the attribute, you can + # use the component :full_error, like: + # + # b.use :full_error, wrap_with: { tag: :span, class: :error } + end + + # The default wrapper to be used by the FormBuilder. + config.default_wrapper = :default + + # Define the way to render check boxes / radio buttons with labels. + # Defaults to :nested for bootstrap config. + # inline: input + label + # nested: label > input + config.boolean_style = :nested + + # Default class for buttons + config.button_class = 'btn' + + # Method used to tidy up errors. Specify any Rails Array method. + # :first lists the first message for each field. + # Use :to_sentence to list all errors for each field. + # config.error_method = :first + + # Default tag used for error notification helper. + config.error_notification_tag = :div + + # CSS class to add for error notification helper. + config.error_notification_class = 'error_notification' + + # ID to add for error notification helper. + # config.error_notification_id = nil + + # Series of attempts to detect a default label method for collection. + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] + + # Series of attempts to detect a default value method for collection. + # config.collection_value_methods = [ :id, :to_s ] + + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. + # config.collection_wrapper_tag = nil + + # You can define the class to use on all collection wrappers. Defaulting to none. + # config.collection_wrapper_class = nil + + # You can wrap each item in a collection of radio/check boxes with a tag, + # defaulting to :span. + # config.item_wrapper_tag = :span + + # You can define a class to use in all item wrappers. Defaulting to none. + # config.item_wrapper_class = nil + + # How the label text should be generated altogether with the required text. + # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" } + + # You can define the class to use on all labels. Default is nil. + # config.label_class = nil + + # You can define the default class to be used on forms. Can be overriden + # with `html: { :class }`. Defaulting to none. + # config.default_form_class = nil + + # You can define which elements should obtain additional classes + # config.generate_additional_classes_for = [:wrapper, :label, :input] + + # Whether attributes are required by default (or not). Default is true. + # config.required_by_default = true + + # Tell browsers whether to use the native HTML5 validations (novalidate form option). + # These validations are enabled in SimpleForm's internal config but disabled by default + # in this configuration, which is recommended due to some quirks from different browsers. + # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations, + # change this configuration to true. + config.browser_validations = false + + # Collection of methods to detect if a file type was given. + # config.file_methods = [ :mounted_as, :file?, :public_filename ] + + # Custom mappings for input types. This should be a hash containing a regexp + # to match as key, and the input type that will be used when the field name + # matches the regexp as value. + # config.input_mappings = { /count/ => :integer } + + # Custom wrappers for input types. This should be a hash containing an input + # type as key and the wrapper that will be used for all inputs with specified type. + # config.wrapper_mappings = { string: :prepend } + + # Namespaces where SimpleForm should look for custom input classes that + # override default inputs. + # config.custom_inputs_namespaces << "CustomInputs" + + # Default priority for time_zone inputs. + # config.time_zone_priority = nil + + # Default priority for country inputs. + # config.country_priority = nil + + # When false, do not use translations for labels. + # config.translate_labels = true + + # Automatically discover new inputs in Rails' autoload path. + # config.inputs_discovery = true + + # Cache SimpleForm inputs discovery + # config.cache_discovery = !Rails.env.development? + + # Default class for inputs + # config.input_class = nil + + # Define the default class of the input wrapper of the boolean input. + config.boolean_label_class = 'checkbox' + + # Defines if the default input wrapper class should be included in radio + # collection wrappers. + # config.include_default_input_wrapper_class = true + + # Defines which i18n scope will be used in Simple Form. + # config.i18n_scope = 'simple_form' +end diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml new file mode 100644 index 0000000..2374383 --- /dev/null +++ b/config/locales/simple_form.en.yml @@ -0,0 +1,31 @@ +en: + simple_form: + "yes": 'Yes' + "no": 'No' + required: + text: 'required' + mark: '*' + # You can uncomment the line below if you need to overwrite the whole required html. + # When using html, text and mark won't be used. + # html: '*' + error_notification: + default_message: "Please review the problems below:" + # Examples + # labels: + # defaults: + # password: 'Password' + # user: + # new: + # email: 'E-mail to sign in.' + # edit: + # email: 'E-mail.' + # hints: + # defaults: + # username: 'User name to sign in.' + # password: 'No special characters, please.' + # include_blanks: + # defaults: + # age: 'Rather not say' + # prompts: + # defaults: + # age: 'Select your age' diff --git a/lib/templates/haml/scaffold/_form.html.haml b/lib/templates/haml/scaffold/_form.html.haml new file mode 100644 index 0000000..ac3aa7b --- /dev/null +++ b/lib/templates/haml/scaffold/_form.html.haml @@ -0,0 +1,10 @@ += simple_form_for(@<%= singular_table_name %>) do |f| + = f.error_notification + + .form-inputs + <%- attributes.each do |attribute| -%> + = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> + <%- end -%> + + .form-actions + = f.button :submit From 484ecb5468538f39a0c4b94b9192f3f73b1cd3fc Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 15:07:14 +0200 Subject: [PATCH 07/16] add more transaction controller tests --- .../transactions_controller_spec.rb | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/spec/controllers/transactions_controller_spec.rb b/spec/controllers/transactions_controller_spec.rb index 7ba1232..fd1135d 100644 --- a/spec/controllers/transactions_controller_spec.rb +++ b/spec/controllers/transactions_controller_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'spec_helper' RSpec.describe TransactionsController, type: :controller do describe "creating transaction" do @@ -8,14 +9,36 @@ RSpec.describe TransactionsController, type: :controller do sign_in @debtor end - it "should create a valid transaction" do - expect do - put :create, { transaction: { + context "with valid attributes" do + before :each do + @attributes = { transaction: { creditor: @creditor.name, amount: 20, - message: "hoi" + message: 'hoi' }} - end.to change {Transaction.count}.by(1) + post :create, @attributes + @transaction = Transaction.last + end + + it "should create a new transaction" do + expect {post :create, @attributes}.to change {Transaction.count}.by(1) + end + + it "should set debtor" do + expect(@transaction.debtor).to eq(@debtor) + end + + it "should set amount" do + expect(@transaction.amount).to eq(20) + end + + it "should set creditor" do + expect(@transaction.creditor).to eq(@creditor) + end + + it "should set issuer" do + expect(@transaction.issuer).to eq(@debtor) + end end end end From 5b73f152637d7de10772d06b8426b80a42763ffe Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 15:13:50 +0200 Subject: [PATCH 08/16] remove sample contents from spec helpers --- spec/helpers/transactions_helper_spec.rb | 1 - spec/helpers/users_helper_spec.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/spec/helpers/transactions_helper_spec.rb b/spec/helpers/transactions_helper_spec.rb index f29b78f..48c6c73 100644 --- a/spec/helpers/transactions_helper_spec.rb +++ b/spec/helpers/transactions_helper_spec.rb @@ -11,5 +11,4 @@ require 'rails_helper' # end # end RSpec.describe TransactionsHelper, type: :helper do - pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index b2e3444..890768c 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -11,5 +11,4 @@ require 'rails_helper' # end # end RSpec.describe UsersHelper, type: :helper do - pending "add some examples to (or delete) #{__FILE__}" end From 028fc8c641cce61baeda8c79b187a3a7daae5e1e Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 15:21:08 +0200 Subject: [PATCH 09/16] test transaction controller with invalid requests --- .../transactions_controller_spec.rb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/controllers/transactions_controller_spec.rb b/spec/controllers/transactions_controller_spec.rb index fd1135d..07f353a 100644 --- a/spec/controllers/transactions_controller_spec.rb +++ b/spec/controllers/transactions_controller_spec.rb @@ -40,5 +40,26 @@ RSpec.describe TransactionsController, type: :controller do expect(@transaction.issuer).to eq(@debtor) end end + + context "with negative amount" do + it "should be refused" do + expect do + post :create, transaction: attributes_for(:transaction, amount: -20) + end.not_to change {Transaction.count} + end + end + + context "for other user" do + it "should be refused" do + expect do + post :create, transaction: { + debtor: @creditor, + creditor: @debtor, + amount: 10000000000000, + message: 'DIT IS OVERVAL' + } + end.not_to change {Transaction.count} + end + end end end From d4576f24539e2a8d62e3a48f9b8e3c7bd979e485 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 15:25:02 +0200 Subject: [PATCH 10/16] update params in transaction controller spec --- spec/controllers/transactions_controller_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/controllers/transactions_controller_spec.rb b/spec/controllers/transactions_controller_spec.rb index 07f353a..de39b7c 100644 --- a/spec/controllers/transactions_controller_spec.rb +++ b/spec/controllers/transactions_controller_spec.rb @@ -12,6 +12,7 @@ RSpec.describe TransactionsController, type: :controller do context "with valid attributes" do before :each do @attributes = { transaction: { + debtor: @debtor.name, creditor: @creditor.name, amount: 20, message: 'hoi' From 661728772fa3d520c1ee92744078098e3dae8665 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 15:31:23 +0200 Subject: [PATCH 11/16] add debtor input field for penning --- app/views/transactions/new.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index 35defe4..4e4f5da 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -1,6 +1,9 @@ = @transaction.errors.full_messages.join(", ") = simple_form_for @transaction do |f| - = f.hidden_field :debtor, value: current_user.name + - if current_user.penning + = f.collection_select :debtor, User.all, :name, :name, {}, { class: 'select2-selector' } + - else + = f.hidden_field :debtor, value: current_user.name = f.collection_select :creditor, User.all, :name, :name, {}, { class: 'select2-selector' } = f.input :amount = f.input :message, required: true From 44e83e2aba5db24c9f61f5d5ab7ceda206acc073 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 16:26:06 +0200 Subject: [PATCH 12/16] allow euros and cents in transaction params --- app/controllers/transactions_controller.rb | 10 ++++---- .../transactions_controller_spec.rb | 24 ++++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 7c1152f..394b608 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -34,12 +34,14 @@ class TransactionsController < ApplicationController def transaction_params t = params.require(:transaction) - .permit(:debtor, :creditor, :amount, :message) + .permit(:debtor, :creditor, :message, :euros, :cents) - t.update({ + { debtor: User.find_by(name: t[:debtor]) || User.zeus, creditor: User.find_by(name: t[:creditor]) || User.zeus, - issuer: current_client || current_user - }) + issuer: current_client || current_user, + amount: (t[:euros].to_f*100 + t[:cents].to_f).to_i, + message: t[:message] + } end end diff --git a/spec/controllers/transactions_controller_spec.rb b/spec/controllers/transactions_controller_spec.rb index de39b7c..19e3e6f 100644 --- a/spec/controllers/transactions_controller_spec.rb +++ b/spec/controllers/transactions_controller_spec.rb @@ -14,7 +14,7 @@ RSpec.describe TransactionsController, type: :controller do @attributes = { transaction: { debtor: @debtor.name, creditor: @creditor.name, - amount: 20, + cents: 70, message: 'hoi' }} post :create, @attributes @@ -30,7 +30,7 @@ RSpec.describe TransactionsController, type: :controller do end it "should set amount" do - expect(@transaction.amount).to eq(20) + expect(@transaction.amount).to eq(70) end it "should set creditor" do @@ -42,10 +42,22 @@ RSpec.describe TransactionsController, type: :controller do end end + context "with float euros" do + it "should set correct amount" do + post :create, transaction: { + debtor: @debtor.name, + creditor: @creditor.name, + euros: 10.5, + message: "Omdat je een leuke jongen bent!" + } + expect(Transaction.last.amount).to eq(1050) + end + end + context "with negative amount" do it "should be refused" do expect do - post :create, transaction: attributes_for(:transaction, amount: -20) + post :create, transaction: attributes_for(:transaction, cents: -20) end.not_to change {Transaction.count} end end @@ -54,9 +66,9 @@ RSpec.describe TransactionsController, type: :controller do it "should be refused" do expect do post :create, transaction: { - debtor: @creditor, - creditor: @debtor, - amount: 10000000000000, + debtor: @creditor.name, + creditor: @debtor.name, + euros: 10000000000000, message: 'DIT IS OVERVAL' } end.not_to change {Transaction.count} From e67a66095983de105ad8f01cdc0790d414293373 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 16:28:11 +0200 Subject: [PATCH 13/16] Made bank robbery spec amount fit in database --- spec/controllers/transactions_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/transactions_controller_spec.rb b/spec/controllers/transactions_controller_spec.rb index 19e3e6f..e96cc51 100644 --- a/spec/controllers/transactions_controller_spec.rb +++ b/spec/controllers/transactions_controller_spec.rb @@ -68,7 +68,7 @@ RSpec.describe TransactionsController, type: :controller do post :create, transaction: { debtor: @creditor.name, creditor: @debtor.name, - euros: 10000000000000, + euros: 10000000, message: 'DIT IS OVERVAL' } end.not_to change {Transaction.count} From 3a0d5f1017c4fa84d7e5ca5e68be62ba83698f70 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 16:51:41 +0200 Subject: [PATCH 14/16] add cancancan ability for creating transactions --- app/controllers/transactions_controller.rb | 1 + app/models/ability.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 394b608..7b5626d 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -1,4 +1,5 @@ class TransactionsController < ApplicationController + load_and_authorize_resource skip_before_filter :verify_authenticity_token, only: :create before_action :authenticate_user!, except: :create diff --git a/app/models/ability.rb b/app/models/ability.rb index f04be4f..30128c4 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -8,6 +8,7 @@ class Ability can :manage, :all else can :read, user, id: user.id + can :create, Transaction, debtor: user end end end From 21e6432b41ecc399593146b3f65b39115cb71d8c Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 16:56:55 +0200 Subject: [PATCH 15/16] fix ability when not logged in --- app/controllers/application_controller.rb | 8 +++----- app/models/ability.rb | 11 ++++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 36957b0..c7cc410 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -16,10 +16,8 @@ class ApplicationController < ActionController::Base end def current_ability - if current_user - @current_ability ||= Ability.new(current_user) - elsif current_client - @current_ability ||= ClientAbility.new(current_client) - end + @current_ability ||= + current_client.try { |c| ClientAbility.new(c) } || + Ability.new(current_user) end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 30128c4..c3a4c81 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -2,13 +2,10 @@ class Ability include CanCan::Ability def initialize(user) - user ||= User.new # guest user (not logged in) + return unless user - if user.penning? - can :manage, :all - else - can :read, user, id: user.id - can :create, Transaction, debtor: user - end + can :manage, :all if user.penning? + can :read, user, id: user.id + can :create, Transaction, debtor: user end end From 1d6ab0f6eb9193cb60a455a0ca285966594f6906 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 17:06:39 +0200 Subject: [PATCH 16/16] Add some styling --- app/assets/stylesheets/application.css | 3 ++ app/assets/stylesheets/forms.css.scss | 22 +++++++++++++ app/assets/stylesheets/purecss.css | 36 +++++++++++++++++++++ app/views/layouts/application.html.haml | 2 +- app/views/partials/_form_errors.html.haml | 10 ++++++ app/views/transactions/new.html.haml | 5 +-- config/initializers/simple_form.rb | 6 ++-- lib/templates/haml/scaffold/_form.html.haml | 2 +- 8 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 app/assets/stylesheets/forms.css.scss create mode 100644 app/views/partials/_form_errors.html.haml diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 788352b..b951e4c 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -16,3 +16,6 @@ *= require_self *= require purecss */ +body { + padding: 30px; +} diff --git a/app/assets/stylesheets/forms.css.scss b/app/assets/stylesheets/forms.css.scss new file mode 100644 index 0000000..5a6d32d --- /dev/null +++ b/app/assets/stylesheets/forms.css.scss @@ -0,0 +1,22 @@ +.error_panel { + margin-bottom: 1em; + border-radius: 3px; + border: 1px solid #ebccd1; + .error_header { + .error_title { + font-size: 16px; + margin-top: 0; + margin-bottom: 0; + } + padding: 10px 15px; + color: #a94442; + background-color: #f2dede; + } + .error_body { + padding: 15px; + ul { + margin-bottom: 0px; + margin-top: 0px; + } + } +} diff --git a/app/assets/stylesheets/purecss.css b/app/assets/stylesheets/purecss.css index a8615b6..f6647f5 100644 --- a/app/assets/stylesheets/purecss.css +++ b/app/assets/stylesheets/purecss.css @@ -7,3 +7,39 @@ =require purecss/menus =require purecss/tables */ + +/* Alerts */ +.pure-alert { + position: relative; + margin-bottom: 1em; + padding: 1em; + background: #ccc; + border-radius: 3px; +} + +.pure-alert label { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + white-space: nowrap; +} + +.pure-alert { + background-color: rgb(209, 235, 238); + color: rgb(102, 131, 145); +} +.pure-alert-error { + background-color: #D13C38; + color: #fff; +} + +.pure-alert-warning { + background-color: rgb(250, 191, 103); + color: rgb(151, 96, 13); +} + +.pure-alert-success { + background-color: rgb(83, 180, 79); + color: #fff; +} diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 20d7dea..716c9b4 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -8,6 +8,6 @@ = csrf_meta_tags %body - flash.each do |key, value| - .alert{ :class => "alert-#{key}" } + .pure-alert{ class: "pure-alert-#{key}" } = value = yield diff --git a/app/views/partials/_form_errors.html.haml b/app/views/partials/_form_errors.html.haml new file mode 100644 index 0000000..46a401d --- /dev/null +++ b/app/views/partials/_form_errors.html.haml @@ -0,0 +1,10 @@ +- if object.errors.any? + .error_panel + .error_header + %h3.error_title + This transaction could not be saved. + .error_body + %ul + - object.errors.full_messages.each do |tr| + %li + = tr diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index 35defe4..742a465 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -1,7 +1,8 @@ -= @transaction.errors.full_messages.join(", ") += render 'partials/form_errors', object: @transaction = simple_form_for @transaction do |f| = f.hidden_field :debtor, value: current_user.name = f.collection_select :creditor, User.all, :name, :name, {}, { class: 'select2-selector' } = f.input :amount = f.input :message, required: true - = f.submit "Send it!" + .pure-controls + = f.button :submit, "Send it!" diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index 934487a..bdf2171 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -5,7 +5,7 @@ SimpleForm.setup do |config| # wrapper, change the order or even add your own to the # stack. The options given below are used to wrap the # whole input. - config.wrappers :default, class: :input, + config.wrappers :default, class: "input pure-control-group", hint_class: :field_with_hint, error_class: :field_with_errors do |b| ## Extensions enabled by default # Any of these extensions can be disabled for a @@ -61,7 +61,7 @@ SimpleForm.setup do |config| config.boolean_style = :nested # Default class for buttons - config.button_class = 'btn' + config.button_class = 'pure-button pure-button-primary' # Method used to tidy up errors. Specify any Rails Array method. # :first lists the first message for each field. @@ -104,7 +104,7 @@ SimpleForm.setup do |config| # You can define the default class to be used on forms. Can be overriden # with `html: { :class }`. Defaulting to none. - # config.default_form_class = nil + config.default_form_class = "pure-form" # You can define which elements should obtain additional classes # config.generate_additional_classes_for = [:wrapper, :label, :input] diff --git a/lib/templates/haml/scaffold/_form.html.haml b/lib/templates/haml/scaffold/_form.html.haml index ac3aa7b..705b47a 100644 --- a/lib/templates/haml/scaffold/_form.html.haml +++ b/lib/templates/haml/scaffold/_form.html.haml @@ -6,5 +6,5 @@ = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> <%- end -%> - .form-actions + .pure-controlls = f.button :submit