Refactor dagschotel and make test succeed again

This commit is contained in:
benji 2015-03-19 16:22:55 +01:00
parent 191517bda7
commit 6ec27acaf8
28 changed files with 259 additions and 236 deletions

View file

@ -9,7 +9,7 @@
text-align: center;
}
.user_info h5 {
.user_info h5 {
margin-right: 10px;
text-align: right;
}
@ -37,7 +37,7 @@
cursor: pointer;
}
.balance {
.debt {
padding: 12px 0;
text-align: center;
font-family: monospace;

View file

@ -99,3 +99,7 @@ table {
color: #999;
}
}
.product_dagschotel {
height: 34px;
}

View file

@ -34,12 +34,18 @@ class UsersController < ApplicationController
def edit_dagschotel
@user = User.find(params[:user_id])
@dagschotel = @user.dagschotel
@products = Product.all
@categories = Product.categories
end
def update_dagschotel
@user = User.find(params[:user_id])
@user.dagschotel = Product.find(params[:product_id])
@products = Product.all
@categories = Product.categories
if @user.save
flash[:success] = "Succesfully updated dagschotel"
redirect_to @user

View file

@ -2,17 +2,18 @@
#
# Table name: orders
#
# id :integer not null, primary key
# user_id :integer
# cost :integer
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# user_id :integer
# price_cents :integer
# created_at :datetime not null
# updated_at :datetime not null
# cancelled :boolean default("f")
#
class Order < ActiveRecord::Base
include ActionView::Helpers::TextHelper
after_create { self.user.decrement!(:balance_cents, price_cents) }
after_create { self.user.increment!(:debt_cents, price_cents) }
belongs_to :user, counter_cache: true
has_many :order_items, dependent: :destroy
@ -39,9 +40,10 @@ class Order < ActiveRecord::Base
def cancel
return if self.cancelled
user.increment!(:balance_cents, price_cents)
user.decrement!(:debt_cents, price_cents)
User.decrement_counter(:orders_count, user.id)
update_attribute(:cancelled, true)
self.order_items.each(&:cancel)
end
def to_sentence

View file

@ -3,9 +3,9 @@
# Table name: order_items
#
# id :integer not null, primary key
# order_id :integer not null
# order_id :integer
# product_id :integer not null
# count :integer default(0)
# count :integer default("0")
#
class OrderItem < ActiveRecord::Base
@ -24,6 +24,10 @@ class OrderItem < ActiveRecord::Base
super
end
def cancel
self.product.increment!(:stock, self.count)
end
private
def remove_from_stock

View file

@ -3,16 +3,16 @@
# Table name: products
#
# id :integer not null, primary key
# name :string(255) not null
# price_cents :integer default(0), not null
# category :integer default(0)
# stock :integer default(0), not null
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# name :string not null
# price_cents :integer default("0"), not null
# created_at :datetime
# updated_at :datetime
# avatar_file_name :string
# avatar_content_type :string
# avatar_file_size :integer
# avatar_updated_at :datetime
# category :integer default("0")
# stock :integer default("0"), not null
#
class Product < ActiveRecord::Base

View file

@ -3,33 +3,35 @@
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# last_name :string(255)
# balance_cents :integer default(0), not null
# nickname :string(255)
# admin :boolean
# koelkast :boolean default(FALSE)
# dagschotel_id :integer
# orders_count :integer default(0)
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# name :string
# last_name :string
# debt_cents :integer default("0"), not null
# nickname :string
# created_at :datetime
# updated_at :datetime
# encrypted_password :string(255) default(""), not null
# encrypted_password :string default(""), not null
# remember_created_at :datetime
# sign_in_count :integer default(0), not null
# sign_in_count :integer default("0"), not null
# current_sign_in_at :datetime
# last_sign_in_at :datetime
# current_sign_in_ip :string(255)
# last_sign_in_ip :string(255)
# current_sign_in_ip :string
# last_sign_in_ip :string
# admin :boolean
# dagschotel_id :integer
# avatar_file_name :string
# avatar_content_type :string
# avatar_file_size :integer
# avatar_updated_at :datetime
# orders_count :integer default("0")
# koelkast :boolean default("f")
# provider :string
# uid :string
#
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable
has_paper_trail only: [:balance, :admin, :orders_count, :koelkast]
has_paper_trail only: [:debt_cents, :admin, :orders_count, :koelkast]
has_attached_file :avatar, styles: { large: "150x150>", medium: "100x100>" }, default_style: :medium
@ -50,13 +52,13 @@ class User < ActiveRecord::Base
"#{name} #{last_name}"
end
def balance
self.balance_cents / 100.0
def debt
self.debt_cents / 100.0
end
def balance=(value)
def debt=(value)
if value.is_a? String then value.sub!(',', '.') end
self.balance_cents = (value.to_f * 100).to_int
self.debt_cents = (value.to_f * 100).to_int
end
# Change URL params for User

View file

@ -1,3 +1,3 @@
<%- headers = ['nickname', 'schulden'] -%>
<%= CSV.generate_line headers -%>
<% @users.each do |user| %><%= CSV.generate_line([user.nickname, user.balance]) %><% end %>
<% @users.each do |user| %><%= CSV.generate_line([user.nickname, user.debt]) %><% end %>

View file

@ -1,4 +1,4 @@
<h3>Order for <%= @user.nickname %> (Huidige schuld: <%= euro(@user.balance) %>)</h3>
<h3>Order for <%= @user.nickname %> (Huidige schuld: <%= euro(@user.debt) %>)</h3>
<div class="row">
<%= f_form_for [@user, @order] do |f| %>

View file

@ -0,0 +1,22 @@
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#all" role="tab" data-toggle="tab">All</a></li>
<% @categories.each do |o, i| %>
<li role="presentation"><a href="#<%= o %>" aria-controls="<%= o %>" role="tab" data-toggle="tab"><%= o.titleize %></a></li>
<% end %>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<br />
<div role="tabpanel" class="tab-pane active" id="all">
<%= render @products %>
</div>
<% @categories.each do |o, i| %>
<div role="tabpanel" class="tab-pane" id="<%= o %>">
<%= render @products.where(category: i) %>
</div>
<% end %>
</div>
</div>

View file

@ -1,16 +1,28 @@
<div class="col-md-3">
<div class="thumbnail pic">
<%= image_tag product.avatar %>
<div class="form_row_image">
<%= image_tag product.avatar %>
</div>
<div class="caption">
<h4><%= product.name %></h4>
<h3><%= euro(product.price) %></h3>
<h6>(In stock: <%= product.stock %>)</h6>
<% if current_user && current_user.admin? %>
<%- if controller_name == 'products' && current_user && current_user.admin? %>
<p>
<%= link_to "Edit", edit_product_path(product), class: "btn btn-default" %>
<%= link_to "Delete", product_path(product), method: :delete, class: "btn btn-danger", data: {confirm: 'Are you sure?'} %>
</p>
<% end %>
<% end -%>
<%- if controller_name == 'users' %>
<div class="product_dagschotel">
<% if current_user.dagschotel != product %>
<%= link_to "Make dagschotel", user_dagschotel_path(current_user, product), class: "btn btn-default" %>
<% else %>
<%= link_to "Huidige dagschotel", user_dagschotel_path(current_user, product), class: "btn btn-success", disabled: true %>
<% end %>
</div>
<% end -%>
</div>
</div>
</div>

View file

@ -1,27 +1,3 @@
<h1>All products</h1>
<%= render partial: 'flash' %>
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#all" role="tab" data-toggle="tab">All</a></li>
<% @categories.each do |o, i| %>
<li role="presentation"><a href="#<%= o %>" aria-controls="<%= o %>" role="tab" data-toggle="tab"><%= o.titleize %></a></li>
<% end %>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<br />
<div role="tabpanel" class="tab-pane active" id="all">
<%= render @products %>
</div>
<% @categories.each do |o, i| %>
<div role="tabpanel" class="tab-pane" id="<%= o %>">
<%= render @products.where(category: i) %>
</div>
<% end %>
</div>
</div>
<%= render 'products/index' %>

View file

@ -6,7 +6,7 @@
<p><strong>Name:</strong> <%= user.name %></p>
<p><strong>Last name:</strong> <%= user.last_name %></p>
<p><strong>Nickname:</strong> <%= user.nickname %></p>
<p><strong>Balance:</strong> <%= euro(user.balance) %></p>
<p><strong>Debt:</strong> <%= euro(user.debt) %></p>
</div>
<% if current_user.admin? %>
<div class="footer">

View file

@ -1,11 +1,2 @@
<% if current_user.dagschotel.present? %>
<h3>Current Dagschotel:</h3>
<div>
<%= render current_user.dagschotel %>
</div>
<% end %>
<h4>Choose new Dagschotel:</h4>
<% Product.all.each do |p| %>
<%= link_to image_tag(p.avatar), user_dagschotel_path(current_user, p) %>
<% end %>
<h3>Choose new Dagschotel</h4>
<%= render 'products/index' %>

View file

@ -7,7 +7,7 @@
</h5>
<h2><%= @user.nickname %> (<%= @user.full_name %>)</h2>
<%= button_to "PLACE ORDER!", new_user_order_path(@user), method: :get if current_user == @user %>
<div class="balance">BALANCE: <%= euro(@user.balance) %></div>
<div class="debt">DEBT: <%= euro(@user.debt) %></div>
</div>
<% if @orders.any? %>

View file

@ -0,0 +1,5 @@
class ChangeBalanceToDebt < ActiveRecord::Migration
def change
rename_column :users, :balance_cents, :debt_cents
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150319134138) do
ActiveRecord::Schema.define(version: 20150319141248) do
create_table "order_items", force: :cascade do |t|
t.integer "order_id"
@ -46,7 +46,7 @@ ActiveRecord::Schema.define(version: 20150319134138) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "last_name"
t.integer "balance_cents", default: 0, null: false
t.integer "debt_cents", default: 0, null: false
t.string "nickname"
t.datetime "created_at"
t.datetime "updated_at"

