This commit is contained in:
benji 2015-11-05 19:52:41 +01:00
commit da8ac14623
18 changed files with 292 additions and 103 deletions

View file

@ -1,6 +1,7 @@
class BarcodesController < ApplicationController class BarcodesController < ApplicationController
load_and_authorize_resource :product, only: :create load_and_authorize_resource :product, only: :create
load_and_authorize_resource :barcode, through: :product, shallow: true load_and_authorize_resource :barcode, through: :product, shallow: true
def create def create
@barcode.save @barcode.save
redirect_to barcode_products_path, notice: "Barcode successfully linked!" redirect_to barcode_products_path, notice: "Barcode successfully linked!"

View file

@ -31,6 +31,6 @@ class OrdersController < ApplicationController
private private
def order_params def order_params
params.require(:order).permit(order_items_attributes: [:count, :price, product_attributes: [:id]]) params.require(:order).permit(order_items_attributes: [:count, :price, :product_id])
end end
end end

View file

@ -29,21 +29,9 @@ class UsersController < ApplicationController
order = @user.orders.build order = @user.orders.build
order.order_items.build(count: 1, product: @user.dagschotel) order.order_items.build(count: 1, product: @user.dagschotel)
if order.save if order.save
respond_to do |format| render json: { message: "Quick pay succeeded for #{@user.name}." }, status: :ok
format.js { render json: { message: "Quick pay succeeded for #{@user.name}." }, status: :ok }
format.html {
flash[:success] = "Quick pay succeeded."
redirect_to root_path
}
end
else else
respond_to do |format| head :unprocessable_entity
format.js { head :unprocessable_entity }
format.html {
flash[:error] = order.errors.full_messages.first
redirect_to root_path
}
end
end end
end end

View file

@ -4,16 +4,25 @@ class Ability
def initialize(user) def initialize(user)
return unless user return unless user
can :read, Barcode initialize_admin if user.admin?
initialize_koelkast if user.koelkast?
initialize_user(user)
if user.admin? can :read, Barcode
end
def initialize_admin
can :manage, :all can :manage, :all
elsif user.koelkast? end
def initialize_koelkast
can :manage, Order do |order| can :manage, Order do |order|
!order.try(:user).try(:private) !order.try(:user).try(:private)
end end
can :quickpay, User can :quickpay, User
else end
def initialize_user(user)
can :read, :all can :read, :all
can :manage, User, id: user.id can :manage, User, id: user.id
can :create, Order do |order| can :create, Order do |order|
@ -23,5 +32,4 @@ class Ability
order.try(:user) == user && order.deletable order.try(:user) == user && order.deletable
end end
end end
end
end end

View file

@ -15,6 +15,6 @@ class Barcode < ActiveRecord::Base
belongs_to :product belongs_to :product
# validates :product, presence: true validates :product, presence: true
validates :code, presence: true, uniqueness: true validates :code, presence: true, uniqueness: true
end end

View file

@ -20,17 +20,6 @@ class OrderItem < ActiveRecord::Base
before_destroy :put_back_in_stock! before_destroy :put_back_in_stock!
after_create :remove_from_stock! after_create :remove_from_stock!
accepts_nested_attributes_for :product
def product_attributes=(attributes)
self.product = OrderItem.products.select{ |p| p.id == attributes[:id].to_i }.first
super
end
def self.products
@products || Product.all
end
private private
def remove_from_stock! def remove_from_stock!

View file

@ -19,8 +19,7 @@
%tr.order_item_wrapper{ data: { product: ff.object.product.id, price: ff.object.product.price_cents } } %tr.order_item_wrapper{ data: { product: ff.object.product.id, price: ff.object.product.price_cents } }
%td %td
= ff.number_field :count = ff.number_field :count
= ff.fields_for :product do |fff| = ff.hidden_field :product_id
/ Needed for haml
%td %td
x x
%td %td

View file

@ -0,0 +1,5 @@
class AddDefaultFalseToAdminUsers < ActiveRecord::Migration
def change
change_column :users, :admin, :boolean, default: false
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150919091214) do ActiveRecord::Schema.define(version: 20151028223229) do
create_table "barcodes", force: :cascade do |t| create_table "barcodes", force: :cascade do |t|
t.integer "product_id" t.integer "product_id"
@ -75,7 +75,7 @@ ActiveRecord::Schema.define(version: 20150919091214) do
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.datetime "remember_created_at" t.datetime "remember_created_at"
t.boolean "admin" t.boolean "admin", default: false
t.integer "dagschotel_id" t.integer "dagschotel_id"
t.string "avatar_file_name" t.string "avatar_file_name"
t.string "avatar_content_type" t.string "avatar_content_type"

View file

@ -1,7 +1,7 @@
# from_barcode_products POST /products/barcode(.:format) products#from_barcode # barcode_products GET /products/barcode(.:format) products#barcode
# load_barcode_products POST /products/barcode(.:format) products#load_barcode
# products GET /products(.:format) products#index # products GET /products(.:format) products#index
# POST /products(.:format) products#create # POST /products(.:format) products#create
# new_product GET /products/new(.:format) products#new
# edit_product GET /products/:id/edit(.:format) products#edit # edit_product GET /products/:id/edit(.:format) products#edit
# product PATCH /products/:id(.:format) products#update # product PATCH /products/:id(.:format) products#update
# PUT /products/:id(.:format) products#update # PUT /products/:id(.:format) products#update
@ -13,24 +13,6 @@ describe ProductsController, type: :controller do
sign_in @admin sign_in @admin
end end
#########
# NEW #
#########
describe 'GET new' do
it 'should render the form' do
get :new
expect(response).to render_template(:new)
expect(response).to have_http_status(200)
end
it 'should initialize a new product' do
get :new
expect(assigns(:product).class).to eq(Product)
expect(assigns(:product)).to_not be_persisted
end
end
########## ##########
# POST # # POST #
########## ##########
@ -43,7 +25,7 @@ describe ProductsController, type: :controller do
}.to change{ Product.count }.by(1) }.to change{ Product.count }.by(1)
end end
it 'should redirect to index page' do it 'should redirect to barcode page' do
post :create, product: attributes_for(:product) post :create, product: attributes_for(:product)
expect(response).to redirect_to action: :barcode expect(response).to redirect_to action: :barcode
end end
@ -82,16 +64,18 @@ describe ProductsController, type: :controller do
describe 'GET edit' do describe 'GET edit' do
before :each do before :each do
@product = create :product @product = create :product
get :edit, id: @product
end end
it 'should render the correct form' do it 'should be successful' do
get :edit, id: @product
expect(response).to render_template(:edit)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
it 'should render the correct form' do
expect(response).to render_template(:edit)
end
it 'should load the correct product' do it 'should load the correct product' do
get :edit, id: @product
expect(assigns :product).to eq(@product) expect(assigns :product).to eq(@product)
end end
end end
@ -106,7 +90,7 @@ describe ProductsController, type: :controller do
end end
it 'loads right product' do it 'loads right product' do
put :edit, id: @product, product: attributes_for(:product) put :update, id: @product, product: attributes_for(:product)
expect(assigns :product).to eq(@product) expect(assigns :product).to eq(@product)
end end
@ -119,23 +103,69 @@ describe ProductsController, type: :controller do
context 'failed' do context 'failed' do
it 'should not update attributes' do it 'should not update attributes' do
old_attributes = @product.attributes old_price = @product.price
put :update, id: @product, product: attributes_for(:invalid_product) put :update, id: @product, product: attributes_for(:invalid_product)
expect(@product.reload.attributes).to eq(old_attributes) expect(@product.reload.price).to eq(old_price)
end end
end end
end end
#############
# BARCODE #
#############
describe 'GET barcode' do
it 'should be successful' do
expect(response).to have_http_status(200)
end
end
################## ##################
# FROM_BARCODE # # LOAD_BARCODE #
################## ##################
describe 'POST from_barcode' do describe 'POST load_barcode' do
it 'should return a product when barcode in database' do describe 'new barcode' do
product = create :product before :each do
bar = create :barcode, product: product @code = attributes_for(:barcode)[:code].to_s
post :from_barcode, barcode: bar.code post :load_barcode, barcode: @code
expect(JSON.parse(response.body)["id"]).to eq(product.id) end
it 'should be successful' do
expect(response).to have_http_status(200)
end
it 'should be render the link partial' do
expect(response).to render_template(:link)
end
it 'should allow building a new product' do
expect(assigns(:product).id).to be nil
end
it 'should have a barcode built for the new product' do
barcode = assigns(:product).barcodes.first
expect(barcode.code).to eq @code
end
end
describe 'existing barcode' do
before :each do
@barcode = create :barcode
post :load_barcode, barcode: @barcode.code
end
it 'should be successful' do
expect(response).to have_http_status(200)
end
it 'should be render the stock_entry partial' do
expect(response).to render_template(:stock_entry)
end
it 'should have the correct product loaded' do
expect(assigns :product).to eq @barcode.product
end
end end
end end
end end

