Merge branch 'master' into combined/bulk-product-edit-and-ng-cloak

This commit is contained in:
Rohan Mitchell
2015-06-03 15:05:51 +10:00
39 changed files with 471 additions and 127 deletions

View File

@@ -32,8 +32,9 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
if product.variants
product.variants = (Variants.register variant for variant in product.variants)
variant.product = product for variant in product.variants
product.master.product = product
product.master = Variants.register product.master if product.master
if product.master
product.master.product = product
product.master = Variants.register product.master
registerVariantsWithCart: ->
for product in @products

View File

@@ -12,9 +12,6 @@ class BaseController < ApplicationController
before_filter :check_order_cycle_expiry
def load_active_distributors
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
end
private

View File

@@ -12,9 +12,6 @@ class CheckoutController < Spree::CheckoutController
include EnterprisesHelper
def edit
# Because this controller doesn't inherit from our BaseController
# We need to duplicate the code here
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
end
def update

View File

@@ -4,7 +4,7 @@ class EnterprisesController < BaseController
include OrderCyclesHelper
# These prepended filters are in the reverse order of execution
prepend_before_filter :load_active_distributors, :set_order_cycles, :require_distributor_chosen, :reset_order, only: :shop
prepend_before_filter :set_order_cycles, :require_distributor_chosen, :reset_order, only: :shop
before_filter :clean_permalink, only: :check_permalink
respond_to :js, only: :permalink_checker

View File

@@ -1,6 +1,5 @@
class GroupsController < BaseController
layout 'darkswarm'
before_filter :load_active_distributors
def index
@groups = EnterpriseGroup.on_front_page.by_position

View File

@@ -1,11 +1,9 @@
class HomeController < BaseController
layout 'darkswarm'
before_filter :load_active_distributors
def index
end
def about_us
end
end

View File

@@ -1,6 +1,5 @@
class MapController < BaseController
layout 'darkswarm'
before_filter :load_active_distributors
def index
end

View File

@@ -1,7 +1,6 @@
class ProducersController < BaseController
layout 'darkswarm'
before_filter :load_active_distributors
def index
end
end

View File

@@ -10,12 +10,16 @@ class ShopController < BaseController
end
def products
# Can we make this query less slow?
#
if @products = products_for_shop
render status: 200,
json: ActiveModel::ArraySerializer.new(@products, each_serializer: Api::ProductSerializer,
current_order_cycle: current_order_cycle, current_distributor: current_distributor).to_json
json: ActiveModel::ArraySerializer.new(@products,
each_serializer: Api::ProductSerializer,
current_order_cycle: current_order_cycle,
current_distributor: current_distributor,
variants: variants_for_shop_by_id,
master_variants: master_variants_for_shop_by_id).to_json
else
render json: "", status: 404
end
@@ -56,4 +60,30 @@ class ShopController < BaseController
"name ASC"
end
end
def all_variants_for_shop
# We use the in_stock? method here instead of the in_stock scope because we need to
# look up the stock as overridden by VariantOverrides, and the scope method is not affected
# by them.
Spree::Variant.
for_distribution(current_order_cycle, current_distributor).
each { |v| v.scope_to_hub current_distributor }.
select(&:in_stock?)
end
def variants_for_shop_by_id
index_by_product_id all_variants_for_shop.reject(&:is_master)
end
def master_variants_for_shop_by_id
index_by_product_id all_variants_for_shop.select(&:is_master)
end
def index_by_product_id(variants)
variants.inject({}) do |vs, v|
vs[v.product_id] ||= []
vs[v.product_id] << v
vs
end
end
end

View File