View file

@ -5,4 +5,76 @@
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
DEFAULT_PASSWORD = "password"
products = [
{
name: 'Fanta',
price: 0.6,
category: 'beverages',
stock: 25,
avatar: File.new('public/seeds/products/fanta.jpg', 'r')
},
{
name: 'Club Mate',
price: 1.2,
category: 'beverages',
stock: 25,
avatar: File.new('public/seeds/products/club_mate.jpg', 'r')
},
{
name: 'Kinder Bueno',
price: 0.6,
category: 'food',
stock: 15,
avatar: File.new('public/seeds/products/bueno.jpg', 'r')
}
]
products.each do |attr|
Product.create name: attr[:name], price: attr[:price], category: attr[:category], stock: attr[:stock], avatar: attr[:avatar]
end
users = [
{
nickname: 'admin',
name: 'A.',
last_name: 'Admin',
avatar: File.new('public/seeds/users/admin.jpg', 'r'),
admin: true
},
{
nickname: 'koelkast',
name: 'K.',
last_name: 'Koelkast',
avatar: File.new('public/seeds/users/admin.jpg', 'r'),
koelkast: true
},
{
nickname: 'benji',
name: 'Benjamin',
last_name: 'Cousaert',
avatar: File.new('public/seeds/users/benji.jpg', 'r'),
dagschotel: Product.first
},
{
nickname: 'don',
name: 'Lorin',
last_name: 'Werthen',
avatar: File.new('public/seeds/users/don.jpg', 'r')
},
{
nickname: 'silox',
name: 'Tom',
last_name: 'Naessens',
avatar: File.new('public/seeds/users/silox.jpg', 'r')
}
]
users.each do |attr|
User.create nickname: attr[:nickname], name: attr[:name], last_name: attr[:last_name], avatar: attr[:avatar], dagschotel: attr[:dagschotel], password: DEFAULT_PASSWORD, password_confirmation: DEFAULT_PASSWORD, admin: attr[:admin] || false, koelkast: attr[:koelkast] || false
end
50.times do |i|
User.create nickname: "TestUser#{i}", name: "Test", last_name: "User", avatar: users[0][:avatar], password: DEFAULT_PASSWORD, password_confirmation: DEFAULT_PASSWORD
end

