Merge branch 'tests-rspec' into master-spec
This commit is contained in:
commit
e20898c5ee
28 changed files with 786 additions and 13 deletions
14
.travis.yml
Normal file
14
.travis.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 1.9.3
|
||||
services:
|
||||
- redis-server
|
||||
before_install:
|
||||
- "export DISPLAY=:99.0"
|
||||
- "sh -e /etc/init.d/xvfb start"
|
||||
before_script:
|
||||
- "bundle exec rake foodsoft:setup:stock_config"
|
||||
- "mysql -e 'create database foodsoft_test;'"
|
||||
- 'printf "test:\n adapter: mysql2\n database: foodsoft_test\n username: travis\n encoding: utf8\n" >config/database.yml'
|
||||
- 'bundle exec rake db:schema:load RAILS_ENV=test'
|
||||
script: bundle exec rake spec
|
24
Gemfile
24
Gemfile
|
@ -54,10 +54,6 @@ group :development do
|
|||
gem 'binding_of_caller'
|
||||
# gem "rails-i18n-debug"
|
||||
|
||||
# Re-enable rails benchmarker/profiler
|
||||
gem 'ruby-prof'
|
||||
gem 'test-unit'
|
||||
|
||||
# Get infos when not using proper eager loading
|
||||
gem 'bullet'
|
||||
|
||||
|
@ -71,3 +67,23 @@ group :development do
|
|||
# Avoid having content-length warnings
|
||||
gem 'thin'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'ruby-prof'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'rspec-rails'
|
||||
gem 'factory_girl_rails', '~> 4.0'
|
||||
gem 'faker'
|
||||
# version requirements to avoid problem http://stackoverflow.com/questions/18114544
|
||||
gem 'capybara', '~> 2.1.0'
|
||||
# webkit and poltergeist don't seem to work yet
|
||||
gem 'selenium-webdriver', '~> 2.35.1'
|
||||
gem 'database_cleaner'
|
||||
gem 'simplecov', require: false
|
||||
# need to include rspec components before i18n-spec or rake fails in test environment
|
||||
gem 'rspec-core'
|
||||
gem 'rspec-expectations'
|
||||
gem 'i18n-spec'
|
||||
end
|
||||
|
|
65
Gemfile.lock
65
Gemfile.lock
|
@ -62,6 +62,14 @@ GEM
|
|||
net-ssh-gateway (>= 1.1.0)
|
||||
capistrano-ext (1.2.1)
|
||||
capistrano (>= 1.0.0)
|
||||
capybara (2.1.0)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
childprocess (0.3.9)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chronic (0.9.0)
|
||||
client_side_validations (3.1.4)
|
||||
coderay (1.0.8)
|
||||
|
@ -74,6 +82,8 @@ GEM
|
|||
coffee-script-source (1.3.3)
|
||||
commonjs (0.2.6)
|
||||
daemons (1.1.9)
|
||||
database_cleaner (0.7.1)
|
||||
diff-lcs (1.2.4)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.3)
|
||||
exception_notification (2.6.1)
|
||||
|
@ -81,6 +91,14 @@ GEM
|
|||
execjs (1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
expression_parser (0.9.0)
|
||||
factory_girl (4.2.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.2.1)
|
||||
factory_girl (~> 4.2.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.1.2)
|
||||
i18n (~> 0.5)
|
||||
ffi (1.9.0)
|
||||
haml (3.1.7)
|
||||
haml-rails (0.3.5)
|
||||
actionpack (>= 3.1, < 4.1)
|
||||
|
@ -92,9 +110,13 @@ GEM
|
|||
highline (1.6.19)
|
||||
hike (1.2.3)
|
||||
i18n (0.6.1)
|
||||
i18n-spec (0.4.0)
|
||||
iso
|
||||
inherited_resources (1.3.1)
|
||||
has_scope (~> 0.5.0)
|
||||
responders (~> 0.6)
|
||||
iso (0.2.0)
|
||||
i18n
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.1.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
|
@ -128,8 +150,9 @@ GEM
|
|||
activesupport (~> 3.1)
|
||||
polyamorous (~> 0.5.0)
|
||||
mime-types (1.21)
|
||||
mini_portile (0.5.1)
|
||||
mono_logger (1.1.0)
|
||||
multi_json (1.7.6)
|
||||
multi_json (1.7.9)
|
||||
mysql2 (0.3.11)
|
||||
net-scp (1.1.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
|
@ -138,6 +161,8 @@ GEM
|
|||
net-ssh (2.6.7)
|
||||
net-ssh-gateway (1.2.0)
|
||||
net-ssh (>= 2.6.5)
|
||||
nokogiri (1.6.0)
|
||||
mini_portile (~> 0.5.0)
|
||||
pdf-reader (1.2.0)
|
||||
Ascii85 (~> 1.0.0)
|
||||
hashery (~> 2.0)
|
||||
|
@ -190,8 +215,20 @@ GEM
|
|||
redis-namespace (~> 1.2)
|
||||
sinatra (>= 0.9.2)
|
||||
vegas (~> 0.1.2)
|
||||
ruby-prof (0.11.2)
|
||||
rspec-core (2.14.2)
|
||||
rspec-expectations (2.14.0)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.14.1)
|
||||
rspec-rails (2.14.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
ruby-prof (0.13.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
rubyzip (0.9.9)
|
||||
sass (3.2.1)
|
||||
sass-rails (3.2.5)
|
||||
railties (~> 3.2.0)
|
||||
|
@ -200,6 +237,11 @@ GEM
|
|||
select2-rails (3.4.2)
|
||||
sass-rails
|
||||
thor (~> 0.14)
|
||||
selenium-webdriver (2.35.1)
|
||||
childprocess (>= 0.2.5)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip (< 1.0.0)
|
||||
websocket (~> 1.0.4)
|
||||
simple-navigation (3.9.0)
|
||||
activesupport (>= 2.3.2)
|
||||
simple-navigation-bootstrap (0.0.4)
|
||||
|
@ -207,6 +249,10 @@ GEM
|
|||
simple_form (2.1.0)
|
||||
actionpack (~> 3.0)
|
||||
activemodel (~> 3.0)
|
||||
simplecov (0.7.1)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.7.1)
|
||||
simplecov-html (0.7.1)
|
||||
sinatra (1.3.6)
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.3)
|
||||
|
@ -220,7 +266,6 @@ GEM
|
|||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sqlite3 (1.3.6)
|
||||
test-unit (2.5.3)
|
||||
therubyracer (0.10.2)
|
||||
libv8 (~> 3.3.10)
|
||||
thin (1.5.1)
|
||||
|
@ -245,12 +290,15 @@ GEM
|
|||
uniform_notifier (1.1.1)
|
||||
vegas (0.1.11)
|
||||
rack (>= 1.0.0)
|
||||
websocket (1.0.7)
|
||||
whenever (0.8.1)
|
||||
activesupport (>= 2.3.4)
|
||||
chronic (>= 0.6.3)
|
||||
wikicloth (0.8.0)
|
||||
builder
|
||||
expression_parser
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -264,11 +312,16 @@ DEPENDENCIES
|
|||
bullet
|
||||
capistrano (= 2.13.5)
|
||||
capistrano-ext
|
||||
capybara (~> 2.1.0)
|
||||
client_side_validations
|
||||
coffee-rails (~> 3.2.1)
|
||||
daemons
|
||||
database_cleaner
|
||||
exception_notification
|
||||
factory_girl_rails (~> 4.0)
|
||||
faker
|
||||
haml-rails
|
||||
i18n-spec
|
||||
inherited_resources
|
||||
jquery-rails
|
||||
kaminari
|
||||
|
@ -281,14 +334,18 @@ DEPENDENCIES
|
|||
rails (~> 3.2.9)
|
||||
rails-settings-cached (= 0.2.4)
|
||||
resque
|
||||
rspec-core
|
||||
rspec-expectations
|
||||
rspec-rails
|
||||
ruby-prof
|
||||
sass-rails (~> 3.2.3)
|
||||
select2-rails
|
||||
selenium-webdriver (~> 2.35.1)
|
||||
simple-navigation
|
||||
simple-navigation-bootstrap
|
||||
simple_form
|
||||
simplecov
|
||||
sqlite3
|
||||
test-unit
|
||||
therubyracer
|
||||
thin
|
||||
twitter-bootstrap-rails
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
FoodSoft
|
||||
=========
|
||||
[![Build Status](https://travis-ci.org/foodcoops/foodsoft.png?branch=tests-rspec)](https://travis-ci.org/foodcoops/foodsoft)
|
||||
[![Code Climate](https://codeclimate.com/github/foodcoops/foodsoft.png)](https://codeclimate.com/github/foodcoops/foodsoft)
|
||||
[![Dependency Status](https://gemnasium.com/foodcoops/foodsoft.png)](https://gemnasium.com/foodcoops/foodsoft)
|
||||
|
||||
|
|
|
@ -13,11 +13,9 @@ class Supplier < ActiveRecord::Base
|
|||
:delivery_days, :order_howto, :note, :shared_supplier_id, :min_order_quantity
|
||||
|
||||
validates :name, :presence => true, :length => { :in => 4..30 }
|
||||
validates :phone, :presence => true, :length => { :in => 8..20 }
|
||||
validates :phone, :presence => true, :length => { :in => 8..25 }
|
||||
validates :address, :presence => true, :length => { :in => 8..50 }
|
||||
validates_length_of :order_howto, :note, maximum: 250
|
||||
validates_length_of :phone, :in => 8..20
|
||||
validates_length_of :address, :in => 8..50
|
||||
validate :uniqueness_of_name
|
||||
|
||||
scope :undeleted, -> { where(deleted_at: nil) }
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
.well.well-small
|
||||
%h3= t('.notes_and_journal')
|
||||
#note
|
||||
- unless @order.note.empty?
|
||||
- unless @order.note.blank?
|
||||
= simple_format @order.note
|
||||
- else
|
||||
%p= t('.comment_on_transaction')
|
||||
|
|
|
@ -38,6 +38,15 @@ namespace :foodsoft do
|
|||
puts yellow "All done! Your foodcoft should be running smoothly."
|
||||
start_server
|
||||
end
|
||||
|
||||
namespace :setup do
|
||||
desc "Initialize stock configuration"
|
||||
task :stock_config do
|
||||
setup_app_config
|
||||
setup_development
|
||||
setup_secret_token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup_bundler
|
||||
|
|
3
lib/tasks/rspec.rake
Normal file
3
lib/tasks/rspec.rake
Normal file
|
@ -0,0 +1,3 @@
|
|||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
task :default => :spec
|
20
spec/factories/article.rb
Normal file
20
spec/factories/article.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
require 'factory_girl'
|
||||
|
||||
FactoryGirl.define do
|
||||
|
||||
factory :article do
|
||||
sequence(:name) { |n| Faker::Lorem.words(rand(2..4)).join(' ') + " ##{n}" }
|
||||
unit { Faker::Unit.unit }
|
||||
price { rand(2600) / 100 }
|
||||
tax { [6, 21].sample }
|
||||
deposit { rand(10) < 8 ? 0 : [0.0, 0.80, 1.20, 12.00].sample }
|
||||
unit_quantity { rand(5) < 3 ? 1 : rand(1..20) }
|
||||
#supplier_id
|
||||
article_category { FactoryGirl.create :article_category }
|
||||
end
|
||||
|
||||
factory :article_category do
|
||||
sequence(:name) { |n| Faker::Lorem.characters(rand(2..12)) + " ##{n}" }
|
||||
end
|
||||
|
||||
end
|
10
spec/factories/group_order.rb
Normal file
10
spec/factories/group_order.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
require 'factory_girl'
|
||||
|
||||
FactoryGirl.define do
|
||||
|
||||
# requires order
|
||||
factory :group_order do
|
||||
ordergroup { FactoryGirl.create(:user, groups: [FactoryGirl.create(:ordergroup)]).ordergroup }
|
||||
end
|
||||
|
||||
end
|
9
spec/factories/group_order_article.rb
Normal file
9
spec/factories/group_order_article.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require 'factory_girl'
|
||||
|
||||
FactoryGirl.define do
|
||||
|
||||
# requires order_article
|
||||
factory :group_order_article do
|
||||
end
|
||||
|
||||
end
|
31
spec/factories/order.rb
Normal file
31
spec/factories/order.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
require 'factory_girl'
|
||||
|
||||
FactoryGirl.define do
|
||||
|
||||
factory :order do
|
||||
starts { Time.now }
|
||||
supplier { FactoryGirl.create :supplier, article_count: (article_count.nil? ? true : article_count) }
|
||||
article_ids { supplier.articles.map(&:id) unless supplier.nil? }
|
||||
|
||||
ignore do
|
||||
article_count true
|
||||
end
|
||||
|
||||
# for an order from stock; need to add articles
|
||||
factory :stock_order do
|
||||
supplier_id 0
|
||||
# article_ids needs to be supplied
|
||||
end
|
||||
|
||||
# In the order's after_save callback order articles are created, so
|
||||
# until the order is saved, these articles do not yet exist.
|
||||
after :create do |order|
|
||||
order.reload
|
||||
end
|
||||
end
|
||||
|
||||
# requires order and article
|
||||
factory :order_article do
|
||||
end
|
||||
|
||||
end
|
21
spec/factories/supplier.rb
Normal file
21
spec/factories/supplier.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require 'factory_girl'
|
||||
|
||||
FactoryGirl.define do
|
||||
|
||||
factory :supplier do
|
||||
name { Faker::Company.name.truncate(30) }
|
||||
phone { Faker::PhoneNumber.phone_number }
|
||||
address { Faker::Address.street_address }
|
||||
|
||||
ignore do
|
||||
article_count 0
|
||||
end
|
||||
|
||||
after :create do |supplier, evaluator|
|
||||
article_count = evaluator.article_count
|
||||
article_count = rand(1..99) if article_count == true
|
||||
FactoryGirl.create_list :article, article_count, supplier: supplier
|
||||
end
|
||||
end
|
||||
|
||||
end
|
36
spec/factories/user.rb
Normal file
36
spec/factories/user.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
require 'factory_girl'
|
||||
|
||||
FactoryGirl.define do
|
||||
|
||||
factory :user do
|
||||
sequence(:nick) { |n| "user#{n}"}
|
||||
first_name { Faker::Name.first_name }
|
||||
email { Faker::Internet.email }
|
||||
password { new_random_password }
|
||||
|
||||
factory :admin do
|
||||
sequence(:nick) { |n| "admin#{n}" }
|
||||
first_name 'Administrator'
|
||||
after :create do |user, evaluator|
|
||||
FactoryGirl.create :workgroup, role_admin: true, user_ids: [user.id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
factory :group do
|
||||
sequence(:name) {|n| "Group ##{n}"}
|
||||
|
||||
factory :workgroup do
|
||||
type ''
|
||||
end
|
||||
|
||||
factory :ordergroup do
|
||||
type 'Ordergroup'
|
||||
sequence(:name) {|n| "Order group ##{n}"}
|
||||
# workaround to avoid needing to save the ordergroup
|
||||
# avoids e.g. error after logging in related to applebar
|
||||
after :create do |group| Ordergroup.find(group.id).update_stats! end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
12
spec/i18n_spec.rb
Normal file
12
spec/i18n_spec.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
require 'spec_helper'
|
||||
require 'i18n-spec'
|
||||
|
||||
Dir.glob('config/locales/*.yml').each do |locale_file|
|
||||
describe "#{locale_file}" do
|
||||
it_behaves_like 'a valid locale file', locale_file
|
||||
# We're currently allowing both German and English as source language
|
||||
# besides, we're using localeapp, so that it's ok if pull requests
|
||||
# don't have this - a localapp pull will fix that right away.
|
||||
#it { expect(locale_file).to be_a_subset_of 'config/locales/en.yml' }
|
||||
end
|
||||
end
|
55
spec/integration/balancing_spec.rb
Normal file
55
spec/integration/balancing_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'settling an order', :type => :feature do
|
||||
let(:admin) { FactoryGirl.create :user, groups:[FactoryGirl.create(:workgroup, role_finance: true)] }
|
||||
let(:supplier) { FactoryGirl.create :supplier }
|
||||
let(:article) { FactoryGirl.create :article, supplier: supplier, unit_quantity: 1 }
|
||||
let(:order) { FactoryGirl.create :order, supplier: supplier, article_ids: [article.id] } # need to ref article
|
||||
let(:go1) { FactoryGirl.create :group_order, order: order }
|
||||
let(:go2) { FactoryGirl.create :group_order, order: order }
|
||||
let(:oa) { order.order_articles.find_by_article_id(article.id) }
|
||||
let(:goa1) { FactoryGirl.create :group_order_article, group_order: go1, order_article: oa }
|
||||
let(:goa2) { FactoryGirl.create :group_order_article, group_order: go2, order_article: oa }
|
||||
before do
|
||||
goa1.update_quantities(3, 0)
|
||||
goa2.update_quantities(1, 0)
|
||||
oa.update_results!
|
||||
order.finish!(admin)
|
||||
goa1.reload
|
||||
goa2.reload
|
||||
end
|
||||
|
||||
it 'has correct order result' do
|
||||
expect(oa.quantity).to eq(4)
|
||||
expect(oa.tolerance).to eq(0)
|
||||
expect(goa1.result).to eq(3)
|
||||
expect(goa2.result).to eq(1)
|
||||
end
|
||||
|
||||
describe :type => :feature, :js => true do
|
||||
before { login admin }
|
||||
before { visit new_finance_order_path(order_id: order.id) }
|
||||
|
||||
it 'has product ordered visible' do
|
||||
expect(page).to have_content(article.name)
|
||||
expect(page).to have_selector("#order_article_#{oa.id}")
|
||||
end
|
||||
|
||||
it 'shows order result' do
|
||||
click_link article.name
|
||||
expect(page).to have_selector("#group_order_articles_#{oa.id}")
|
||||
within("#group_order_articles_#{oa.id}") do
|
||||
# make sure these ordergroup names are in the list for this product
|
||||
expect(page).to have_content(go1.ordergroup.name)
|
||||
expect(page).to have_content(go2.ordergroup.name)
|
||||
# and that their order results match what we expect
|
||||
expect(page).to have_selector("#group_order_article_#{goa1.id}_quantity")
|
||||
expect(find("#group_order_article_#{goa1.id}_quantity").text.to_f).to eq(3)
|
||||
expect(page).to have_selector("#group_order_article_#{goa2.id}_quantity")
|
||||
expect(find("#group_order_article_#{goa2.id}_quantity").text.to_f).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
57
spec/integration/product_distribution_example_spec.rb
Normal file
57
spec/integration/product_distribution_example_spec.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'product distribution', :type => :feature do
|
||||
let(:admin) { FactoryGirl.create :admin }
|
||||
let(:user_a) { FactoryGirl.create :user, groups: [FactoryGirl.create(:ordergroup)] }
|
||||
let(:user_b) { FactoryGirl.create :user, groups: [FactoryGirl.create(:ordergroup)] }
|
||||
let(:supplier) { FactoryGirl.create :supplier }
|
||||
let(:article) { FactoryGirl.create :article, supplier: supplier, unit_quantity: 5 }
|
||||
let(:order) { FactoryGirl.create(:order, supplier: supplier, article_ids: [article.id]) }
|
||||
let(:oa) { order.order_articles.first }
|
||||
|
||||
describe :type => :feature do
|
||||
# make sure users have enough money to order
|
||||
before do
|
||||
[user_a, user_b].each do |user|
|
||||
ordergroup = Ordergroup.find(user.ordergroup.id)
|
||||
ordergroup.add_financial_transaction! 5000, 'for ordering', admin
|
||||
end
|
||||
end
|
||||
|
||||
it 'agrees to documented example', :js => true do
|
||||
# gruppe a bestellt 2(3), weil sie auf jeden fall was von x bekommen will
|
||||
login user_a
|
||||
visit new_group_order_path(:order_id => order.id)
|
||||
2.times { find("[data-increase_quantity='#{oa.id}']").click }
|
||||
3.times { find("[data-increase_tolerance='#{oa.id}']").click }
|
||||
find('input[type=submit]').click
|
||||
expect(page).to have_selector('body')
|
||||
# gruppe b bestellt 2(0)
|
||||
login user_b
|
||||
visit new_group_order_path(:order_id => order.id)
|
||||
2.times { find("[data-increase_quantity='#{oa.id}']").click }
|
||||
find('input[type=submit]').click
|
||||
expect(page).to have_selector('body')
|
||||
# gruppe a faellt ein dass sie doch noch mehr braucht von x und aendert auf 4(1).
|
||||
login user_a
|
||||
visit edit_group_order_path(order.group_order(user_a.ordergroup), :order_id => order.id)
|
||||
2.times { find("[data-increase_quantity='#{oa.id}']").click }
|
||||
2.times { find("[data-decrease_tolerance='#{oa.id}']").click }
|
||||
find('input[type=submit]').click
|
||||
expect(page).to have_selector('body')
|
||||
# die zuteilung
|
||||
order.finish!(admin)
|
||||
oa.reload
|
||||
# Endstand: insg. Bestellt wurden 6(1)
|
||||
expect(oa.quantity).to eq(6)
|
||||
expect(oa.tolerance).to eq(1)
|
||||
# Gruppe a bekommt 3 einheiten.
|
||||
goa_a = oa.group_order_articles.joins(:group_order).where(:group_orders => {:ordergroup_id => user_a.ordergroup.id}).first
|
||||
expect(goa_a.result).to eq(3)
|
||||
# gruppe b bekommt 2 einheiten.
|
||||
goa_b = oa.group_order_articles.joins(:group_order).where(:group_orders => {:ordergroup_id => user_b.ordergroup.id}).first
|
||||
expect(goa_b.result).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
21
spec/integration/session_spec.rb
Normal file
21
spec/integration/session_spec.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'the session', :type => :feature do
|
||||
let(:user) { FactoryGirl.create :user }
|
||||
|
||||
describe 'login page', :type => :feature do
|
||||
it 'is accesible' do
|
||||
get login_path
|
||||
expect(response).to be_success
|
||||
end
|
||||
it 'logs me in' do
|
||||
login user
|
||||
expect(page).to_not have_selector('.alert-error')
|
||||
end
|
||||
it 'does not log me in with wrong password' do
|
||||
login user.nick, 'XX'+user.password
|
||||
expect(page).to have_selector('.alert-error')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
63
spec/integration/supplier_spec.rb
Normal file
63
spec/integration/supplier_spec.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'supplier', :type => :feature do
|
||||
let(:supplier) { FactoryGirl.create :supplier }
|
||||
|
||||
describe :type => :feature, :js => true do
|
||||
let(:user) { FactoryGirl.create :user, groups:[FactoryGirl.create(:workgroup, role_suppliers: true)] }
|
||||
before { login user }
|
||||
|
||||
it 'can be created' do
|
||||
visit suppliers_path
|
||||
click_on I18n.t('suppliers.index.action_new')
|
||||
supplier = FactoryGirl.build :supplier
|
||||
within('#new_supplier') do
|
||||
fill_in 'supplier_name', :with => supplier.name
|
||||
fill_in 'supplier_address', :with => supplier.address
|
||||
fill_in 'supplier_phone', :with => supplier.phone
|
||||
find('input[type="submit"]').click
|
||||
end
|
||||
expect(page).to have_content(supplier.name)
|
||||
end
|
||||
|
||||
it 'is included in supplier list' do
|
||||
supplier
|
||||
visit suppliers_path
|
||||
expect(page).to have_content(supplier.name)
|
||||
end
|
||||
end
|
||||
|
||||
describe :type => :feature, :js => true do
|
||||
let(:article_category) { FactoryGirl.create :article_category }
|
||||
let(:user) { FactoryGirl.create :user, groups:[FactoryGirl.create(:workgroup, role_article_meta: true)] }
|
||||
before { login user }
|
||||
|
||||
it 'can visit supplier articles path' do
|
||||
visit supplier_articles_path(supplier)
|
||||
expect(page).to have_content(supplier.name)
|
||||
expect(page).to have_content(I18n.t('articles.index.edit_all'))
|
||||
end
|
||||
|
||||
it 'can create a new article' do
|
||||
article_category.save!
|
||||
visit supplier_articles_path(supplier)
|
||||
click_on I18n.t('articles.index.new')
|
||||
expect(page).to have_selector('form#new_article')
|
||||
article = FactoryGirl.build :article, supplier: supplier, article_category: article_category
|
||||
within('#new_article') do
|
||||
fill_in 'article_name', :with => article.name
|
||||
fill_in 'article_unit', :with => article.unit
|
||||
select article.article_category.name, :from => 'article_article_category_id'
|
||||
fill_in 'article_price', :with => article.price
|
||||
fill_in 'article_unit_quantity', :with => article.unit_quantity
|
||||
fill_in 'article_tax', :with => article.tax
|
||||
fill_in 'article_deposit', :with => article.deposit
|
||||
# "Element cannot be scrolled into view" error, js as workaround
|
||||
#find('input[type="submit"]').click
|
||||
page.execute_script('$("form#new_article").submit();')
|
||||
end
|
||||
expect(page).to have_content(article.name)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
47
spec/models/article_spec.rb
Normal file
47
spec/models/article_spec.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Article do
|
||||
let(:supplier) { FactoryGirl.create :supplier }
|
||||
let(:article) { FactoryGirl.create :article, supplier: supplier }
|
||||
|
||||
it 'has a unique name' do
|
||||
article2 = FactoryGirl.build :article, supplier: supplier, name: article.name
|
||||
expect(article2).to be_invalid
|
||||
end
|
||||
|
||||
it 'computes the gross price correctly' do
|
||||
article.deposit = 0
|
||||
article.tax = 12
|
||||
expect(article.gross_price).to eq((article.price * 1.12).round(2))
|
||||
article.deposit = 1.20
|
||||
expect(article.gross_price).to eq(((article.price + 1.20) * 1.12).round(2))
|
||||
end
|
||||
|
||||
it 'gross price >= net price' do
|
||||
expect(article.gross_price).to be >= article.price
|
||||
end
|
||||
|
||||
it 'fc-price >= gross price' do
|
||||
if article.gross_price > 0
|
||||
expect(article.fc_price).to be > article.gross_price
|
||||
else
|
||||
expect(article.fc_price).to be >= article.gross_price
|
||||
end
|
||||
end
|
||||
|
||||
it 'knows when it is deleted' do
|
||||
expect(supplier.deleted?).to be_false
|
||||
supplier.mark_as_deleted
|
||||
expect(supplier.deleted?).to be_true
|
||||
end
|
||||
|
||||
it 'keeps a price history' do
|
||||
expect(article.article_prices.all.map(&:price)).to eq([article.price])
|
||||
oldprice = article.price
|
||||
sleep 1 # so that the new price really has a later creation time
|
||||
article.price += 1
|
||||
article.save!
|
||||
expect(article.article_prices.all.map(&:price)).to eq([article.price, oldprice])
|
||||
end
|
||||
|
||||
end
|
48
spec/models/group_order_article_spec.rb
Normal file
48
spec/models/group_order_article_spec.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GroupOrderArticle do
|
||||
let(:user) { FactoryGirl.create :user, groups: [FactoryGirl.create(:ordergroup)] }
|
||||
let(:order) { FactoryGirl.create(:order).reload }
|
||||
let(:go) { FactoryGirl.create :group_order, order: order, ordergroup: user.ordergroup }
|
||||
let(:goa) { FactoryGirl.create :group_order_article, group_order: go, order_article: order.order_articles.first }
|
||||
|
||||
it 'has zero quantity by default' do expect(goa.quantity).to eq(0) end
|
||||
it 'has zero tolerance by default' do expect(goa.tolerance).to eq(0) end
|
||||
it 'has zero result by default' do expect(goa.result).to eq(0) end
|
||||
it 'is not ordered by default' do expect(GroupOrderArticle.ordered.where(:id => goa.id).exists?).to be_false end
|
||||
it 'has zero total price by default' do expect(goa.total_price).to eq(0) end
|
||||
|
||||
describe do
|
||||
let(:article) { FactoryGirl.create :article, supplier: order.supplier, unit_quantity: 1 }
|
||||
let(:oa) { order.order_articles.create(:article => article) }
|
||||
let(:goa) { FactoryGirl.create :group_order_article, group_order: go, order_article: oa }
|
||||
|
||||
it 'can be ordered by piece' do
|
||||
goa.update_quantities(1, 0)
|
||||
expect(goa.quantity).to eq(1)
|
||||
expect(goa.tolerance).to eq(0)
|
||||
end
|
||||
|
||||
it 'can be ordered in larger amounts' do
|
||||
quantity, tolerance = rand(13..99), rand(0..99)
|
||||
goa.update_quantities(quantity, tolerance)
|
||||
expect(goa.quantity).to eq(quantity)
|
||||
expect(goa.tolerance).to eq(tolerance)
|
||||
end
|
||||
|
||||
it 'has a proper total price' do
|
||||
quantity = rand(1..99)
|
||||
goa.update_quantities(quantity, 0)
|
||||
expect(goa.total_price).to eq(quantity * goa.order_article.price.fc_price)
|
||||
end
|
||||
|
||||
it 'can unorder a product' do
|
||||
goa.update_quantities(rand(1..99), rand(0..99))
|
||||
goa.update_quantities(0, 0)
|
||||
expect(goa.quantity).to eq(0)
|
||||
expect(goa.tolerance).to eq(0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
25
spec/models/group_order_spec.rb
Normal file
25
spec/models/group_order_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GroupOrder do
|
||||
let(:user) { FactoryGirl.create :user, groups: [FactoryGirl.create(:ordergroup)] }
|
||||
let(:order) { FactoryGirl.create :order }
|
||||
|
||||
# the following two tests are currently disabled - https://github.com/foodcoops/foodsoft/issues/158
|
||||
|
||||
#it 'needs an order' do
|
||||
# expect(FactoryGirl.build(:group_order, ordergroup: user.ordergroup)).to be_invalid
|
||||
#end
|
||||
|
||||
#it 'needs an ordergroup' do
|
||||
# expect(FactoryGirl.build(:group_order, order: order)).to be_invalid
|
||||
#end
|
||||
|
||||
describe do
|
||||
let(:go) { FactoryGirl.create :group_order, order: order, ordergroup: user.ordergroup }
|
||||
|
||||
it 'has zero price initially' do
|
||||
expect(go.price).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
47
spec/models/order_spec.rb
Normal file
47
spec/models/order_spec.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Order do
|
||||
|
||||
it 'needs a supplier' do
|
||||
expect(FactoryGirl.build(:order, supplier: nil)).to be_invalid
|
||||
end
|
||||
|
||||
it 'needs order articles' do
|
||||
supplier = FactoryGirl.create :supplier, article_count: 0
|
||||
expect(FactoryGirl.build(:order, supplier: supplier)).to be_invalid
|
||||
end
|
||||
|
||||
it 'can be created' do
|
||||
expect(FactoryGirl.build(:order, article_count: 1)).to be_valid
|
||||
end
|
||||
|
||||
describe 'with articles' do
|
||||
let(:order) { FactoryGirl.create :order }
|
||||
|
||||
it 'is open by default' do expect(order).to be_open end
|
||||
it 'is not finished by default' do expect(order).to_not be_finished end
|
||||
it 'is not closed by default' do expect(order).to_not be_closed end
|
||||
|
||||
it 'has valid order articles' do
|
||||
order.order_articles.all.each {|oa| expect(oa).to be_valid }
|
||||
end
|
||||
|
||||
it 'can be finished' do
|
||||
# TODO randomise user
|
||||
order.finish!(User.first)
|
||||
expect(order).to_not be_open
|
||||
expect(order).to be_finished
|
||||
expect(order).to_not be_closed
|
||||
end
|
||||
|
||||
it 'can be closed' do
|
||||
# TODO randomise user
|
||||
order.finish!(User.first)
|
||||
order.close!(User.first)
|
||||
expect(order).to_not be_open
|
||||
expect(order).to be_closed
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
16
spec/models/supplier_spec.rb
Normal file
16
spec/models/supplier_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Supplier do
|
||||
let(:supplier) { FactoryGirl.create :supplier }
|
||||
|
||||
it 'has a unique name' do
|
||||
supplier2 = FactoryGirl.build :supplier, name: supplier.name
|
||||
expect(supplier2).to be_invalid
|
||||
end
|
||||
|
||||
it 'has valid articles' do
|
||||
supplier = FactoryGirl.create :supplier, article_count: true
|
||||
supplier.articles.all.each {|a| expect(a).to be_valid }
|
||||
end
|
||||
|
||||
end
|
59
spec/models/user_spec.rb
Normal file
59
spec/models/user_spec.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
|
||||
it 'is correctly created' do
|
||||
user = FactoryGirl.create :user,
|
||||
nick: 'johnnydoe', first_name: 'Johnny', last_name: 'DoeBar',
|
||||
email: 'johnnydoe@foodcoop.test', phone: '+1234567890'
|
||||
expect(user.nick).to eq('johnnydoe')
|
||||
expect(user.first_name).to eq('Johnny')
|
||||
expect(user.last_name).to eq('DoeBar')
|
||||
expect(user.name).to eq('Johnny DoeBar')
|
||||
expect(user.email).to eq('johnnydoe@foodcoop.test')
|
||||
expect(user.phone).to eq('+1234567890')
|
||||
end
|
||||
|
||||
describe 'does not have the role' do
|
||||
let(:user) { FactoryGirl.create :user }
|
||||
it 'admin' do expect(user.role_admin?).to be_false end
|
||||
it 'finance' do expect(user.role_finance?).to be_false end
|
||||
it 'article_meta' do expect(user.role_article_meta?).to be_false end
|
||||
it 'suppliers' do expect(user.role_suppliers?).to be_false end
|
||||
it 'orders' do expect(user.role_orders?).to be_false end
|
||||
end
|
||||
|
||||
describe do
|
||||
let(:user) { FactoryGirl.create :user, password: 'blahblah' }
|
||||
|
||||
it 'can authenticate with correct password' do
|
||||
expect(User.authenticate(user.nick, 'blahblah')).to be_true
|
||||
end
|
||||
it 'can not authenticate with incorrect password' do
|
||||
expect(User.authenticate(user.nick, 'foobar')).to be_nil
|
||||
end
|
||||
it 'can not set a password without matching confirmation' do
|
||||
user.password = 'abcdefghij'
|
||||
user.password_confirmation = 'foobarxyz'
|
||||
expect(user).to be_invalid
|
||||
end
|
||||
it 'can set a password with matching confirmation' do
|
||||
user.password = 'abcdefghij'
|
||||
user.password_confirmation = 'abcdefghij'
|
||||
expect(user).to be_valid
|
||||
end
|
||||
|
||||
it 'has a unique nick' do
|
||||
expect(FactoryGirl.build(:user, nick: user.nick, email: "x-#{user.email}")).to be_invalid
|
||||
end
|
||||
it 'has a unique email' do
|
||||
expect(FactoryGirl.build(:user, email: "#{user.email}")).to be_invalid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'admin' do
|
||||
let(:user) { FactoryGirl.create :admin }
|
||||
it 'default admin role' do expect(user.role_admin?).to be_true end
|
||||
end
|
||||
|
||||
end
|
67
spec/spec_helper.rb
Normal file
67
spec/spec_helper.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
require 'support/coverage' # needs to be first
|
||||
require File.expand_path("../../config/environment", __FILE__)
|
||||
require 'rspec/rails'
|
||||
require 'rspec/autorun'
|
||||
|
||||
require 'capybara/rails'
|
||||
require 'capybara/rspec'
|
||||
|
||||
# Requires supporting ruby files with custom matchers and macros, etc,
|
||||
# in spec/support/ and its subdirectories.
|
||||
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
|
||||
|
||||
RSpec.configure do |config|
|
||||
# ## Mock Framework
|
||||
#
|
||||
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
||||
#
|
||||
# config.mock_with :mocha
|
||||
# config.mock_with :flexmock
|
||||
# config.mock_with :rr
|
||||
|
||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
||||
# examples within a transaction, remove the following line or assign false
|
||||
# instead of true.
|
||||
#config.use_transactional_fixtures = true
|
||||
# We use capybara with selenium, and need database_cleaner
|
||||
config.before(:each) do
|
||||
DatabaseCleaner.strategy = (example.metadata[:js] ? :truncation : :transaction)
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
config.after(:each) do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
# If true, the base class of anonymous controllers will be inferred
|
||||
# automatically. This will be the default behavior in future versions of
|
||||
# rspec-rails.
|
||||
config.infer_base_class_for_anonymous_controllers = false
|
||||
|
||||
# Run specs in random order to surface order dependencies. If you find an
|
||||
# order dependency and want to debug it, you can fix the order by providing
|
||||
# the seed, which is printed after each run.
|
||||
# --seed 1234
|
||||
config.order = "random"
|
||||
|
||||
config.include SessionHelper
|
||||
end
|
||||
|
||||
module Faker
|
||||
class Unit
|
||||
class << self
|
||||
def unit
|
||||
['kg', '1L', '100ml', 'piece', 'bunch', '500g'].sample
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# include default foodsoft scope in urls, so that *_path works
|
||||
ActionDispatch::Integration::Runner.class_eval do
|
||||
undef default_url_options
|
||||
def default_url_options(options={})
|
||||
{foodcoop: FoodsoftConfig.scope}.merge(options)
|
||||
end
|
||||
end
|
14
spec/support/coverage.rb
Normal file
14
spec/support/coverage.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
# optional test coverage
|
||||
# needs to be loaded first, e.g. add a require at top of spec_helper
|
||||
if ENV['COVERAGE']
|
||||
require 'simplecov'
|
||||
SimpleCov.start do
|
||||
add_filter '/spec/'
|
||||
add_filter '/test/'
|
||||
add_group 'Models', '/app/models/'
|
||||
add_group 'Controllers', '/app/controllers/'
|
||||
add_group 'Helpers', '/app/helpers/'
|
||||
add_group 'Documents', '/app/documents/'
|
||||
add_group 'Libraries', '/lib/'
|
||||
end
|
||||
end
|
17
spec/support/session_helper.rb
Normal file
17
spec/support/session_helper.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
module SessionHelper
|
||||
|
||||
def login(user=nil, password=nil)
|
||||
visit login_path
|
||||
user = FactoryGirl.create :user if user.nil?
|
||||
if user.instance_of? ::User
|
||||
nick, password = user.nick, user.password
|
||||
else
|
||||
nick = user
|
||||
end
|
||||
fill_in 'nick', :with => nick
|
||||
fill_in 'password', :with => password
|
||||
find('input[type=submit]').click
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue