Auto-merge from CI [skip ci]

This commit is contained in:
Continuous Integration
2015-12-16 10:58:03 +11:00
29 changed files with 504 additions and 74 deletions

View File

@@ -0,0 +1,22 @@
angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attrs, shops, orderCycles) ->
$scope.$compile = $compile
$scope.shops = shops
$scope.orderCycles = orderCycles
for oc in $scope.orderCycles
oc.name_and_status = "#{oc.name} (#{oc.status})"
$scope.distributor_id = $attrs.ofnDistributorId
$scope.order_cycle_id = $attrs.ofnOrderCycleId
$scope.validOrderCycle = (oc, index, array) ->
$scope.orderCycleHasDistributor oc, parseInt($scope.distributor_id)
$scope.distributorHasOrderCycles = (distributor) ->
(oc for oc in orderCycles when @orderCycleHasDistributor(oc, distributor.id)).length > 0
$scope.orderCycleHasDistributor = (oc, distributor_id) ->
distributor_ids = (d.id for d in oc.distributors)
distributor_ids.indexOf(distributor_id) != -1
$scope.distributionChosen = ->
$scope.distributor_id && $scope.order_cycle_id

View File

@@ -1,3 +1,5 @@
require 'open_food_network/last_used_address'
class CheckoutController < Spree::CheckoutController
layout 'darkswarm'
@@ -129,7 +131,11 @@ class CheckoutController < Spree::CheckoutController
def before_address
associate_user
last_used_bill_address, last_used_ship_address = find_last_used_addresses(@order.email)
lua = OpenFoodNetwork::LastUsedAddress.new(@order.email)
last_used_bill_address = lua.last_used_bill_address.andand.clone
last_used_ship_address = lua.last_used_ship_address.andand.clone
preferred_bill_address, preferred_ship_address = spree_current_user.bill_address, spree_current_user.ship_address if spree_current_user.respond_to?(:bill_address) && spree_current_user.respond_to?(:ship_address)
@order.bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default
@order.ship_address ||= preferred_ship_address || last_used_ship_address || Spree::Address.default

View File

@@ -17,6 +17,24 @@ Spree::Admin::LineItemsController.class_eval do
end
end
def create
variant = Spree::Variant.find(params[:line_item][:variant_id])
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
@line_item = @order.add_variant(variant, params[:line_item][:quantity].to_i)
if @order.save
respond_with(@line_item) do |format|
format.html { render :partial => 'spree/admin/orders/form', :locals => { :order => @order.reload } }
end
else
respond_with(@line_item) do |format|
format.js { render :action => 'create', :locals => { :order => @order.reload } }
end
end
end
private
def load_order

View File

@@ -10,6 +10,8 @@ Spree::Admin::OrdersController.class_eval do
# in an auth failure as the @order object is nil for collection actions
before_filter :check_authorization, except: [:bulk_management, :managed]
before_filter :load_distribution_choices, only: [:new, :edit, :update]
# After updating an order, the fees should be updated as well
# Currently, adding or deleting line items does not trigger updating the
# fees! This is a quick fix for that.
@@ -19,6 +21,7 @@ Spree::Admin::OrdersController.class_eval do
before_filter :require_distributor_abn, only: :invoice
respond_to :html, :json
# Mostly the original Spree method, tweaked to allow us to ransack with completed_at in a sane way
@@ -112,4 +115,14 @@ Spree::Admin::OrdersController.class_eval do
respond_with(@order) { |format| format.html { redirect_to edit_admin_order_path(@order) } }
end
end
def load_distribution_choices
@shops = Enterprise.is_distributor.managed_by(spree_current_user).by_name
ocs = OrderCycle.managed_by(spree_current_user)
@order_cycles = ocs.soonest_closing +
ocs.soonest_opening +
ocs.closed +
ocs.undated
end
end

View File