View file

@ -1,79 +0,0 @@
namespace :db do
desc "Fill the database with some sample data."
task generatedata: :environment do
DEFAULT_PASSWORD = "password"
products = [
{
name: 'Fanta',
price: 0.6,
category: 'beverages',
stock: 25,
avatar: File.new('public/seeds/products/fanta.jpg', 'r')
},
{
name: 'Club Mate',
price: 1.2,
category: 'beverages',
stock: 25,
avatar: File.new('public/seeds/products/club_mate.jpg', 'r')
},
{
name: 'Kinder Bueno',
price: 0.6,
category: 'food',
stock: 15,
avatar: File.new('public/seeds/products/bueno.jpg', 'r')
}
]
products.each do |attr|
Product.create name: attr[:name], price: attr[:price], category: attr[:category], stock: attr[:stock], avatar: attr[:avatar]
end
users = [
{
nickname: 'admin',
name: 'A.',
last_name: 'Admin',
avatar: File.new('public/seeds/users/admin.jpg', 'r'),
admin: true
},
{
nickname: 'koelkast',
name: 'K.',
last_name: 'Koelkast',
avatar: File.new('public/seeds/users/admin.jpg', 'r'),
koelkast: true
},
{
nickname: 'benji',
name: 'Benjamin',
last_name: 'Cousaert',
avatar: File.new('public/seeds/users/benji.jpg', 'r'),
dagschotel: Product.first
},
{
nickname: 'don',
name: 'Lorin',
last_name: 'Werthen',
avatar: File.new('public/seeds/users/don.jpg', 'r')
},
{
nickname: 'silox',
name: 'Tom',
last_name: 'Naessens',
avatar: File.new('public/seeds/users/silox.jpg', 'r')
}
]
users.each do |attr|
User.create nickname: attr[:nickname], name: attr[:name], last_name: attr[:last_name], avatar: attr[:avatar], dagschotel: attr[:dagschotel], password: DEFAULT_PASSWORD, password_confirmation: DEFAULT_PASSWORD, admin: attr[:admin] || false, koelkast: attr[:koelkast] || false
end
50.times do |i|
User.create nickname: "TestUser#{i}", name: "Test", last_name: "User", avatar: users[0][:avatar], password: DEFAULT_PASSWORD, password_confirmation: DEFAULT_PASSWORD
end
end
end