@@ -1,6 +1,16 @@
require 'open_food_network/enterprise_injection_data'
module InjectionHelper
def inject_enterprises
inject_json_ams "enterprises", Enterprise.activated.all, Api::EnterpriseSerializer, active_distributors: @active_distributors
inject_json_ams "enterprises", Enterprise.activated.includes(:address).all, Api::EnterpriseSerializer, enterprise_injection_data
end
def inject_group_enterprises
inject_json_ams "group_enterprises", @group.enterprises, Api::EnterpriseSerializer, enterprise_injection_data
end
def inject_current_hub
inject_json_ams "currentHub", current_distributor, Api::EnterpriseSerializer, enterprise_injection_data
end
def inject_current_order
@@ -53,4 +63,13 @@ module InjectionHelper
end
render partial: "json/injection_ams", locals: {name: name, json: json}
end
private
def enterprise_injection_data
@enterprise_injection_data ||= OpenFoodNetwork::EnterpriseInjectionData.new
{data: @enterprise_injection_data}
end
end

View File

@@ -178,6 +178,10 @@ class Enterprise < ActiveRecord::Base
count(distinct: true)
end
def activated?
confirmed_at.present? && sells != 'unspecified'
end
def set_producer_property(property_name, property_value)
transaction do
property = Spree::Property.where(name: property_name).first_or_create!(presentation: property_name)

View File

@@ -25,6 +25,32 @@ class EnterpriseRelationship < ActiveRecord::Base
scope :by_name, with_enterprises.order('child_enterprises.name, parent_enterprises.name')
# Load an array of the relatives of each enterprise (ie. any enterprise related to it in
# either direction). This array is split into distributors and producers, and has the format:
# {enterprise_id => {distributors: [id, ...], producers: [id, ...]} }
def self.relatives(activated_only=false)
relationships = EnterpriseRelationship.includes(:child, :parent)
relatives = {}
relationships.each do |r|
relatives[r.parent_id] ||= {distributors: Set.new, producers: Set.new}
relatives[r.child_id] ||= {distributors: Set.new, producers: Set.new}
if !activated_only || r.child.activated?
relatives[r.parent_id][:producers] << r.child_id if r.child.is_primary_producer
relatives[r.parent_id][:distributors] << r.child_id if r.child.is_distributor
end
if !activated_only || r.parent.activated?
relatives[r.child_id][:producers] << r.parent_id if r.parent.is_primary_producer
relatives[r.child_id][:distributors] << r.parent_id if r.parent.is_distributor
end
end
relatives
end
def permissions_list=(perms)
perms.andand.each { |name| permissions.build name: name }
end

View File

@@ -92,11 +92,25 @@ class OrderCycle < ActiveRecord::Base
with_distributor(distributor).soonest_closing.first
end
def self.most_recently_closed_for(distributor)
with_distributor(distributor).most_recently_closed.first
end
# Find the earliest closing times for each distributor in an active order cycle, and return
# them in the format {distributor_id => closing_time, ...}
def self.earliest_closing_times
Hash[
Exchange.
outgoing.
joins(:order_cycle).
merge(OrderCycle.active).
group('exchanges.receiver_id').
select('exchanges.receiver_id AS receiver_id, MIN(order_cycles.orders_close_at) AS earliest_close_at').
map { |ex| [ex.receiver_id, ex.earliest_close_at.to_time] }
]
end
def clone!
oc = self.dup
oc.name = "COPY OF #{oc.name}"

View File

@@ -25,6 +25,22 @@ Spree::ShippingMethod.class_eval do
scope :by_name, order('spree_shipping_methods.name ASC')
# Return the services (pickup, delivery) that different distributors provide, in the format:
# {distributor_id => {pickup: true, delivery: false}, ...}
def self.services
Hash[
Spree::ShippingMethod.
joins(:distributor_shipping_methods).
group('distributor_id').
select("distributor_id").
select("BOOL_OR(spree_shipping_methods.require_ship_address = 'f') AS pickup").
select("BOOL_OR(spree_shipping_methods.require_ship_address = 't') AS delivery").
map { |sm| [sm.distributor_id.to_i, {pickup: sm.pickup == 't', delivery: sm.delivery == 't'}] }
]
end
def available_to_order_with_distributor_check?(order, display_on=nil)
available_to_order_without_distributor_check?(order, display_on) &&
self.distributors.include?(order.distributor)

View File