@@ -12,7 +12,14 @@ Spree::Admin::SearchController.class_eval do
:bill_address_lastname_start => params[:q]
}).result.limit(10)
end
render :users
render :users
end
def users_with_ams
users_without_ams
render json: @users, each_serializer: Api::Admin::UserSerializer
end
alias_method_chain :users, :ams
end

View File

@@ -1,3 +1,5 @@
require 'open_food_network/last_used_address'
Spree::CheckoutController.class_eval do
include CheckoutHelper
@@ -19,7 +21,10 @@ Spree::CheckoutController.class_eval do
def before_address
associate_user
last_used_bill_address, last_used_ship_address = find_last_used_addresses(@order.email)
lua = OpenFoodNetwork::LastUsedAddress.new(@order.email)
last_used_bill_address = lua.last_used_bill_address.andand.clone
last_used_ship_address = lua.last_used_ship_address.andand.clone
preferred_bill_address, preferred_ship_address = spree_current_user.bill_address, spree_current_user.ship_address if spree_current_user.respond_to?(:bill_address) && spree_current_user.respond_to?(:ship_address)
@order.bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default
@@ -29,14 +34,4 @@ Spree::CheckoutController.class_eval do
def after_complete
reset_order
end
def find_last_used_addresses(email)
past = Spree::Order.order("id desc").where(:email => email).where("state != 'cart'").limit(8)
if order = past.detect(&:bill_address)
bill_address = order.bill_address.clone if order.bill_address
ship_address = order.ship_address.clone if order.ship_address and order.shipping_method.andand.require_ship_address
end
[bill_address, ship_address]
end
end

View File

@@ -25,8 +25,8 @@ module Admin
admin_inject_json_ams_array "admin.shipping_methods", "shippingMethods", @shipping_methods, Api::Admin::IdNameSerializer
end
def admin_inject_shops
admin_inject_json_ams_array "admin.customers", "shops", @shops, Api::Admin::IdNameSerializer
def admin_inject_shops(ngModule='admin.customers')
admin_inject_json_ams_array ngModule, "shops", @shops, Api::Admin::IdNameSerializer
end
def admin_inject_hubs
@@ -74,6 +74,10 @@ module Admin
render partial: "admin/json/injection_ams", locals: {ngModule: 'admin.orderCycles', name: 'ocInstance', json: "{coordinator_id: '#{@order_cycle.coordinator.id}'}"}
end
def admin_inject_order_cycles
admin_inject_json_ams_array "admin.orders", "orderCycles", @order_cycles, Api::Admin::BasicOrderCycleSerializer, current_user: spree_current_user
end
def admin_inject_spree_api_key
render partial: "admin/json/injection_ams", locals: {ngModule: 'ofn.admin', name: 'SpreeApiKey', json: "'#{@spree_api_key.to_s}'"}
end

View File