View file

@ -1,11 +1,11 @@
# == Schema Information
#
# Table name: order_products
# Table name: order_items
#
# id :integer not null, primary key
# order_id :integer
# product_id :integer
# count :integer default(1)
# product_id :integer not null
# count :integer default("0")
#
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

View file

@ -2,11 +2,12 @@
#
# Table name: orders
#
# id :integer not null, primary key
# user_id :integer
# cost :integer
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# user_id :integer
# price_cents :integer
# created_at :datetime not null
# updated_at :datetime not null
# cancelled :boolean default("f")
#
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

View file

@ -3,16 +3,16 @@
# Table name: products
#
# id :integer not null, primary key
# name :string(255) not null
# price_cents :integer default(0), not null
# category :integer default(0)
# stock :integer default(0), not null
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# name :string not null
# price_cents :integer default("0"), not null
# created_at :datetime
# updated_at :datetime
# avatar_file_name :string
# avatar_content_type :string
# avatar_file_size :integer
# avatar_updated_at :datetime
# category :integer default("0")
# stock :integer default("0"), not null
#
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

View file

@ -3,27 +3,29 @@
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# last_name :string(255)
# balance_cents :integer default(0), not null
# nickname :string(255)
# admin :boolean
# koelkast :boolean default(FALSE)
# dagschotel_id :integer
# orders_count :integer default(0)
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# name :string
# last_name :string
# debt_cents :integer default("0"), not null
# nickname :string
# created_at :datetime
# updated_at :datetime
# encrypted_password :string(255) default(""), not null
# encrypted_password :string default(""), not null
# remember_created_at :datetime
# sign_in_count :integer default(0), not null
# sign_in_count :integer default("0"), not null
# current_sign_in_at :datetime
# last_sign_in_at :datetime
# current_sign_in_ip :string(255)
# last_sign_in_ip :string(255)
# current_sign_in_ip :string
# last_sign_in_ip :string
# admin :boolean
# dagschotel_id :integer
# avatar_file_name :string
# avatar_content_type :string
# avatar_file_size :integer
# avatar_updated_at :datetime
# orders_count :integer default("0")
# koelkast :boolean default("f")
# provider :string
# uid :string
#
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

View file