View file

@ -22,10 +22,13 @@ describe UsersController, type: :controller do
end end
it 'should be successful' do it 'should be successful' do
expect(response).to render_template(:show)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
it 'should render the user' do
expect(response).to render_template(:show)
end
it 'should load the correct user' do it 'should load the correct user' do
expect(assigns(:user)).to eq(@user) expect(assigns(:user)).to eq(@user)
end end
@ -40,6 +43,10 @@ describe UsersController, type: :controller do
get :edit, id: @user get :edit, id: @user
end end
it 'should be successful' do
expect(response).to have_http_status(200)
end
it 'should render the form' do it 'should render the form' do
expect(response).to render_template(:edit) expect(response).to render_template(:edit)
end end
@ -79,10 +86,73 @@ describe UsersController, type: :controller do
##################### #####################
describe 'GET edit_dagschotel' do describe 'GET edit_dagschotel' do
it 'should be successful' do
expect(response).to have_http_status(200)
end
it 'should render the page' do it 'should render the page' do
get :edit_dagschotel, id: @user get :edit_dagschotel, id: @user
expect(response).to render_template(:edit_dagschotel) expect(response).to render_template(:edit_dagschotel)
end
end
##############
# QUICKPAY #
##############
describe 'GET quickpay' do
describe 'successful' do
before :each do
@dagschotel = create :product, stock: 20
@user.update_attribute(:dagschotel, @dagschotel)
end
it 'should be successful' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
it 'should make an order' do
expect{
get :quickpay, id: @user
}.to change{ @user.reload.orders_count }.by(1)
end
describe 'order' do
before :each do
get :quickpay, id: @user
@order = @user.orders.last
end
it 'should contain 1 orderitem' do
expect(@order.order_items.size).to eq 1
end
it 'should have an orderitem with count 1' do
expect(@order.order_items.first.count).to eq 1
end
it 'should contain an orderitem for @dagschotel' do
expect(@order.order_items.first.product).to eq @dagschotel
end
end
end
describe 'failed' do
before :each do
@dagschotel = create :product, stock: 0
@user.update_attribute(:dagschotel, @dagschotel)
end
it 'should fail' do
xhr :get, :quickpay, id: @user
expect(response).to have_http_status(422)
end
it 'should not make an order' do
expect{
get :quickpay, id: @user
}.to_not change{ @user.reload.orders_count }
end
end
end end
end end

View file

@ -26,6 +26,7 @@ FactoryGirl.define do
factory :user do factory :user do
name { Faker::Name.name } name { Faker::Name.name }
avatar { Identicon.data_url_for name } avatar { Identicon.data_url_for name }
private { false }
factory :admin do factory :admin do
admin true admin true

View file

@ -21,13 +21,13 @@ describe User do
let(:user) { create :user } let(:user) { create :user }
it{ should be_able_to(:create, Order.new(user: user)) } it{ should be_able_to(:create, Order.new(user: user)) }
it{ should be_able_to(:delete, Order.new(user: user, created_at: (Rails.application.config.call_api_after - 1.minutes).ago)) } it{ should be_able_to(:destroy, Order.new(user: user, created_at: (Rails.application.config.call_api_after - 1.minutes).ago)) }
it{ should_not be_able_to(:delete, Order.new(user: user, created_at: 10.minutes.ago)) } it{ should_not be_able_to(:destroy, Order.new(user: user, created_at: 10.minutes.ago)) }
it{ should_not be_able_to(:create, Order.new) } it{ should_not be_able_to(:create, Order.new) }
it{ should_not be_able_to(:update, Order.new) } it{ should_not be_able_to(:update, Order.new) }
it{ should be_able_to(:read, Product.new) } it{ should be_able_to(:read, Product.new) }
it{ should_not be_able_to(:delete, Product.new) } it{ should_not be_able_to(:destroy, Product.new) }
it{ should_not be_able_to(:update, Product.new) } it{ should_not be_able_to(:update, Product.new) }
it{ should_not be_able_to(:create, Stock.new) } it{ should_not be_able_to(:create, Stock.new) }