@@ -24,6 +24,8 @@ class OrderCycle < ActiveRecord::Base
scope :soonest_opening, lambda { upcoming.order('order_cycles.orders_open_at ASC') }
scope :by_name, order('name')
scope :distributing_product, lambda { |product|
joins(:exchanges).
merge(Exchange.outgoing).

View File

@@ -26,18 +26,15 @@ Spree::Variant.class_eval do
after_save :update_units
scope :with_order_cycles_inner, joins(exchanges: :order_cycle)
scope :with_order_cycles_outer, joins('LEFT OUTER JOIN exchange_variants AS o_exchange_variants ON (o_exchange_variants.variant_id = spree_variants.id)').
joins('LEFT OUTER JOIN exchanges AS o_exchanges ON (o_exchanges.id = o_exchange_variants.exchange_id)').
joins('LEFT OUTER JOIN order_cycles AS o_order_cycles ON (o_order_cycles.id = o_exchanges.order_cycle_id)')
scope :not_deleted, where(deleted_at: nil)
scope :in_stock, where('spree_variants.count_on_hand > 0 OR spree_variants.on_demand=?', true)
scope :in_distributor, lambda { |distributor|
with_order_cycles_outer.
where('o_exchanges.incoming = ? AND o_exchanges.receiver_id = ?', false, distributor).
select('DISTINCT spree_variants.*')
where(id: ExchangeVariant.select(:variant_id).
joins(:exchange).
where('exchanges.incoming = ? AND exchanges.receiver_id = ?', false, distributor)
)
}
scope :in_order_cycle, lambda { |order_cycle|
with_order_cycles_inner.
merge(Exchange.outgoing).

View File

@@ -1,7 +1,7 @@
/ insert_before "[data-hook='admin_order_form_buttons']"
%fieldset.no-border-bottom
%legend{align => 'center'} Distribution
%legend{align: 'center'} Distribution
- if @order.complete?
.alpha.six.columns
@@ -18,9 +18,12 @@
- else
.alpha.six.columns
.field
= f.label :distributor_id
= f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true
%label{for: "order_distributor_id"} Distributor
%select.fullwidth{id: "order_distributor_id", name: "order[distributor_id]", 'ng-model' => 'distributor_id'}
%option{"ng-repeat" => "shop in shops", "ng-value" => "shop.id", "ng-selected" => "distributor_id == shop.id", "ng-disabled" => "!distributorHasOrderCycles(shop)", "ng-bind" => "shop.name"}
.omega.six.columns
.field
= f.label :order_cycle_id
= f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true
.field{"ng-show" => "distributor_id"}
%label{for: "order_order_cycle_id"} Order Cycle
%select.select2.fullwidth{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'}
%option{"ng-repeat" => "oc in orderCycles | filter:validOrderCycle", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name_and_status"}

View File

@@ -0,0 +1,2 @@
add_to_attributes "table.index, [data-hook='admin_order_form_buttons']"
attributes "ng-show" => "distributionChosen()"

View File

@@ -1,14 +1,24 @@
class Api::Admin::BasicOrderCycleSerializer < ActiveModel::Serializer
attributes :id, :name, :first_order, :last_order
include OrderCyclesHelper
attributes :id, :name, :status, :first_order, :last_order
has_many :suppliers, serializer: Api::Admin::IdNameSerializer
has_many :distributors, serializer: Api::Admin::IdNameSerializer
def status
order_cycle_status_class object
end
def first_order
object.orders_open_at.strftime("%F")
object.orders_open_at.andand.strftime("%F")
end
def last_order
(object.orders_close_at + 1.day).strftime("%F")
if object.orders_close_at.present?
(object.orders_close_at + 1.day).strftime("%F")
else
nil
end
end
end

View File

@@ -1,3 +1,5 @@
require 'open_food_network/order_cycle_permissions'
class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
attributes :id, :name, :orders_open_at, :orders_close_at, :coordinator_id, :exchanges
attributes :editable_variants_for_incoming_exchanges, :editable_variants_for_outgoing_exchanges

View File

@@ -1,3 +1,18 @@
require 'open_food_network/last_used_address'
class Api::Admin::UserSerializer < ActiveModel::Serializer
attributes :id, :email
has_one :ship_address, serializer: Api::AddressSerializer
has_one :bill_address, serializer: Api::AddressSerializer
def ship_address
object.ship_address ||
OpenFoodNetwork::LastUsedAddress.new(object.email).last_used_ship_address
end
def bill_address
object.bill_address ||
OpenFoodNetwork::LastUsedAddress.new(object.email).last_used_bill_address
end
end

View File

@@ -0,0 +1,6 @@
// The admin order form contains angular directives, so it needs to be
// compiled before insertion into the DOM
var scope = angular.element("#order-form-wrapper").scope();
$("#order-form-wrapper").html(scope.$compile('<%= escape_javascript(render :partial => "spree/admin/orders/form") %>')(scope));
scope.$apply();
$('select.select2').select2({allowClear: true});

View File

@@ -0,0 +1,24 @@
= csrf_meta_tags
- content_for :page_actions do
%li= event_links
%li= button_link_to t(:resend), resend_admin_order_url(@order), method: :post, icon: 'icon-email'
%li= button_link_to t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left'
= admin_inject_shops 'admin.orders'
= admin_inject_order_cycles
= render 'spree/admin/shared/order_tabs', current: 'Order Details'
%div{"data-hook" => "admin_order_edit_header"}
= render 'spree/shared/error_messages', target: @order
%div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl", "ofn-distributor-id" => @order.distributor_id, "ofn-order-cycle-id" => @order.order_cycle_id}
= render 'add_product'
%div{"data-hook" => "admin_order_edit_form"}
#order-form-wrapper
= render 'form', order: @order
- content_for :head do
= javascript_tag 'var expand_variants = true;'

View File

@@ -0,0 +1,27 @@
- content_for :page_title do
= t(:new)
- content_for :page_actions do
%li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left'
= admin_inject_shops 'admin.orders'
= admin_inject_order_cycles
= render 'spree/admin/shared/order_tabs', :current => 'Order Details'
= csrf_meta_tags
%div{"data-hook" => "admin_order_new_header"}
= render 'spree/shared/error_messages', :target => @order
%div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl"}
%div{"ng-show" => "distributionChosen()"}
= render 'add_product'
- unless @order.line_items.any?
%div{"data-hook" => "admin_order_new_form"}
#order-form-wrapper
= render 'form'
- content_for :head do
= javascript_tag 'var expand_variants = true;'

View File

@@ -0,0 +1,28 @@
module OpenFoodNetwork
class LastUsedAddress
def initialize(email)
@email = email
end
def last_used_bill_address
recent_orders.detect(&:bill_address).andand.bill_address
end
def last_used_ship_address
recent_orders.detect { |o|
o.ship_address && o.shipping_method.andand.require_ship_address
}.andand.ship_address
end
private
def recent_orders
Spree::Order.
order("id DESC").
where(email: @email).
where("state != 'cart'").
limit(8)
end
end
end

View File

@@ -6,6 +6,7 @@ module OpenFoodNetwork
[
"PRODUCT",
"Description",
"SKU",
"Qty",
"Pack Size",
"Unit",
@@ -18,15 +19,23 @@ module OpenFoodNetwork
end
def table
variants.map do |variant|
variants = variants()
if params[:distributor_id].to_i > 0
distributor = Enterprise.find(params[:distributor_id])
scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor)
variants.each { |v| scoper.scope(v) }
end
variants.select { |v| v.in_stock? }
.map do |variant|
[
variant.product.name,
variant.full_name,
variant.sku,
'',
OptionValueNamer.new(variant).value,
OptionValueNamer.new(variant).unit,
variant.price - gst(variant),
variant.price,
'',
gst(variant),
grower_and_method(variant),
variant.product.primary_taxon.name

View File

@@ -28,8 +28,6 @@ module OpenFoodNetwork
end
def filter(variants)
# NOTE: Ordering matters.
# filter_to_order_cycle and filter_to_distributor return arrays not relations
filter_to_distributor filter_to_order_cycle filter_on_hand filter_to_supplier filter_not_deleted variants
end
@@ -56,9 +54,7 @@ module OpenFoodNetwork
def filter_to_distributor(variants)
if params[:distributor_id].to_i > 0
distributor = Enterprise.find params[:distributor_id]
variants.select do |v|
Enterprise.distributing_product(v.product_id).include? distributor
end
variants.in_distributor(distributor)
else
variants
end
@@ -67,7 +63,7 @@ module OpenFoodNetwork
def filter_to_order_cycle(variants)
if params[:order_cycle_id].to_i > 0
order_cycle = OrderCycle.find params[:order_cycle_id]
variants.select { |v| order_cycle.variants.include? v }
variants.where(id: order_cycle.variants)
else
variants
end

View File

@@ -52,12 +52,6 @@ describe CheckoutController do
response.should be_success
end
it "doesn't copy the previous shipping address from a pickup order" do
old_order = create(:order, bill_address: create(:address), ship_address: create(:address))
Spree::Order.stub_chain(:order, :where, :where, :limit, :detect).and_return(old_order)
controller.send(:find_last_used_addresses, "email").last.should == nil
end
describe "building the order" do
before do
controller.stub(:current_distributor).and_return(distributor)

View File

@@ -126,6 +126,23 @@ describe Spree::Admin::LineItemsController do
end
end
describe "#create" do
let!(:variant) { create(:variant, price: 88) }
let!(:vo) { create(:variant_override, hub: distributor, variant: variant, price: 11.11) }
let!(:distributor) { create(:distributor_enterprise) }
let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], variants: [variant]) }
let!(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) }
let(:params) { { order_id: order.number, line_item: { variant_id: variant.id, quantity: 1 } } }
before { login_as_admin }
it "takes variant overrides into account for price" do
spree_post :create, params
order.line_items(:reload).last.price.should == 11.11
end
end
describe "#update" do
let(:supplier) { create(:supplier_enterprise) }
let(:distributor1) { create(:distributor_enterprise) }

View File

@@ -3,7 +3,7 @@ require "spec_helper"
feature %q{
As an administrator
I want to manage orders
} do
}, js: true do
include AuthenticationWorkflow
include WebHelper
@@ -11,7 +11,7 @@ feature %q{
@user = create(:user)
@product = create(:simple_product)
@distributor = create(:distributor_enterprise, charges_sales_tax: true)
@order_cycle = create(:simple_order_cycle, distributors: [@distributor], variants: [@product.variants.first])
@order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first])
@order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due')
@@ -21,33 +21,39 @@ feature %q{
create :check_payment, order: @order, amount: @order.total
end
scenario "creating an order with distributor and order cycle", js: true, retry: 3 do
order_cycle = create(:order_cycle)
distributor = order_cycle.distributors.first
product = order_cycle.products.first
scenario "creating an order with distributor and order cycle", retry: 3 do
distributor_disabled = create(:distributor_enterprise)
create(:simple_order_cycle, name: 'Two')
login_to_admin_section
visit '/admin/orders'
click_link 'New Order'
# Distributors without an order cycle should be shown as disabled
page.should have_selector "option[value='#{distributor_disabled.id}'][disabled='disabled']"
# When we select a distributor, it should limit order cycle selection to those for that distributor
page.should_not have_select2 'order_order_cycle_id'
select @distributor.name, from: 'order_distributor_id'
page.should have_select2 'order_order_cycle_id', options: ['', 'One (open)']
select2_select @order_cycle.name, from: 'order_order_cycle_id'
page.should have_content 'ADD PRODUCT'
targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
click_link 'Add'
page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS
page.should have_selector 'td', text: product.name
page.should have_selector 'td', text: @product.name
select distributor.name, from: 'order_distributor_id'
select order_cycle.name, from: 'order_order_cycle_id'
click_button 'Update'
page.should have_selector 'h1', text: 'Customer Details'
o = Spree::Order.last
o.distributor.should == distributor
o.order_cycle.should == order_cycle
o.distributor.should == @distributor
o.order_cycle.should == @order_cycle
end
scenario "can add a product to an existing order", js: true, retry: 3 do
scenario "can add a product to an existing order", retry: 3 do
login_to_admin_section
visit '/admin/orders'
@@ -61,7 +67,29 @@ feature %q{
@order.line_items(true).map(&:product).should include @product
end
scenario "can't add products to an order outside the order's hub and order cycle", js: true do
scenario "displays error when incorrect distribution for products is chosen" do
d = create(:distributor_enterprise)
oc = create(:simple_order_cycle, distributors: [d])
@order.state = 'cart'; @order.completed_at = nil; @order.save
login_to_admin_section
visit '/admin/orders'
uncheck 'Only show complete orders'
click_button 'Filter Results'
click_edit
select d.name, from: 'order_distributor_id'
select2_select oc.name, from: 'order_order_cycle_id'
click_button 'Update And Recalculate Fees'
page.should have_content "Distributor or order cycle cannot supply the products in your cart"
end
scenario "can't add products to an order outside the order's hub and order cycle" do
product = create(:simple_product)
login_to_admin_section
@@ -79,12 +107,42 @@ feature %q{
page.find('td.actions a.icon-edit').click
page.should have_no_select 'order_distributor_id'
page.should have_no_select 'order_order_cycle_id'
page.should_not have_select2 'order_order_cycle_id'
page.should have_selector 'p', text: "Distributor: #{@order.distributor.name}"
page.should have_selector 'p', text: "Order cycle: None"
end
scenario "filling customer details" do
# Given a customer with an order, which includes their shipping and billing address
@order.ship_address = create(:address, lastname: 'Ship')
@order.bill_address = create(:address, lastname: 'Bill')
@order.shipping_method = create(:shipping_method, require_ship_address: true)
@order.save!
# When I create a new order
login_to_admin_section
visit '/admin/orders'
click_link 'New Order'
select @distributor.name, from: 'order_distributor_id'
select2_select @order_cycle.name, from: 'order_order_cycle_id'
targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
click_link 'Add'
page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS
click_button 'Update'
within('h1.page-title') { page.should have_content "Customer Details" }
# And I select that customer's email address and save the order
targetted_select2_search @order.user.email, from: '#customer_search', dropdown_css: '.select2-drop'
click_button 'Continue'
within('h1.page-title') { page.should have_content "Shipments" }
# Then their addresses should be associated with the order
order = Spree::Order.last
order.ship_address.lastname.should == 'Ship'
order.bill_address.lastname.should == 'Bill'
end
scenario "capture multiple payments from the orders index page" do
# d.cook: could also test for an order that has had payment voided, then a new check payment created but not yet captured. But it's not critical and I know it works anyway.
@@ -127,10 +185,13 @@ feature %q{
login_to_admin_as @enterprise_user
end
scenario "creating an order with distributor and order cycle", js: true do
scenario "creating an order with distributor and order cycle" do
visit '/admin/orders'
click_link 'New Order'
select distributor1.name, from: 'order_distributor_id'
select2_select order_cycle1.name, from: 'order_order_cycle_id'
expect(page).to have_content 'ADD PRODUCT'
targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
@@ -141,11 +202,9 @@ feature %q{
expect(page).to have_select 'order_distributor_id', with_options: [distributor1.name]
expect(page).to_not have_select 'order_distributor_id', with_options: [distributor2.name]
expect(page).to have_select 'order_order_cycle_id', with_options: [order_cycle1.name]
expect(page).to_not have_select 'order_order_cycle_id', with_options: [order_cycle2.name]
expect(page).to have_select2 'order_order_cycle_id', with_options: ["#{order_cycle1.name} (open)"]
expect(page).to_not have_select2 'order_order_cycle_id', with_options: ["#{order_cycle2.name} (open)"]
select distributor1.name, from: 'order_distributor_id'
select order_cycle1.name, from: 'order_order_cycle_id'
click_button 'Update'
expect(page).to have_selector 'h1', text: 'Customer Details'

View File

@@ -323,8 +323,8 @@ feature %q{
click_link 'Reports'
click_link 'LettuceShare'
page.should have_table_row ['PRODUCT', 'Description', 'Qty', 'Pack Size', 'Unit', 'Unit Price', 'Total', 'GST incl.', 'Grower and growing method', 'Taxon'].map(&:upcase)
page.should have_table_row ['Product 2', '100g', '', '100', 'g', '99.0', '99.0', '0', 'Supplier Name (Organic - NASAA 12345)', 'Taxon Name']
page.should have_table_row ['PRODUCT', 'Description', 'SKU', 'Qty', 'Pack Size', 'Unit', 'Unit Price', 'Total', 'GST incl.', 'Grower and growing method', 'Taxon'].map(&:upcase)
page.should have_table_row ['Product 2', '100g', 'ABC', '', '100', 'g', '99.0', '', '0', 'Supplier Name (Organic - NASAA 12345)', 'Taxon Name']
end
end

View File

@@ -0,0 +1,40 @@
describe "ordersCtrl", ->
ctrl = null
scope = {}
attrs = {}
shops = []
orderCycles = [
{id: 10, name: 'Ten', status: 'open', distributors: [{id: 1, name: 'One'}]}
{id: 20, name: 'Twenty', status: 'closed', distributors: [{id: 2, name: 'Two', status: 'closed'}]}
]
beforeEach ->
scope = {}
module('admin.orders')
inject ($controller) ->
ctrl = $controller 'ordersCtrl', {$scope: scope, $attrs: attrs, shops: shops, orderCycles: orderCycles}
it "initialises name_and_status", ->
expect(scope.orderCycles[0].name_and_status).toEqual "Ten (open)"
expect(scope.orderCycles[1].name_and_status).toEqual "Twenty (closed)"
describe "finding valid order cycles for a distributor", ->
order_cycle = {id: 10, distributors: [{id: 1, name: 'One'}]}
it "returns true when the order cycle includes the distributor", ->
scope.distributor_id = '1'
expect(scope.validOrderCycle(order_cycle, 1, [order_cycle])).toBe true
it "returns false otherwise", ->
scope.distributor_id = '2'
expect(scope.validOrderCycle(order_cycle, 1, [order_cycle])).toBe false
describe "checking if a distributor has order cycles", ->
it "returns true when it does", ->
distributor = {id: 1}
expect(scope.distributorHasOrderCycles(distributor)).toBe true
it "returns false otherwise", ->
distributor = {id: 3}
expect(scope.distributorHasOrderCycles(distributor)).toBe false

View File

@@ -0,0 +1,58 @@
require 'open_food_network/last_used_address'
module OpenFoodNetwork
describe LastUsedAddress do
let(:email) { 'test@example.com' }
let(:address) { 'address' }
describe "last used bill address" do
let(:lua) { LastUsedAddress.new(email) }
let(:order_with_bill_address) { double(:order, bill_address: address) }
let(:order_without_bill_address) { double(:order, bill_address: nil) }
it "returns the bill address when present" do
lua.stub(:recent_orders) { [order_with_bill_address] }
lua.last_used_bill_address.should == address
end
it "returns nil when there's no order with a bill address" do
lua.stub(:recent_orders) { [order_without_bill_address] }
lua.last_used_bill_address.should be_nil
end
it "returns nil when there are no recent orders" do
lua.stub(:recent_orders) { [] }
lua.last_used_bill_address.should be_nil
end
end
describe "last used ship address" do
let(:lua) { LastUsedAddress.new(email) }
let(:pickup) { double(:shipping_method, require_ship_address: false) }
let(:delivery) { double(:shipping_method, require_ship_address: true) }
let(:order_with_ship_address) { double(:order, ship_address: address, shipping_method: delivery) }
let(:order_with_unrequired_ship_address) { double(:order, ship_address: address, shipping_method: pickup) }
let(:order_without_ship_address) { double(:order, ship_address: nil) }
it "returns the ship address when present" do
lua.stub(:recent_orders) { [order_with_ship_address] }
lua.last_used_ship_address.should == address
end
it "returns nil when the order doesn't require a ship address" do
lua.stub(:recent_orders) { [order_with_unrequired_ship_address] }
lua.last_used_ship_address.should be_nil
end
it "returns nil when there's no order with a ship address" do
lua.stub(:recent_orders) { [order_without_ship_address] }
lua.last_used_ship_address.should be_nil
end
it "returns nil when there are no recent orders" do
lua.stub(:recent_orders) { [] }
lua.last_used_ship_address.should be_nil
end
end
end
end

View File

@@ -27,5 +27,44 @@ module OpenFoodNetwork
report.send(:gst, v).should == 0
end
end
describe "table" do
it "handles no items" do
report.send(:table).should eq []
end
describe "lists" do
let(:v2) { create(:variant) }
let(:v3) { create(:variant) }
let(:v4) { create(:variant, count_on_hand: 0, on_demand: true) }
let(:hub_address) { create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234") }
let(:hub) { create(:distributor_enterprise, :address => hub_address) }
let(:v2o) { create(:variant_override, hub: hub, variant: v2) }
let(:v3o) { create(:variant_override, hub: hub, variant: v3, count_on_hand: 0) }
it "all items" do
report.stub(:variants) { [v, v2, v3] }
report.send(:table).count.should eq 3
end
it "only available items" do
report.stub(:variants) { [v, v2, v3, v4] }
v.count_on_hand = 0
report.send(:table).count.should eq 3
end
it "only available items considering overrides" do
# create the overrides
v2o
v3o
report.stub(:variants) { [v, v2, v3] }
report.stub(:params) { {distributor_id: hub.id} }
rows = report.send(:table)
rows.count.should eq 2
rows[1][0].should eq v2.product.name
end
end
end
end
end

View File

@@ -124,15 +124,16 @@ module OpenFoodNetwork
it "filters to a specific distributor" do
distributor = create(:distributor_enterprise)
product1 = create(:simple_product, supplier: supplier)
product2 = create(:simple_product, supplier: supplier, distributors: [distributor])
product2 = create(:simple_product, supplier: supplier)
order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product2.variants.first])
subject.stub(:params).and_return(distributor_id: distributor.id)
subject.filter(variants).should == [product2.variants.first]
end
it "filters to a specific order cycle" do
distributor = create(:distributor_enterprise)
product1 = create(:simple_product, supplier: supplier, distributors: [distributor])
product2 = create(:simple_product, supplier: supplier, distributors: [distributor])
product1 = create(:simple_product, supplier: supplier)
product2 = create(:simple_product, supplier: supplier)
order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product1.variants.first])
subject.stub(:params).and_return(order_cycle_id: order_cycle.id)
@@ -141,8 +142,8 @@ module OpenFoodNetwork
it "should do all the filters at once" do
distributor = create(:distributor_enterprise)
product1 = create(:simple_product, supplier: supplier, distributors: [distributor])
product2 = create(:simple_product, supplier: supplier, distributors: [distributor])
product1 = create(:simple_product, supplier: supplier)
product2 = create(:simple_product, supplier: supplier)
order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product1.variants.first])
subject.stub(:params).and_return(

View File

@@ -28,15 +28,43 @@ RSpec::Matchers.define :have_select2 do |id, options={}|
end
failure_message_for_should do |actual|
message = "expected to find select2 ##{@id}"
message = "expected to find select2 ##{@id}"
message += " with #{@options.inspect}" if @options.any?
message
end
match_for_should_not do |node|
raise "Not yet implemented"
@id, @options, @node = id, options, node
#id = find_label_by_text(locator)
from = "#s2id_#{id}"
results = []
results << node.has_no_selector?(from, wait: 1)
# if results.all?
# results << selected_option_is(from, options[:selected]) if options.key? :selected
# end
if results.none?
results << all_options_absent(from, options[:with_options]) if options.key? :with_options
#results << exact_options_present(from, options[:options]) if options.key? :options
#results << no_options_present(from, options[:without_options]) if options.key? :without_options
end
if (options.keys & %i(selected options without_options)).any?
raise "Not yet implemented"
end
results.any?
end
failure_message_for_should_not do |actual|
message = "expected not to find select2 ##{@id}"
message += " with #{@options.inspect}" if @options.any?
message
end
def all_options_present(from, options)
with_select2_open(from) do
@@ -46,6 +74,14 @@ RSpec::Matchers.define :have_select2 do |id, options={}|
end
end
def all_options_absent(from, options)
with_select2_open(from) do
options.all? do |option|
@node.has_no_selector? "div.select2-drop-active ul.select2-results li", text: option
end
end
end
def exact_options_present(from, options)
with_select2_open(from) do
@node.all("div.select2-drop-active ul.select2-results li").map(&:text) == options