@ -15,14 +15,14 @@ class OrderIntegrationTest < ActionDispatch::IntegrationTest
assert page.has_content? 'Order for benji'
assert_difference "User.find(users(:benji).id).balance_cents", -240 do
assert_difference "User.find(users(:benji).id).debt_cents", 240 do
fill_in 'order_order_items_attributes_2_count', with: 2
click_button "Order!"
end
end
test 'quickpay' do
assert_difference "User.find(users(:benji).id).balance_cents", -User.find(users(:benji).id).dagschotel.price_cents do
assert_difference "User.find(users(:benji).id).debt_cents", User.find(users(:benji).id).dagschotel.price_cents do
visit user_quickpay_path(users(:benji))
assert page.has_content? 'Success!'
end
@ -31,7 +31,7 @@ class OrderIntegrationTest < ActionDispatch::IntegrationTest
test 'cancelling quickpay' do
visit user_quickpay_path(users(:benji))
assert_difference "User.find(users(:benji).id).balance_cents", User.find(users(:benji).id).dagschotel.price_cents do
assert_difference "User.find(users(:benji).id).debt_cents", -User.find(users(:benji).id).dagschotel.price_cents do
click_link 'Undo'
assert page.has_content? 'Success!'
end

View file

@ -10,7 +10,7 @@ class StockTest < ActiveSupport::TestCase
end
assert_difference "products(:fanta).stock", +2 do
order.destroy
order.cancel
end
end
end

View file

@ -2,11 +2,12 @@
#
# Table name: orders
#
# id :integer not null, primary key
# user_id :integer
# cost :integer
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# user_id :integer
# price_cents :integer
# created_at :datetime not null
# updated_at :datetime not null
# cancelled :boolean default("f")
#
require 'test_helper'
@ -19,7 +20,7 @@ class OrderTest < ActiveSupport::TestCase
end
test "order total price is correct" do
assert_equal @order.price, 300
assert_equal @order.price, 3.00
end
test "to_sentence is correct" do

View file

@ -3,16 +3,16 @@
# Table name: products
#
# id :integer not null, primary key
# name :string(255) not null
# price_cents :integer default(0), not null
# category :integer default(0)
# stock :integer default(0), not null
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# name :string not null
# price_cents :integer default("0"), not null
# created_at :datetime
# updated_at :datetime
# avatar_file_name :string
# avatar_content_type :string
# avatar_file_size :integer
# avatar_updated_at :datetime
# category :integer default("0")
# stock :integer default("0"), not null
#
require 'test_helper'

View file

@ -3,27 +3,29 @@
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# last_name :string(255)
# balance_cents :integer default(0), not null
# nickname :string(255)
# admin :boolean
# koelkast :boolean default(FALSE)
# dagschotel_id :integer
# orders_count :integer default(0)
# avatar_file_name :string(255)
# avatar_content_type :string(255)
# avatar_file_size :integer
# avatar_updated_at :datetime
# name :string
# last_name :string
# debt_cents :integer default("0"), not null
# nickname :string
# created_at :datetime
# updated_at :datetime
# encrypted_password :string(255) default(""), not null
# encrypted_password :string default(""), not null
# remember_created_at :datetime
# sign_in_count :integer default(0), not null
# sign_in_count :integer default("0"), not null
# current_sign_in_at :datetime
# last_sign_in_at :datetime
# current_sign_in_ip :string(255)
# last_sign_in_ip :string(255)
# current_sign_in_ip :string
# last_sign_in_ip :string
# admin :boolean
# dagschotel_id :integer
# avatar_file_name :string
# avatar_content_type :string
# avatar_file_size :integer
# avatar_updated_at :datetime
# orders_count :integer default("0")
# koelkast :boolean default("f")
# provider :string
# uid :string
#
require 'test_helper'
@ -37,14 +39,14 @@ class UserTest < ActiveSupport::TestCase
assert_equal @user.full_name, "Benjamin Cousaert"
end
test "balance behaves correctly" do
assert_equal @user.balance_cents, 0
assert_equal @user.balance, 0
test "debt behaves correctly" do
assert_equal @user.debt_cents, 0
assert_equal @user.debt, 0
@user.balance = 1.3
@user.debt = 1.3
assert_equal @user.balance, 1.3
assert_equal @user.balance_cents, 130
assert_equal @user.debt, 1.3
assert_equal @user.debt_cents, 130
end
test "to_param" do