@@ -9,4 +9,40 @@ Spree::Taxon.class_eval do
#fs << Spree::ProductFilters.distributor_filter if Spree::ProductFilters.respond_to? :distributor_filter
fs
end
# Find all the taxons of supplied products for each enterprise, indexed by enterprise.
# Format: {enterprise_id => [taxon_id, ...]}
def self.supplied_taxons
taxons = {}
Spree::Taxon.
joins(:products => :supplier).
select('spree_taxons.*, enterprises.id AS enterprise_id').
each do |t|
taxons[t.enterprise_id.to_i] ||= Set.new
taxons[t.enterprise_id.to_i] << t.id
end
taxons
end
# Find all the taxons of distributed products for each enterprise, indexed by enterprise.
# Format: {enterprise_id => [taxon_id, ...]}
def self.distributed_taxons
taxons = {}
Spree::Taxon.
joins(:products).
merge(Spree::Product.with_order_cycles_outer).
where('o_exchanges.incoming = ?', false).
select('spree_taxons.*, o_exchanges.receiver_id AS enterprise_id').
each do |t|
taxons[t.enterprise_id.to_i] ||= Set.new
taxons[t.enterprise_id.to_i] << t.id
end
taxons
end
end

View File

@@ -1,4 +1,7 @@
class Api::EnterpriseSerializer < ActiveModel::Serializer
# We reference this here because otherwise the serializer complains about its absence
Api::IdSerializer
def serializable_hash
cached_serializer_hash.merge uncached_serializer_hash
end
@@ -6,11 +9,11 @@ class Api::EnterpriseSerializer < ActiveModel::Serializer
private
def cached_serializer_hash
Api::CachedEnterpriseSerializer.new(object, @options).serializable_hash
Api::CachedEnterpriseSerializer.new(object, @options).serializable_hash || {}
end
def uncached_serializer_hash
Api::UncachedEnterpriseSerializer.new(object, @options).serializable_hash
Api::UncachedEnterpriseSerializer.new(object, @options).serializable_hash || {}
end
end
@@ -18,19 +21,22 @@ class Api::UncachedEnterpriseSerializer < ActiveModel::Serializer
attributes :orders_close_at, :active
def orders_close_at
OrderCycle.first_closing_for(object).andand.orders_close_at
options[:data].earliest_closing_times[object.id]
end
def active
@options[:active_distributors].andand.include? object
options[:data].active_distributors.andand.include? object
end
end
class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
cached
delegate :cache_key, to: :object
#delegate :cache_key, to: :object
def cache_key
object.andand.cache_key
end
attributes :name, :id, :description, :latitude, :longitude,
:long_description, :website, :instagram, :linkedin, :twitter,
@@ -38,17 +44,27 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
:email, :hash, :logo, :promo_image, :path, :pickup, :delivery,
:icon, :icon_font, :producer_icon_font, :category, :producers, :hubs
has_many :distributed_taxons, key: :taxons, serializer: Api::IdSerializer
has_many :supplied_taxons, serializer: Api::IdSerializer
attributes :taxons, :supplied_taxons
has_one :address, serializer: Api::AddressSerializer
def taxons
ids_to_objs options[:data].distributed_taxons[object.id]
end
def supplied_taxons
ids_to_objs options[:data].supplied_taxons[object.id]
end
def pickup
object.shipping_methods.where(:require_ship_address => false).present?
services = options[:data].shipping_method_services[object.id]
services ? services[:pickup] : false
end
def delivery
object.shipping_methods.where(:require_ship_address => true).present?
services = options[:data].shipping_method_services[object.id]
services ? services[:delivery] : false
end
def email
@@ -72,11 +88,13 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
end
def producers
ActiveModel::ArraySerializer.new(object.suppliers.activated, {each_serializer: Api::IdSerializer})
relatives = options[:data].relatives[object.id]
relatives ? ids_to_objs(relatives[:producers]) : []
end
def hubs
ActiveModel::ArraySerializer.new(object.distributors.activated, {each_serializer: Api::IdSerializer})
relatives = options[:data].relatives[object.id]
relatives ? ids_to_objs(relatives[:distributors]) : []
end
# Map svg icons.
@@ -116,4 +134,11 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
}
icon_fonts[object.category]
end
private
def ids_to_objs(ids)
ids.andand.map { |id| {id: id} }
end
end