View file

@ -1,3 +1,14 @@
# == Schema Information
#
# Table name: barcodes
#
# id :integer not null, primary key
# product_id :integer
# code :string default(""), not null
# created_at :datetime
# updated_at :datetime
#
describe Barcode do describe Barcode do
before :each do before :each do
@barcode = create :barcode @barcode = create :barcode
@ -23,5 +34,12 @@ describe Barcode do
expect(barcode).to_not be_valid expect(barcode).to_not be_valid
end end
end end
describe 'product' do
it 'should be present' do
@barcode.product = nil
expect(@barcode).to_not be_valid
end
end
end end
end end

View file

@ -44,7 +44,7 @@ describe OrderItem do
it 'should be less or equal to product stock' do it 'should be less or equal to product stock' do
@order_item.count = @order_item.product.stock + 1 @order_item.count = @order_item.product.stock + 1
expect(@order_item).to_not be_valid expect(@order_item).to_not be_valid
@order_item.count = @order_item.product.stock @order_item.count = [@order_item.product.stock, 100].min
expect(@order_item).to be_valid expect(@order_item).to be_valid
end end
end end

View file

@ -26,7 +26,10 @@ describe Order do
describe 'fields' do describe 'fields' do
describe 'user' do describe 'user' do
it { Order.reflect_on_association(:user).macro.should eq(:belongs_to) } it 'should be an association' do
expect(Order.reflect_on_association(:user).macro).to eq(:belongs_to)
end
it 'should be present' do it 'should be present' do
@order.user = nil @order.user = nil
expect(@order).to_not be_valid expect(@order).to_not be_valid
@ -74,4 +77,24 @@ describe Order do
end end
end end
#############
# HELPERS #
#############
describe 'deletable' do
it 'should be true' do
@order.created_at = Rails.application.config.call_api_after.ago + 2.minutes
expect(@order.deletable).to be true
end
it 'should be false' do
@order.created_at = Rails.application.config.call_api_after.ago - 2.minutes
expect(@order.deletable).to be false
end
end
it 'sec_until_remove should return a number of seconds' do
@order.created_at = Rails.application.config.call_api_after.ago + 2.minutes
expect((@order.sec_until_remove - 120).abs).to be < 10
end
end end

View file

@ -67,6 +67,11 @@ describe Product do
expect(@product).to_not be_valid expect(@product).to_not be_valid
end end
it 'should be a number' do
@product.stock = "123abc"
expect(@product).to_not be_valid
end
it 'should be positive' do it 'should be positive' do
@product.stock = -5 @product.stock = -5
expect(@product).to_not be_valid expect(@product).to_not be_valid
@ -81,6 +86,11 @@ describe Product do
expect(@product).to be_valid expect(@product).to be_valid
end end
it 'should be a number' do
@product.calories = "123abc"
expect(@product).to_not be_valid
end
it 'should be positive' do it 'should be positive' do
@product.calories = -5 @product.calories = -5
expect(@product).to_not be_valid expect(@product).to_not be_valid
@ -93,6 +103,12 @@ describe Product do
expect(@product).to_not be_valid expect(@product).to_not be_valid
end end
end end
describe 'deleted' do
it 'should default false' do
expect(@product.deleted).to be false
end
end
end end
############# #############
@ -111,4 +127,15 @@ describe Product do
end end
end end
############
# SCOPES #
############
describe 'for sale' do
it 'should return non-deleted products' do
product = create :product
product.update_attribute(:deleted, true)
expect(Product.for_sale).to eq([@product])
end
end
end end

View file

@ -45,5 +45,35 @@ describe User do
expect{ create :order, user: @user }.to change{ @user.reload.orders_count }.by(1) expect{ create :order, user: @user }.to change{ @user.reload.orders_count }.by(1)
end end
end end
describe 'admin' do
it 'should be false by default' do
expect(@user.reload.admin).to be false
end
end
describe 'koelkast' do
it 'should be false by default' do
expect(@user.reload.koelkast).to be false
end
end
end
############
# SCOPES #
############
describe 'scopes' do
it 'members should return members' do
create :koelkast
user = create :user
expect(User.members).to eq([@user, user])
end
it 'publik should return publik members' do
user = create :user
create :user, private: true
expect(User.publik).to eq([@user, user])
end
end end
end end