From 321d0ea7166558b7cb94a908458749e6091a1fbe Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 11:24:45 +0200 Subject: [PATCH 01/32] Add ClientAbility --- Gemfile | 2 ++ Gemfile.lock | 4 ++++ app/controllers/application_controller.rb | 8 ++++++++ app/models/client_ability.rb | 8 ++++++++ app/views/transactions/new.html.haml | 6 +++--- 5 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 app/models/client_ability.rb diff --git a/Gemfile b/Gemfile index ab0fe33..85db2d0 100644 --- a/Gemfile +++ b/Gemfile @@ -82,3 +82,5 @@ group :production do end gem 'high_voltage', '~> 2.4.0' + +gem 'simple_form' diff --git a/Gemfile.lock b/Gemfile.lock index 4ffca3f..3a644d4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -217,6 +217,9 @@ GEM select2-rails (3.5.9.3) thor (~> 0.14) sexp_processor (4.6.0) + simple_form (3.1.1) + actionpack (~> 4.0) + activemodel (~> 4.0) spring (1.3.6) sprockets (3.3.4) rack (~> 1.0) @@ -276,6 +279,7 @@ DEPENDENCIES sass-rails (~> 5.0) sdoc (~> 0.4.0) select2-rails + simple_form spring sqlite3 turbolinks diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3ea39cf..6ee6fac 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,4 +6,12 @@ class ApplicationController < ActionController::Base rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, alert: exception.message end + + def current_ability + if current_user + @current_ability ||= Ability.new(current_user) + elsif current_client + @current_ability ||= ClientAbility.new(current_account) + end + end end diff --git a/app/models/client_ability.rb b/app/models/client_ability.rb new file mode 100644 index 0000000..1f804eb --- /dev/null +++ b/app/models/client_ability.rb @@ -0,0 +1,8 @@ +class Ability + include CanCan::Ability + + def initialize(client) + client ||= Client.new # guest user (not logged in) + can :manage, :all + end +end diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index d65c6d5..68d35f0 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -1,6 +1,6 @@ = @transaction.errors.full_messages.join(", ") -= form_for @transaction do |f| += simple_form_for @transaction do |f| = f.collection_select :creditor_id, User.all, :id, :name, {}, { class: 'select2-selector' } - = f.number_field :amount - = f.text_field :message, required: true + = f.input :amount + = f.input :message, required: true = f.submit "Send it!" From 7423cb4dda270497a097690daaad385a7b0df2a4 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 11:31:34 +0200 Subject: [PATCH 02/32] Add client identification methods --- app/controllers/application_controller.rb | 11 +++++++++++ app/controllers/transactions_controller.rb | 4 +++- app/datatables/transaction_datatable.rb | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3ea39cf..16a8765 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,4 +6,15 @@ class ApplicationController < ActionController::Base rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, alert: exception.message end + + def current_client + @current_client ||= identify_client + end + + private + + def identify_client + 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 ce60de4..5257ce8 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -1,4 +1,5 @@ class TransactionsController < ApplicationController + skip_before_filter :verify_authenticity_token, :only => :create def index @transactions = Transaction.all @@ -9,7 +10,8 @@ class TransactionsController < ApplicationController end def create - @transaction = current_user.outgoing_transactions.build transaction_params.merge(origin: I18n.t('origin.created_by_user')) + @transaction = current_user.outgoing_transactions.build( + transaction_params.merge(origin: I18n.t('origin.created_by_user')) if @transaction.save redirect_to current_user diff --git a/app/datatables/transaction_datatable.rb b/app/datatables/transaction_datatable.rb index 69ebfa3..3220a0d 100644 --- a/app/datatables/transaction_datatable.rb +++ b/app/datatables/transaction_datatable.rb @@ -2,7 +2,7 @@ class TransactionDatatable < AjaxDatatablesRails::Base include TransactionsHelper def sortable_columns - @sortable_columns ||= ['Transaction.amount'] + @sortable_columns ||= ['Transaction.created_at'] end def searchable_columns From 738283ddddf63bdc0328455b6d07e117ea9c1674 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 11:53:30 +0200 Subject: [PATCH 03/32] Change skip_authenticity_token by :null_session --- app/controllers/application_controller.rb | 2 +- app/controllers/transactions_controller.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6ee6fac..3198b31 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,7 +1,7 @@ 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: :exception + protect_from_forgery with: :null_session rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, alert: exception.message diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index ce60de4..01c3f0a 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -1,5 +1,4 @@ class TransactionsController < ApplicationController - def index @transactions = Transaction.all end From dbc533a1cb101b6c7f642ac944402b5781a0ef28 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 11:56:13 +0200 Subject: [PATCH 04/32] 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 87c2994cf033decd05b461e9148ceb942b85dee5 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 12:49:24 +0200 Subject: [PATCH 05/32] add issuer to transaction --- app/models/client.rb | 5 +---- app/models/transaction.rb | 9 ++++----- app/models/user.rb | 2 ++ db/migrate/20150908091546_create_transactions.rb | 2 +- db/schema.rb | 4 +++- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/models/client.rb b/app/models/client.rb index bb674c5..842921b 100644 --- a/app/models/client.rb +++ b/app/models/client.rb @@ -10,15 +10,12 @@ # class Client < ActiveRecord::Base + has_many :issued_transactions, as: :issuer, class_name: 'Transaction' before_create :generate_key validates :name, presence: true, uniqueness: true validates :key, presence: true, uniqueness: true - def transactions - Transaction.where(origin: name) - end - private def generate_key self.key = SecureRandom.base64(16) unless self.key diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 2e6f346..cadbe06 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -15,6 +15,7 @@ class Transaction < ActiveRecord::Base belongs_to :debtor, class_name: 'User' belongs_to :creditor, class_name: 'User' + belongs_to :issuer, polymorphic: true after_save :recalculate_balances after_destroy :recalculate_balances @@ -22,10 +23,6 @@ class Transaction < ActiveRecord::Base validates :amount, numericality: { greater_than: 0 } validate :different_debtor_creditor - def client - Client.find_by name: origin - end - private def recalculate_balances @@ -34,6 +31,8 @@ class Transaction < ActiveRecord::Base end def different_debtor_creditor - self.errors.add :base, "Can't write money to yourself" if self.debtor == self.creditor + if self.debtor == self.creditor + self.errors.add :base, "Can't write money to yourself" + end end end diff --git a/app/models/user.rb b/app/models/user.rb index 8a318e9..c5886cf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -17,6 +17,8 @@ class User < ActiveRecord::Base has_many :outgoing_transactions, class_name: 'Transaction', foreign_key: 'debtor_id' + has_many :issued_transactions, as: :issuer, class_name: 'Transaction' + validates :name, presence: true, uniqueness: true def transactions diff --git a/db/migrate/20150908091546_create_transactions.rb b/db/migrate/20150908091546_create_transactions.rb index dda51f7..d1e83c4 100644 --- a/db/migrate/20150908091546_create_transactions.rb +++ b/db/migrate/20150908091546_create_transactions.rb @@ -3,8 +3,8 @@ class CreateTransactions < ActiveRecord::Migration create_table :transactions do |t| t.references :debtor, index: true, null: false t.references :creditor, index: true, null: false + t.references :issuer, polymorphic: true, index: true, null: false t.integer :amount, null: false, default: 0 - t.string :origin, null: false t.string :message t.timestamps null: false diff --git a/db/schema.rb b/db/schema.rb index b4292bf..f6bf104 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -26,8 +26,9 @@ ActiveRecord::Schema.define(version: 20150908092731) do create_table "transactions", force: :cascade do |t| t.integer "debtor_id", null: false t.integer "creditor_id", null: false + t.integer "issuer_id", null: false + t.string "issuer_type", null: false t.integer "amount", default: 0, null: false - t.string "origin", null: false t.string "message" t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -35,6 +36,7 @@ ActiveRecord::Schema.define(version: 20150908092731) do add_index "transactions", ["creditor_id"], name: "index_transactions_on_creditor_id" add_index "transactions", ["debtor_id"], name: "index_transactions_on_debtor_id" + add_index "transactions", ["issuer_type", "issuer_id"], name: "index_transactions_on_issuer_type_and_issuer_id" create_table "users", force: :cascade do |t| t.string "name" From 95f4c54780260d03f107a4c6d4d55a173de156cf Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 12:50:39 +0200 Subject: [PATCH 06/32] re-annotate --- app/controllers/transactions_controller.rb | 2 +- app/models/transaction.rb | 3 ++- spec/factories/transactions.rb | 3 ++- spec/models/transaction_spec.rb | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/controllers/transactions_controller.rb b/app/controllers/transactions_controller.rb index 5257ce8..7e971c8 100644 --- a/app/controllers/transactions_controller.rb +++ b/app/controllers/transactions_controller.rb @@ -11,7 +11,7 @@ class TransactionsController < ApplicationController def create @transaction = current_user.outgoing_transactions.build( - transaction_params.merge(origin: I18n.t('origin.created_by_user')) + transaction_params.merge(origin: I18n.t('origin.created_by_user'))) if @transaction.save redirect_to current_user diff --git a/app/models/transaction.rb b/app/models/transaction.rb index cadbe06..fe56854 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -5,8 +5,9 @@ # id :integer not null, primary key # debtor_id :integer not null # creditor_id :integer not null +# issuer_id :integer not null +# issuer_type :string not null # amount :integer default(0), not null -# origin :string not null # message :string # created_at :datetime not null # updated_at :datetime not null diff --git a/spec/factories/transactions.rb b/spec/factories/transactions.rb index d0eea9f..21fe059 100644 --- a/spec/factories/transactions.rb +++ b/spec/factories/transactions.rb @@ -5,8 +5,9 @@ # id :integer not null, primary key # debtor_id :integer not null # creditor_id :integer not null +# issuer_id :integer not null +# issuer_type :string not null # amount :integer default(0), not null -# origin :string not null # message :string # created_at :datetime not null # updated_at :datetime not null diff --git a/spec/models/transaction_spec.rb b/spec/models/transaction_spec.rb index 805bf63..d05aaf8 100644 --- a/spec/models/transaction_spec.rb +++ b/spec/models/transaction_spec.rb @@ -5,8 +5,9 @@ # id :integer not null, primary key # debtor_id :integer not null # creditor_id :integer not null +# issuer_id :integer not null +# issuer_type :string not null # amount :integer default(0), not null -# origin :string not null # message :string # created_at :datetime not null # updated_at :datetime not null From c2ec8ba51b23e117e14502c1a29415776653fe32 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 12:52:32 +0200 Subject: [PATCH 07/32] update transaction factory --- spec/factories/transactions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/factories/transactions.rb b/spec/factories/transactions.rb index 21fe059..716b419 100644 --- a/spec/factories/transactions.rb +++ b/spec/factories/transactions.rb @@ -17,8 +17,8 @@ FactoryGirl.define do factory :transaction do association :debtor, factory: :user association :creditor, factory: :user + issuer { debtor } amount { rand(100) } - origin 'FactoryGirl' message { Faker::Lorem.sentence } end end From 6229556e38c5c45cfe054f137865cde45f884649 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 12:58:44 +0200 Subject: [PATCH 08/32] 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 09/32] 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 83f4cfecef6ea63fae28204714e5d7be7782d5f8 Mon Sep 17 00:00:00 2001 From: Tom Naessens Date: Wed, 9 Sep 2015 13:37:10 +0200 Subject: [PATCH 10/32] Add errbit integration --- Gemfile | 3 +++ Gemfile.lock | 4 ++++ config/initializers/errbit.rb | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100644 config/initializers/errbit.rb diff --git a/Gemfile b/Gemfile index 85db2d0..f1dfbf1 100644 --- a/Gemfile +++ b/Gemfile @@ -84,3 +84,6 @@ end gem 'high_voltage', '~> 2.4.0' gem 'simple_form' + +# Errors on errbit +gem 'airbrake' diff --git a/Gemfile.lock b/Gemfile.lock index 3a644d4..6261c2e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,6 +36,9 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + airbrake (4.3.1) + builder + multi_json ajax-datatables-rails (0.3.1) railties (>= 3.1) annotate (2.6.10) @@ -254,6 +257,7 @@ PLATFORMS ruby DEPENDENCIES + airbrake ajax-datatables-rails annotate byebug diff --git a/config/initializers/errbit.rb b/config/initializers/errbit.rb new file mode 100644 index 0000000..00712ab --- /dev/null +++ b/config/initializers/errbit.rb @@ -0,0 +1,6 @@ +Airbrake.configure do |config| + config.api_key = '066f6146dde14038b5ab69a2f680cd4a' + config.host = 'zeus-errbit.ilion.me' + config.port = 80 + config.secure = config.port == 443 +end From 20c3bf2f31550f64080d50af411328a9dd054792 Mon Sep 17 00:00:00 2001 From: Tom Naessens Date: Wed, 9 Sep 2015 14:00:20 +0200 Subject: [PATCH 11/32] Add travis and coveralls integration --- .gitignore | 1 + .travis.yml | 14 ++++++++++++++ Gemfile | 4 ++++ Gemfile.lock | 28 ++++++++++++++++++++++++++++ spec/spec_helper.rb | 4 ++++ 5 files changed, 51 insertions(+) create mode 100644 .travis.yml diff --git a/.gitignore b/.gitignore index 050c9d9..354eb8e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ /log/* !/log/.keep /tmp +coverage/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2c05534 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: ruby +sudo: false +rvm: +- 2.2.2 +before_script: +- RAILS_ENV=test bundle exec rspec spec +notifications: + email: + recipients: + - tab@zeus.ugent.be + on_success: never + on_failure: change + slack: + secure: G2bPwlS5GR3EkCqdeeE5usS0k/JKEErShIED0M1+/IKhTf6Yn7r4S4KZARndIG6B2y4nZ5EF0ONbdqZkOTwj6QaPv+2NNqmh2CK9Q6BqEN/5fyx5zfVUjCJNRnXPVWuyhooYaKbaDO23KtwvsW0ZpFjS+pZzTZNEWI4UOo2ojIEW1jZfFHYJ0U/W6HX8j65VwWP0/I7od7XBs7UgNavndtJV8sQyRXCvlGfkkYe8MgxG/6QdCV9z46i+IbfPkvETMFIhrx0CpohV00TsVOmuPWpqbi86YV5EzdSWImdc3Dyei+SG6xSi3mfaocEjEvb3btHYBYRwCzBU+ObYLHmz7FdG3Vqzyhqf9c8hzuAAUduXYX9W1sEHi6nfwQqquuibXhptpyS/Np7wqSGhqdbdmTbgWpdAbTEwg9i9ZGgV+YpGhYMypA2yGA/7x+akoHJoKEL7qGsbncifjJlOqYoAVVVj67PFIszyDQiGBlMFddn233oqT+3odyiJGWLaXZY+7Ew1sE1BX5GpFxO71EwMZMxhm0FDtittpkK/uhX05d4DvPElxUmIHWEf5UMvQxjrqpSuYjXLM7xEVn2zktZ1Skk6X4wGU6bSV2Jy+JpzVvkVBXzTf9JMZSMbDKwypwcUjXBn+7/frv5QXkCJrKsRIPm8Ox69YNsDuNz/EWpcQsI= diff --git a/Gemfile b/Gemfile index f1dfbf1..62a60d5 100644 --- a/Gemfile +++ b/Gemfile @@ -77,6 +77,10 @@ group :development do gem 'capistrano-passenger' end +group :test do + gem 'coveralls', require: false +end + group :production do gem 'mysql2', '~> 0.3.0' end diff --git a/Gemfile.lock b/Gemfile.lock index 6261c2e..73ca1ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,6 +74,12 @@ GEM execjs coffee-script-source (1.9.1.1) colorize (0.7.7) + coveralls (0.8.2) + json (~> 1.8) + rest-client (>= 1.6.8, < 2) + simplecov (~> 0.10.0) + term-ansicolor (~> 1.3) + thor (~> 0.19.1) debug_inspector (0.0.2) devise (3.5.2) bcrypt (~> 3.0) @@ -83,6 +89,9 @@ GEM thread_safe (~> 0.1) warden (~> 1.2.3) diff-lcs (1.2.5) + docile (1.1.5) + domain_name (0.5.24) + unf (>= 0.0.5, < 1.0.0) erubis (2.7.0) execjs (2.6.0) factory_girl (4.5.0) @@ -111,6 +120,8 @@ GEM haml (~> 4.0.0) nokogiri (~> 1.6.0) ruby_parser (~> 3.5) + http-cookie (1.0.2) + domain_name (~> 0.5) i18n (0.7.0) jbuilder (2.3.1) activesupport (>= 3.0.0, < 5) @@ -140,6 +151,7 @@ GEM net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (2.9.2) + netrc (0.10.3) nokogiri (1.6.6.2) mini_portile (~> 0.6.0) oauth2 (1.0.0) @@ -188,6 +200,10 @@ GEM rdoc (4.2.0) responders (2.1.0) railties (>= 4.2.0, < 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.3.2) rspec-support (~> 3.3.0) rspec-expectations (3.3.1) @@ -223,6 +239,11 @@ GEM simple_form (3.1.1) actionpack (~> 4.0) activemodel (~> 4.0) + simplecov (0.10.0) + docile (~> 1.1.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) spring (1.3.6) sprockets (3.3.4) rack (~> 1.0) @@ -235,9 +256,12 @@ GEM colorize (>= 0.7.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) + term-ansicolor (1.3.2) + tins (~> 1.0) thor (0.19.1) thread_safe (0.3.5) tilt (2.0.1) + tins (1.6.0) turbolinks (2.5.3) coffee-rails tzinfo (1.2.2) @@ -245,6 +269,9 @@ GEM uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.1) warden (1.2.3) rack (>= 1.0) web-console (2.2.1) @@ -267,6 +294,7 @@ DEPENDENCIES capistrano-rails (~> 1.1) capistrano-rbenv coffee-rails (~> 4.1.0) + coveralls devise factory_girl_rails faker diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 87ddb8c..cc47a08 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,7 @@ +# Coveralls integrations +require 'coveralls' +Coveralls.wear!('rails') + # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause From 1c9ead7249a42c156a5f19bca0693e8079e3ffd5 Mon Sep 17 00:00:00 2001 From: Tom Naessens Date: Wed, 9 Sep 2015 14:08:30 +0200 Subject: [PATCH 12/32] Add badges to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a0d561..8f302a1 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Tab +# Tab [![Analytics](https://ga-beacon.appspot.com/UA-25444917-6/ZeusWPI/Tab/README.md?pixel)](https://github.com/igrigorik/ga-beacon) [![Coverage Status](https://coveralls.io/repos/ZeusWPI/Tab/badge.png?branch=master)](https://coveralls.io/r/ZeusWPI/Tab) [![Build Status](https://travis-ci.org/ZeusWPI/Tab.png?branch=master)](https://travis-ci.org/ZeusWPI/Tab) From d948071e49a6b3aef16cd7a43ec1b2fbe418ce70 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 14:08:40 +0200 Subject: [PATCH 13/32] 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 0483ad2e0cf8bc04758f9bd6d2bbb99678065872 Mon Sep 17 00:00:00 2001 From: Tom Naessens Date: Wed, 9 Sep 2015 14:10:00 +0200 Subject: [PATCH 14/32] Add another badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f302a1..c995018 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Tab [![Analytics](https://ga-beacon.appspot.com/UA-25444917-6/ZeusWPI/Tab/README.md?pixel)](https://github.com/igrigorik/ga-beacon) [![Coverage Status](https://coveralls.io/repos/ZeusWPI/Tab/badge.png?branch=master)](https://coveralls.io/r/ZeusWPI/Tab) [![Build Status](https://travis-ci.org/ZeusWPI/Tab.png?branch=master)](https://travis-ci.org/ZeusWPI/Tab) +# Tab [![Code Climate](https://codeclimate.com/github/ZeusWPI/Tab/badges/gpa.svg)](https://codeclimate.com/github/ZeusWPI/Tab) [![Travis CI](https://travis-ci.org/ZeusWPI/Tab.svg)](https://travis-ci.org/ZeusWPI/Tab) [![Coverage Status](https://coveralls.io/repos/ZeusWPI/Tab/badge.svg?branch=master&service=github)](https://coveralls.io/github/ZeusWPI/Tab?branch=master) From 971b67aa2df5b764e12e9cde31d51a26f1328e0c Mon Sep 17 00:00:00 2001 From: Tom Naessens Date: Wed, 9 Sep 2015 14:20:29 +0200 Subject: [PATCH 15/32] Use new travis infrastructure, let travis use .ruby-version --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c05534..37397b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: ruby sudo: false -rvm: -- 2.2.2 + before_script: -- RAILS_ENV=test bundle exec rspec spec + - RAILS_ENV=test bundle exec rspec spec + notifications: email: recipients: - - tab@zeus.ugent.be + - tab@zeus.ugent.be on_success: never on_failure: change slack: From ae676023685874bdb5709e30259b677ef64f95c0 Mon Sep 17 00:00:00 2001 From: Tom Naessens Date: Wed, 9 Sep 2015 14:24:41 +0200 Subject: [PATCH 16/32] Fix coveralls badge, add url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c995018..5017edd 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Tab [![Code Climate](https://codeclimate.com/github/ZeusWPI/Tab/badges/gpa.svg)](https://codeclimate.com/github/ZeusWPI/Tab) [![Travis CI](https://travis-ci.org/ZeusWPI/Tab.svg)](https://travis-ci.org/ZeusWPI/Tab) [![Coverage Status](https://coveralls.io/repos/ZeusWPI/Tab/badge.svg?branch=master&service=github)](https://coveralls.io/github/ZeusWPI/Tab?branch=master) +# [Tab](https://zeus.ugent.be/tab) [![Analytics](https://ga-beacon.appspot.com/UA-25444917-6/ZeusWPI/Tab/README.md?pixel)](https://github.com/igrigorik/ga-beacon) [![Code Climate](https://codeclimate.com/github/ZeusWPI/Tab/badges/gpa.svg)](https://codeclimate.com/github/ZeusWPI/Tab) [![Coverage Status](https://coveralls.io/repos/ZeusWPI/Tab/badge.svg?branch=master&service=github)](https://coveralls.io/github/ZeusWPI/Tab?branch=master) [![Build Status](https://travis-ci.org/ZeusWPI/Tab.png?branch=master)](https://travis-ci.org/ZeusWPI/Tab) From 5d97041e296451fa504d3cb93f3a9544a37bc0f5 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 14:37:40 +0200 Subject: [PATCH 17/32] 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 18/32] 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 19/32] 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 20/32] 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 21/32] 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 22/32] 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 23/32] 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 24/32] 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 25/32] 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 26/32] 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 27/32] 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 28/32] 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 From f217f07a8323f6822442de77e159e840daacae0e Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 17:34:49 +0200 Subject: [PATCH 29/32] Add some links on application view --- app/views/layouts/application.html.haml | 13 ++++++++++--- app/views/partials/_flash.html.haml | 3 +++ app/views/transactions/new.html.haml | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 app/views/partials/_flash.html.haml diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 716c9b4..18bdf90 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -7,7 +7,14 @@ = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags %body - - flash.each do |key, value| - .pure-alert{ class: "pure-alert-#{key}" } - = value + .pure-menu.pure-menu-horizontal + %ul.pure-menu-list + - if current_user + %li.pure-menu-item + = link_to current_user.name.capitalize, current_user, class: "pure-menu-link" + %li.pure-menu-item + = link_to "New Transaction", new_transaction_path, class: "pure-menu-link" + - else + = link_to "Sign in", user_omniauth_authorize_path(:zeuswpi), class: "pure-menu-link" unless current_user + = render 'partials/flash' = yield diff --git a/app/views/partials/_flash.html.haml b/app/views/partials/_flash.html.haml new file mode 100644 index 0000000..f953346 --- /dev/null +++ b/app/views/partials/_flash.html.haml @@ -0,0 +1,3 @@ +- flash.each do |key, value| + .pure-alert{ class: "pure-alert-#{key}" } + = value diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index 91f158f..c335b4b 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -5,7 +5,7 @@ - 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 :cents, input_html: { value: @transaction.amount } = f.input :message, required: true .pure-controls = f.button :submit, "Send it!" From 1ac1d54c268f5214e0d5a99ffb45f1b291a9d48d Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Wed, 9 Sep 2015 17:37:03 +0200 Subject: [PATCH 30/32] add transaction default debtor and creditor --- app/views/transactions/new.html.haml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index 4e4f5da..246edef 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -1,10 +1,12 @@ = @transaction.errors.full_messages.join(", ") = simple_form_for @transaction do |f| - if current_user.penning - = f.collection_select :debtor, User.all, :name, :name, {}, { class: 'select2-selector' } + = f.collection_select :debtor, User.all, :name, :name, + {selected: current_user.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.collection_select :creditor, User.all, :name, :name, + {selected: User.zeus.name}, { class: 'select2-selector' } = f.input :amount = f.input :message, required: true = f.submit "Send it!" From a1b3326b73f60ac0d06fa2fe4472708dc275b187 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 17:43:50 +0200 Subject: [PATCH 31/32] Add pure css grids --- app/views/layouts/application.html.haml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 18bdf90..0f335a3 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -7,14 +7,17 @@ = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags %body - .pure-menu.pure-menu-horizontal - %ul.pure-menu-list - - if current_user - %li.pure-menu-item - = link_to current_user.name.capitalize, current_user, class: "pure-menu-link" - %li.pure-menu-item - = link_to "New Transaction", new_transaction_path, class: "pure-menu-link" - - else - = link_to "Sign in", user_omniauth_authorize_path(:zeuswpi), class: "pure-menu-link" unless current_user - = render 'partials/flash' - = yield + .pure-g + .pure-u-1 + .pure-menu.pure-menu-horizontal + %ul.pure-menu-list + - if current_user + %li.pure-menu-item + = link_to current_user.name.capitalize, current_user, class: "pure-menu-link" + %li.pure-menu-item + = link_to "New Transaction", new_transaction_path, class: "pure-menu-link" + - else + = link_to "Sign in", user_omniauth_authorize_path(:zeuswpi), class: "pure-menu-link" unless current_user + .pure-u-1 + = render 'partials/flash' + = yield From 86b751fb8161079047bd2248e5e58b1faaca3301 Mon Sep 17 00:00:00 2001 From: benji Date: Wed, 9 Sep 2015 17:56:27 +0200 Subject: [PATCH 32/32] Keep selected value in select2 when creating transaction fails --- app/views/transactions/new.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/transactions/new.html.haml b/app/views/transactions/new.html.haml index 949c6e6..bd46894 100644 --- a/app/views/transactions/new.html.haml +++ b/app/views/transactions/new.html.haml @@ -2,11 +2,11 @@ = simple_form_for @transaction do |f| - if current_user.penning = f.collection_select :debtor, User.all, :name, :name, - {selected: current_user.name}, { class: 'select2-selector'} + { selected: @transaction.debtor.try(:name) || current_user.name }, { class: 'select2-selector'} - else = f.hidden_field :debtor, value: current_user.name = f.collection_select :creditor, User.all, :name, :name, - {selected: User.zeus.name}, { class: 'select2-selector' } + { selected: @transaction.creditor.try(:name) || User.zeus.name }, { class: 'select2-selector' } = f.input :message, required: true = f.input :euros, input_html: { value: @transaction.amount/100} .pure-controls