View File

@@ -30,8 +30,9 @@ class Api::CachedProductSerializer < ActiveModel::Serializer
#cached
#delegate :cache_key, to: :object
attributes :id, :name, :permalink, :count_on_hand, :on_demand, :group_buy,
:notes, :description, :properties_with_values
attributes :id, :name, :permalink, :count_on_hand
attributes :on_demand, :group_buy, :notes, :description
attributes :properties_with_values
has_many :variants, serializer: Api::VariantSerializer
has_many :taxons, serializer: Api::IdSerializer
@@ -46,13 +47,11 @@ class Api::CachedProductSerializer < ActiveModel::Serializer
end
def variants
# We use the in_stock? method here instead of the in_stock scope because we need to
# look up the stock as overridden by VariantOverrides, and the scope method is not affected
# by them.
object.variants.
for_distribution(options[:current_order_cycle], options[:current_distributor]).
each { |v| v.scope_to_hub options[:current_distributor] }.
select(&:in_stock?)
options[:variants][object.id] || []
end
def master
options[:master_variants][object.id].andand.first
end
end

View File

@@ -3,8 +3,8 @@
= inject_enterprises
-# inject enterprises in this group
-# further hubs and producers of these enterprises can't be resoleved within this small subset
= inject_json_ams "group_enterprises", @group.enterprises, Api::EnterpriseSerializer, active_distributors: @active_distributors
-# further hubs and producers of these enterprises can't be resolved within this small subset
= inject_group_enterprises
#group-page.row.pad-top{"ng-controller" => "GroupPageCtrl"}
.small-12.columns.pad-top
@@ -95,7 +95,7 @@
= render partial: 'home/fat'
= render partial: 'shared/components/enterprise_no_results'
.small-12.medium-12.large-3.columns
= render partial: 'contact'

View File

@@ -1,6 +0,0 @@
object current_distributor
extends 'json/partials/enterprise'
child suppliers: :producers do
attributes :id
end

View File

@@ -24,7 +24,7 @@
= render partial: "shared/ie_warning"
= javascript_include_tag "iehack"
= inject_json "currentHub", "current_hub"
= inject_current_hub
= inject_json "user", "current_user"
= inject_json "railsFlash", "flash"
= inject_taxons

View File

@@ -0,0 +1,27 @@
module OpenFoodNetwork
class EnterpriseInjectionData
def active_distributors
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
end
def earliest_closing_times
@earliest_closing_times ||= OrderCycle.earliest_closing_times
end
def shipping_method_services
@shipping_method_services ||= Spree::ShippingMethod.services
end
def relatives
@relatives ||= EnterpriseRelationship.relatives(true)
end
def supplied_taxons
@supplied_taxons ||= Spree::Taxon.supplied_taxons
end
def distributed_taxons
@distributed_taxons ||= Spree::Taxon.distributed_taxons
end
end
end

View File

@@ -6,5 +6,9 @@ source ./script/ci/includes.sh
echo "--- Verifying branch is based on current master"
exit_unless_master_merged
echo "--- Pushing branch"
git push origin $BUILDKITE_COMMIT:master
echo "--- Merging and pushing branch"
git checkout master
git merge origin/master
git merge origin/$BUILDKITE_BRANCH
git push origin master
git checkout origin/$BUILDKITE_BRANCH

View File

@@ -16,4 +16,4 @@ echo "--- Loading test database"
bundle exec rake db:test:load
echo "--- Running tests"
bundle exec rspec spec
bundle exec rspec --tag ~performance spec

View File

@@ -24,9 +24,4 @@ describe BaseController do
response.should redirect_to root_url
flash[:info].should == "The order cycle you've selected has just closed. Please try again!"
end
it "loads active_distributors" do
Enterprise.stub(:distributors_with_active_order_cycles) { 'active distributors' }
controller.load_active_distributors.should == 'active distributors'
end
end

View File

