mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge branch 'master' into combined/bulk-product-edit-and-ng-cloak
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
class GroupsController < BaseController
|
||||
layout 'darkswarm'
|
||||
before_filter :load_active_distributors
|
||||
|
||||
def index
|
||||
@groups = EnterpriseGroup.on_front_page.by_position
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
class HomeController < BaseController
|
||||
layout 'darkswarm'
|
||||
before_filter :load_active_distributors
|
||||
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def about_us
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
class MapController < BaseController
|
||||
layout 'darkswarm'
|
||||
before_filter :load_active_distributors
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
class ProducersController < BaseController
|
||||
layout 'darkswarm'
|
||||
before_filter :load_active_distributors
|
||||
|
||||
|
||||
def index
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
object current_distributor
|
||||
extends 'json/partials/enterprise'
|
||||
|
||||
child suppliers: :producers do
|
||||
attributes :id
|
||||
end
|
||||
@@ -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
|
||||
|
||||
27
lib/open_food_network/enterprise_injection_data.rb
Normal file
27
lib/open_food_network/enterprise_injection_data.rb
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
17
spec/lib/open_food_network/enterprise_injection_data_spec.rb
Normal file
17
spec/lib/open_food_network/enterprise_injection_data_spec.rb
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
28
spec/models/spree/taxon_spec.rb
Normal file
28
spec/models/spree/taxon_spec.rb
Normal 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
|
||||
29
spec/performance/injection_helper_spec.rb
Normal file
29
spec/performance/injection_helper_spec.rb
Normal 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
|
||||
46
spec/performance/shop_controller_spec.rb
Normal file
46
spec/performance/shop_controller_spec.rb
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user