@@ -9,21 +9,9 @@ describe HomeController do
Enterprise.stub(:distributors_with_active_order_cycles) { [distributor] }
end
it "sets active distributors" do
get :index
assigns[:active_distributors].should == [distributor]
end
# Exclusion from actual rendered view handled in features/consumer/home
it "shows JSON for invisible hubs" do
get :index
response.body.should have_content invisible_distributor.name
end
# This is done inside the json/hubs Serializer
it "gets the next order cycle for each hub" do
OrderCycle.should_receive(:first_closing_for).twice
get :index
end
end

View File

@@ -1,13 +0,0 @@
require 'spec_helper'
describe MapController do
it "loads active distributors" do
active_distributors = double(:distributors)
Enterprise.stub(:distributors_with_active_order_cycles) { active_distributors }
get :index
assigns(:active_distributors).should == active_distributors
end
end

View File

@@ -1,15 +0,0 @@
require 'spec_helper'
describe ProducersController do
let!(:distributor) { create(:distributor_enterprise) }
before do
Enterprise.stub(:distributors_with_active_order_cycles) { [distributor] }
Enterprise.stub(:all).and_return([distributor])
end
it "sets active distributors" do
get :index
assigns[:active_distributors].should == [distributor]
end
end

View File

@@ -176,4 +176,18 @@ describe ShopController do
end
end
end
describe "loading variants" do
let(:hub) { create(:distributor_enterprise) }
let(:oc) { create(:simple_order_cycle, distributors: [hub], variants: [v1]) }
let(:p) { create(:simple_product) }
let!(:v1) { create(:variant, product: p, unit_value: 3) }
let!(:v2) { create(:variant, product: p, unit_value: 5) }
it "scopes variants to distribution" do
controller.stub(:current_order_cycle) { oc }
controller.stub(:current_distributor) { hub }
controller.send(:variants_for_shop_by_id).should == {p.id => [v1]}
end
end
end

View File

@@ -205,8 +205,9 @@ feature %q{
expect(page).to have_selector "a.edit-variant", count: 1
# When I remove two, they should be removed
page.all('a.delete-variant').first.click
page.all('a.delete-variant').first.click
page.all('a.delete-variant', visible: true).first.click
expect(page).to have_selector "tr.variant", count: 2
page.all('a.delete-variant', visible: true).first.click
expect(page).to have_selector "tr.variant", count: 1
# When I fill out variant details and hit update

View File

@@ -4,7 +4,7 @@ describe InjectionHelper do
let!(:enterprise) { create(:distributor_enterprise, facebook: "roger") }
it "will inject via AMS" do
helper.inject_json_ams("test", [enterprise], Api::EnterpriseSerializer).should match enterprise.name
helper.inject_json_ams("test", [enterprise], Api::IdSerializer).should match /#{enterprise.id}/
end
it "injects enterprises" do

View File

@@ -0,0 +1,17 @@
require 'spec_helper'
module OpenFoodNetwork
describe EnterpriseInjectionData do
describe "relatives" do
let!(:enterprise) { create(:distributor_enterprise) }
let!(:producer) { create(:supplier_enterprise) }
let!(:producer_inactive) { create(:supplier_enterprise, confirmed_at: nil) }
let!(:er_p) { create(:enterprise_relationship, parent: producer, child: enterprise) }
let!(:er_pi) { create(:enterprise_relationship, parent: producer_inactive, child: enterprise) }
it "only loads activated relatives" do
subject.relatives[enterprise.id][:producers].should_not include producer_inactive.id
end
end
end
end

View File

@@ -69,4 +69,32 @@ describe EnterpriseRelationship do
EnterpriseRelationship.with_permission('two').should match_array [er1, er2]
end
end
describe "finding relatives" do
let(:e1) { create(:supplier_enterprise) }
let(:e2) { create(:supplier_enterprise, sells: 'any') }
let!(:er) { create(:enterprise_relationship, parent: e1, child: e2) }
let(:er_reverse) { create(:enterprise_relationship, parent: e2, child: e1) }
it "categorises enterprises into distributors and producers" do
EnterpriseRelationship.relatives.should ==
{e1.id => {distributors: Set.new([e2.id]), producers: Set.new([e2.id])},
e2.id => {distributors: Set.new([]), producers: Set.new([e1.id])}}
end
it "finds inactive enterprises by default" do
e1.update_attribute :confirmed_at, nil
EnterpriseRelationship.relatives[e2.id][:producers].should == Set.new([e1.id])
end
it "does not find inactive enterprises when requested" do
e1.update_attribute :confirmed_at, nil
EnterpriseRelationship.relatives(true)[e2.id][:producers].should be_empty
end
it "does not show duplicates" do
er_reverse
EnterpriseRelationship.relatives[e2.id][:producers].should == Set.new([e1.id])
end
end
end

View File

@@ -422,4 +422,23 @@ describe OrderCycle do
OrderCycle.first_closing_for(distributor).should == oc
end
end
describe "finding the earliest closing times for each distributor" do
let(:time1) { 1.week.from_now }
let(:time2) { 2.weeks.from_now }
let(:time3) { 3.weeks.from_now }
let(:e1) { create(:distributor_enterprise) }
let(:e2) { create(:distributor_enterprise) }
let!(:oc1) { create(:simple_order_cycle, orders_close_at: time1, distributors: [e1]) }
let!(:oc2) { create(:simple_order_cycle, orders_close_at: time2, distributors: [e2]) }
let!(:oc3) { create(:simple_order_cycle, orders_close_at: time3, distributors: [e2]) }
it "returns the closing time, indexed by enterprise id" do
OrderCycle.earliest_closing_times[e1.id].should == time1
end
it "returns the earliest closing time" do
OrderCycle.earliest_closing_times[e2.id].should == time2
end
end
end

View File

@@ -55,5 +55,32 @@ module Spree
sm.should be_available_to_order o
end
end
describe "finding services offered by all distributors" do
let!(:d1) { create(:distributor_enterprise) }
let!(:d2) { create(:distributor_enterprise) }
let!(:d3) { create(:distributor_enterprise) }
let!(:d4) { create(:distributor_enterprise) }
let!(:d1_pickup) { create(:shipping_method, require_ship_address: false, distributors: [d1]) }
let!(:d1_delivery) { create(:shipping_method, require_ship_address: true, distributors: [d1]) }
let!(:d2_pickup) { create(:shipping_method, require_ship_address: false, distributors: [d2]) }
let!(:d3_delivery) { create(:shipping_method, require_ship_address: true, distributors: [d3]) }
it "reports when the services are available" do
ShippingMethod.services[d1.id].should == {pickup: true, delivery: true}
end
it "reports when only pickup is available" do
ShippingMethod.services[d2.id].should == {pickup: true, delivery: false}
end
it "reports when only delivery is available" do
ShippingMethod.services[d3.id].should == {pickup: false, delivery: true}
end
it "returns no entry when no service is available" do
ShippingMethod.services[d4.id].should be_nil
end
end
end
end

View File

@@ -0,0 +1,28 @@
require 'spec_helper'
module Spree
describe Taxon do
let(:e) { create(:supplier_enterprise) }
let(:t0) { p1.taxons.order('id ASC').first }
let(:t1) { create(:taxon) }
let(:t2) { create(:taxon) }
describe "finding all supplied taxons" do
let!(:p1) { create(:simple_product, supplier: e, taxons: [t1, t2]) }
it "finds taxons" do
Taxon.supplied_taxons.should == {e.id => Set.new([t0.id, t1.id, t2.id])}
end
end
describe "finding all distributed taxons" do
let!(:oc) { create(:simple_order_cycle, distributors: [e], variants: [p1.master]) }
let(:s) { create(:supplier_enterprise) }
let(:p1) { create(:simple_product, supplier: s, taxons: [t1, t2]) }
it "finds taxons" do
Taxon.distributed_taxons.should == {e.id => Set.new([t0.id, t1.id, t2.id])}
end
end
end
end

View File

@@ -0,0 +1,29 @@
require 'spec_helper'
describe InjectionHelper, type: :helper, performance: true do
let(:oc) { create(:simple_order_cycle) }
let(:relative_supplier) { create(:supplier_enterprise) }
let(:relative_distributor) { create(:distributor_enterprise) }
before do
50.times do
e = create(:enterprise)
oc.distributors << e
create(:enterprise_relationship, parent: e, child: relative_supplier)
create(:enterprise_relationship, parent: e, child: relative_distributor)
end
end
it "is performant in injecting enterprises" do
results = []
4.times do |i|
ActiveRecord::Base.connection.query_cache.clear
Rails.cache.clear
result = Benchmark.measure { helper.inject_enterprises }
results << result.total if i > 0
puts result
end
puts (results.sum / results.count * 1000).round 0
end
end

View File

@@ -0,0 +1,46 @@
require 'spec_helper'
describe ShopController, type: :controller, performance: true do
let(:d) { create(:distributor_enterprise) }
let(:enterprise_fee) { create(:enterprise_fee) }
let(:order_cycle) { create(:simple_order_cycle, distributors: [d], coordinator_fees: [enterprise_fee]) }
before do
controller.stub(:current_distributor) { d }
controller.stub(:current_order_cycle) { order_cycle }
end
describe "fetching products" do
let(:exchange) { order_cycle.exchanges.to_enterprises(d).outgoing.first }
let(:image) { File.open(File.expand_path('../../../app/assets/images/logo.jpg', __FILE__)) }
before do
11.times do
p = create(:simple_product)
p.set_property 'Organic Certified', 'NASAA 12345'
v1 = create(:variant, product: p)
v2 = create(:variant, product: p)
Spree::Image.create! viewable_id: p.master.id, viewable_type: 'Spree::Variant', attachment: image
exchange.variants << [v1, v2]
end
end
it "returns products via json" do
results = []
4.times do |i|
ActiveRecord::Base.connection.query_cache.clear
Rails.cache.clear
result = Benchmark.measure do
xhr :get, :products
response.should be_success
end
results << result.total if i > 0
puts result
end
puts (results.sum / results.count * 1000).round 0
end
end
end

View File

@@ -1,21 +1,31 @@
#require 'spec_helper'
describe Api::EnterpriseSerializer do
let(:serializer) { Api::EnterpriseSerializer.new enterprise, data: data }
let(:enterprise) { create(:distributor_enterprise) }
let(:taxon) { create(:taxon) }
let(:data) { OpenStruct.new(earliest_closing_times: {},
active_distributors: [],
distributed_taxons: {enterprise.id => [123]},
supplied_taxons: {enterprise.id => [456]},
shipping_method_services: {},
relatives: {enterprise.id => {producers: [123], distributors: [456]}}) }
it "serializes an enterprise" do
serializer = Api::EnterpriseSerializer.new enterprise
serializer.to_json.should match enterprise.name
end
it "includes distributed taxons" do
enterprise.stub(:distributed_taxons).and_return [taxon]
serializer = Api::EnterpriseSerializer.new enterprise
serializer.to_json.should match taxon.id.to_s
it "serializes taxons as ids only" do
serializer.serializable_hash[:taxons].should == [{id: 123}]
serializer.serializable_hash[:supplied_taxons].should == [{id: 456}]
end
it "will render urls" do
serializer = Api::EnterpriseSerializer.new enterprise
it "serializes producers and hubs as ids only" do
serializer.serializable_hash[:producers].should == [{id: 123}]
serializer.serializable_hash[:hubs].should == [{id: 456}]
end
it "serializes icons" do
serializer.to_json.should match "map_005-hub.svg"
end
end

View File

@@ -1,14 +0,0 @@
describe Api::ProductSerializer do
let(:hub) { create(:distributor_enterprise) }
let(:oc) { create(:simple_order_cycle, distributors: [hub], variants: [v1]) }
let(:p) { create(:simple_product) }
let!(:v1) { create(:variant, product: p, unit_value: 3) }
let!(:v2) { create(:variant, product: p, unit_value: 5) }
it "scopes variants to distribution" do
s = Api::ProductSerializer.new p, current_distributor: hub, current_order_cycle: oc
json = s.to_json
json.should include v1.options_text
json.should_not include v2.options_text
end
end