Merge branch 'master' into ent_types_frontend

This commit is contained in:
Rafael Schouten
2014-09-25 10:09:42 +10:00
37 changed files with 402 additions and 111 deletions

View File

@@ -42,6 +42,7 @@ gem 'gmaps4rails'
gem 'spinjs-rails'
gem 'rack-ssl', :require => 'rack/ssl'
gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg'
gem 'angularjs-file-upload-rails', '~> 1.1.0'
gem 'foreigner'
gem 'immigrant'

View File

@@ -153,6 +153,7 @@ GEM
railties (>= 3.1)
sprockets
tilt
angularjs-file-upload-rails (1.1.0)
angularjs-rails (1.2.13)
ansi (1.4.2)
arel (3.0.3)
@@ -505,6 +506,7 @@ DEPENDENCIES
active_model_serializers
andand
angular-rails-templates
angularjs-file-upload-rails (~> 1.1.0)
angularjs-rails
awesome_print
aws-sdk

View File

@@ -15,6 +15,8 @@
#= require ../shared/bindonce.min.js
#= require ../shared/ng-infinite-scroll.min.js
#= require ../shared/angular-local-storage.js
#= require angularjs-file-upload
#= require angular-rails-templates
#= require_tree ../templates

View File

@@ -0,0 +1,13 @@
angular.module('Darkswarm').controller "EnterpriseImageCtrl", ($scope, EnterpriseImageService) ->
$scope.imageStep = 'logo'
$scope.imageSteps = ['logo', 'promo']
$scope.imageUploader = EnterpriseImageService.imageUploader
$scope.imageSelect = (image_step) ->
EnterpriseImageService.imageSrc = null
$scope.imageStep = image_step
$scope.imageSrc = ->
EnterpriseImageService.imageSrc

View File

@@ -12,4 +12,4 @@ Darkswarm.controller "RegistrationFormCtrl", ($scope, RegistrationService, Enter
EnterpriseRegistrationService.update(nextStep) if $scope.valid(form)
$scope.selectIfValid = (nextStep, form) ->
RegistrationService.select(nextStep) if $scope.valid(form)
RegistrationService.select(nextStep) if $scope.valid(form)

View File

@@ -1,18 +1,19 @@
window.Darkswarm = angular.module("Darkswarm", ["ngResource",
'mm.foundation',
'angularLocalStorage',
'pasvaz.bindonce',
'infinite-scroll',
'angular-flash.service',
window.Darkswarm = angular.module("Darkswarm", ["ngResource",
'mm.foundation',
'angularLocalStorage',
'pasvaz.bindonce',
'infinite-scroll',
'angular-flash.service',
'templates',
'ngSanitize',
'ngAnimate',
'google-maps',
'duScroll',
'angularFileUpload',
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
# This allows us to trigger these two events on tooltips
@@ -20,4 +21,3 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
# We manually handle our scrolling
$anchorScrollProvider.disableAutoScrolling()

View File

@@ -0,0 +1,12 @@
Darkswarm.factory "EnterpriseImageService", (FileUploader, spreeApiKey) ->
new class EnterpriseImageService
imageSrc: null
imageUploader: new FileUploader
headers:
'X-Spree-Token': spreeApiKey
autoUpload: true
configure: (enterprise) =>
@imageUploader.url = "/api/enterprises/#{enterprise.id}/update_image"
@imageUploader.onSuccessItem = (image, response) => @imageSrc = response

View File

@@ -1,4 +1,4 @@
Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService, CurrentUser, spreeApiKey, Loading, availableCountries, enterpriseAttributes) ->
Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService, EnterpriseImageService, CurrentUser, spreeApiKey, Loading, availableCountries, enterpriseAttributes) ->
new class EnterpriseRegistrationService
enterprise:
user_ids: [CurrentUser.id]
@@ -22,6 +22,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
).success((data) =>
Loading.clear()
@enterprise.id = data
EnterpriseImageService.configure(@enterprise)
RegistrationService.select('about')
).error((data) =>
Loading.clear()
@@ -54,4 +55,4 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
enterprise[key] = value
enterprise.address_attributes = @enterprise.address if @enterprise.address?
enterprise.address_attributes.country_id = @enterprise.country.id if @enterprise.country?
enterprise
enterprise

View File

@@ -1,4 +1,4 @@
Darkswarm.factory "RegistrationService", (Navigation, $modal, Loading)->
angular.module('Darkswarm').factory "RegistrationService", (Navigation, $modal, Loading)->
new class RegistrationService
constructor: ->
@@ -20,4 +20,4 @@ Darkswarm.factory "RegistrationService", (Navigation, $modal, Loading)->
close: ->
Loading.message = "Taking you back to the home page"
Navigation.go "/"
Navigation.go "/"

View File

@@ -9,7 +9,7 @@
{{ enterprise.name }}
%ng-include{ src: "'registration/steps.html'" }
%form{ name: 'about', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('social',about)" } }
%form{ name: 'about', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('images',about)" } }
.row
.small-12.columns
.alert-box.alert{"data-alert" => ""}

View File

@@ -1,14 +1,20 @@
.container#registration-images
.container#registration-images{ 'nv-file-drop' => true, uploader: "imageUploader", options:"{ alias: imageStep }", ng: { controller: "EnterpriseImageCtrl" } }
.header
%h2 Thanks!
%h5 Let's upload some pretty pictures so your profile looks great! :)
%ng-include{ src: "'registration/steps.html'" }
.row.content
%form{ name: 'images', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "select('social')" } }
.row{ ng: { repeat: 'image_step in imageSteps', show: "imageStep == image_step" } }
%ng-include{ src: "'registration/images/'+ image_step + '.html'" }
.row.buttons
.small-12.columns
%input.button.primary.left{ type: "button", value: "Back", ng: { click: "select('about')" } }
 
%input.button.primary.right{ type: "button", value: "Continue", ng: { click: "select('social')" } }
.row.buttons.pad-top{ ng: { if: "imageStep == 'logo'" } }
.small-12.columns
%input.button.primary{ type: "button", value: "Back", ng: { click: "select('about')" } }
 
%input.button.primary{ type: "button", value: "Continue", ng: { click: "imageSelect('promo')" } }
.row.buttons.pad-top{ ng: { if: "imageStep == 'promo'" } }
.small-12.columns
%input.button.primary{ type: "button", value: "Back", ng: { click: "imageSelect('logo')" } }
 
%input.button.primary{ type: "submit", value: "Continue" }

View File

@@ -0,0 +1,41 @@
.small-12.medium-12.large-6.columns
.row
.small-12.columns.center
.row
.small-12.columns.center
%h4
Step 1. Select Logo Image
.row
.small-12.columns.center
%span.small
Tip: Square images will work best, preferably at least 300×300px
.row.pad-top
.small-12.columns
.image-select.small-12.columns
%label.small-12.columns.button{ for: 'image-select' } Choose a logo image
%input#image-select{ type: 'file', hidden: true, 'nv-file-select' => true, uploader: "imageUploader", options: '{ alias: imageStep }' }
.row.show-for-large-up
.large-12.columns
%span#or.large-12.columns
OR
.row.show-for-large-up
.large-12.columns
#image-over{ 'nv-file-over' => true, uploader: "imageUploader" }
Drag and drop your logo here
.small-12.medium-12.large-6.columns
.row
.small-12.columns.center
.row
.small-12.columns.center
%h4
Step 2. Review Your Logo
.row
.small-12.columns.center
%span.small
Tip: for best results, your logo should fill the available space
.row.pad-top
.small-12.columns.center
#image-placeholder.logo
%img{ ng: { show: "imageSrc()", src: '{{ imageSrc() }}' } }
.message{ ng: { hide: "imageSrc()" } }
Your logo will appear here for review once uploaded

View File

@@ -0,0 +1,39 @@
.small-12.medium-12.large-12.columns
.row
.small-12.columns.center
%h4
Step 3. Select Promo Image
.row
.small-12.medium-12.large-5.columns.center
.row
.small-12.columns.center
%span.small
Tip: Shown as a banner, preferred size is 1200×260px
.row.pad-top
.small-12.columns
.image-select.small-12.columns
%label.small-12.columns.button{ for: 'image-select' } Choose a promo image
%input#image-select{ type: 'file', hidden: true, 'nv-file-select' => true, uploader: "imageUploader", options: '{ alias: imageStep }' }
.large-2.columns
%span#or.horizontal.large-12.columns
OR
.large-5.columns
#image-over{ 'nv-file-over' => true, uploader: "imageUploader" }
Drag and drop your promo here
.small-12.medium-12.large-12.columns.pad-top
.row
.small-12.columns.center
%h4
Step 4. Review Your Promo Banner
.row
.small-12.columns.center
.row
.small-12.columns.center
%span.small
Tip: for best results, your promo image should fill the available space
.row.pad-top
.small-12.columns.center
#image-placeholder.promo
%img{ ng: { show: "imageSrc()", src: '{{ imageSrc() }}' } }
.message{ ng: { hide: "imageSrc()" } }
Your logo will appear here for review once uploaded

View File

@@ -6,35 +6,34 @@
.small-12.medium-3.large-2.columns.text-right.hide-for-small-only
%img{:src => "/assets/potatoes.png"}
.small-12.medium-9.large-10.columns
%p
Your profile gives you an online presence on the
%strong Open Food Network,
%p
Your profile gives you an online presence on the
%strong Open Food Network,
allowing you to easily connect with potential customers or partners. You can always choose to update your info later, as well as choose to upgrade your Profile to and Online Store, where you can sell products, track orders and receive payments. Creating a profile takes about 5-10 minutes.
.row{ 'data-equalizer' => true }
.small-12.medium-6.large-6.columns.pad-top{ 'data-equalizer-watch' => true }
%h5 You'll need the following:
%ul.check-list
%li
%li
Your enterprise address and contact details
%li
%li
Your logo image
%li
%li
A pretty picture for your profile header
%li
%li
Some 'About Us' text
.small-12.medium-6.large-6.columns{ 'data-equalizer-watch' => true}
.highlight-box
%h5 Your profile entitles you to:
%ul.small-block-grid-1
%li
%li
%i.ofn-i_020-search
A searchable listing
%li
%li
%i.ofn-i_040-hub
A pin on the OFN map
.row
.small-12.columns
%hr
%input.button.primary{ type: "button", value: "Let's get started!", ng: { click: "select('details')" } }

View File

@@ -30,6 +30,6 @@
.row.buttons
.small-12.columns
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('about')" } }
%input.button.secondary{ type: "button", value: "Back", ng: { click: "select('images')" } }
 
%input.button.primary{ type: "submit", value: "Continue" }
%input.button.primary{ type: "submit", value: "Continue" }

View File

@@ -80,6 +80,53 @@
color: #333
@include box-shadow(inset 0 0 1px 0 #fff)
.image-select
label
font-size: 18px
padding: 21px 0px
#logo-select
display: none
#image-over
font-size: 18px
padding: 41px 0px
border: 3px dashed #494949
text-align: center
font-weight: bold
color: #494949
&.nv-file-over
background-color: #78cd91
#or
text-align: center
font-weight: bold
font-size: 18px
padding: 21px 0px
&.horizontal
padding: 41px 0px
#image-placeholder
font-size: 18px
font-weight: bold
color: #373737
background-color: #e1e1e1
text-align: center
border: 3px dashed #494949
margin-left: auto
margin-right: auto
&.logo
.message
padding-top: 6em
width: 306px
height: 306px
&.promo
.message
padding-top: 4em
width: 726px
height: 166px
#registration-details
#enterprise-types
a.panel
@@ -112,4 +159,3 @@
p
clear: both
font-size: 0.875rem

View File

@@ -7,6 +7,7 @@ module Admin
before_filter :check_bulk_type, only: :bulk_update
before_filter :override_owner, only: :create
before_filter :check_owner, only: :update
before_filter :check_bulk_owner, only: :bulk_update
helper 'spree/products'
include OrderCyclesHelper
@@ -79,11 +80,19 @@ module Admin
end
def check_owner
unless spree_current_user == @enterprise.owner || spree_current_user.admin?
unless ( spree_current_user == @enterprise.owner ) || spree_current_user.admin?
params[:enterprise].delete :owner_id
end
end
def check_bulk_owner
unless spree_current_user.admin?
params[:enterprise_set][:collection_attributes].each do |i, enterprise_params|
enterprise_params.delete :owner_id
end
end
end
# Overriding method on Spree's resource controller
def location_after_save
if params[:enterprise].key? :producer_properties_attributes

View File

@@ -27,9 +27,9 @@ module Api
end
def update
authorize! :update, Enterprise
@enterprise = Enterprise.find(params[:id])
authorize! :update, @enterprise
if @enterprise.update_attributes(params[:enterprise])
render text: @enterprise.id, :status => 200
else
@@ -37,6 +37,19 @@ module Api
end
end
def update_image
@enterprise = Enterprise.find(params[:id])
authorize! :update, @enterprise
if params[:logo] && @enterprise.update_attributes( { logo: params[:logo] } )
render text: @enterprise.logo.url(:medium), :status => 200
elsif params[:promo] && @enterprise.update_attributes( { promo_image: params[:promo] } )
render text: @enterprise.promo_image.url(:medium), :status => 200
else
invalid_resource!(@enterprise)
end
end
private
def override_owner

View File

@@ -2,7 +2,7 @@ require 'open_food_network/spree_api_key_loader'
class RegistrationController < BaseController
include OpenFoodNetwork::SpreeApiKeyLoader
before_filter :load_spree_api_key, only: :index
before_filter :load_spree_api_key, only: [:index, :store]
before_filter :check_user, except: :authenticate
layout 'registration'

View File

@@ -12,6 +12,7 @@ Spree::Api::ProductsController.class_eval do
def bulk_products
@products = OpenFoodNetwork::Permissions.new(current_api_user).managed_products.
merge(product_scope).
order('created_at DESC').
ransack(params[:q]).result.
page(params[:page]).per(params[:per_page])

View File

@@ -34,7 +34,7 @@ class Enterprise < ActiveRecord::Base
path: 'public/images/enterprises/logos/:id/:style/:basename.:extension'
has_attached_file :promo_image,
styles: { large: "1200x260#", thumb: "100x100>" },
styles: { large: "1200x260#", medium: "720x156#", thumb: "100x100>" },
url: '/images/enterprises/promo_images/:id/:style/:basename.:extension',
path: 'public/images/enterprises/promo_images/:id/:style/:basename.:extension'

View File

@@ -2,12 +2,17 @@ class AbilityDecorator
include CanCan::Ability
def initialize(user)
add_base_abilities user if is_new_user? user
add_enterprise_management_abilities user if can_manage_enterprises? user
add_product_management_abilities user if can_manage_products? user
add_relationship_management_abilities user if can_manage_relationships? user
end
def is_new_user?(user)
user.enterprises.blank?
end
def can_manage_enterprises?(user)
user.enterprises.present?
end
@@ -22,6 +27,9 @@ class AbilityDecorator
can_manage_enterprises? user
end
def add_base_abilities(user)
can [:create], Enterprise
end
def add_enterprise_management_abilities(user)
# Spree performs authorize! on (:create, nil) when creating a new order from admin, and also (:search, nil)
@@ -71,7 +79,7 @@ class AbilityDecorator
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization
can [:create], OrderCycle
can [:admin, :index, :read, :edit, :update, :bulk_update, :clone], OrderCycle do |order_cycle|
user.enterprises.include? order_cycle.coordinator

View File

@@ -16,7 +16,8 @@
%col{style: "width: 5%;"}/
- if spree_current_user.admin?
%col{style: "width: 12%;"}/
%col{style: "width: 18%;"}/
- if spree_current_user.admin?
%col{style: "width: 18%;"}/
%col{style: "width: 25%;"}/
%thead
%tr{"data-hook" => "enterprises_header"}
@@ -25,7 +26,8 @@
%th Visible?
- if spree_current_user.admin?
%th Type
%th Owner
- if spree_current_user.admin?
%th Owner
%th
%tbody
= f.fields_for :collection do |enterprise_form|
@@ -41,7 +43,8 @@
%td= enterprise_form.check_box :visible
- if spree_current_user.admin?
%td= enterprise_form.select :type, Enterprise::TYPES, {}, class: 'select2 fullwidth'
%td= enterprise_form.select :owner_id, enterprise.users.map{ |e| [ e.email, e.id ] }, {}, class: "select2 fullwidth"
- if spree_current_user.admin?
%td= enterprise_form.select :owner_id, enterprise.users.map{ |e| [ e.email, e.id ] }, {}, class: "select2 fullwidth"
%td{"data-hook" => "admin_users_index_row_actions"}
= render 'actions', enterprise: enterprise
- if @enterprises.empty?

View File

@@ -31,6 +31,6 @@
%section{ role: "main" }
= yield
#footer
%loading

View File

@@ -23,6 +23,11 @@ Spree.config do |config|
#config.override_actionmailer_config = false
end
# TODO Work out why this is necessary
# Seems like classes within OFN module become 'uninitialized' when server reloads
# unless the empty module is explicity 'registered' here. Something to do with autoloading?
module OpenFoodNetwork
end
# Add calculators category for enterprise fees
module Spree
@@ -38,7 +43,7 @@ module Spree
end
# Forcing spree to always allow SSL connections
# Since we are using config.force_ssl = true
# Since we are using config.force_ssl = true
# Without this we get a redirect loop: see https://groups.google.com/forum/#!topic/spree-user/NwpqGxJ4klk
SslRequirement.module_eval do
protected

View File

@@ -67,6 +67,7 @@ Openfoodnetwork::Application.routes.draw do
namespace :api do
resources :enterprises do
post :update_image, on: :member
get :managed, on: :collection
get :accessible, on: :collection
end

View File

@@ -9,4 +9,4 @@ module OpenFoodNetwork
end
end
end
end
end

View File

@@ -2,6 +2,7 @@ require 'spec_helper'
module Admin
describe EnterprisesController do
include AuthenticationWorkflow
let(:distributor_owner) do
user = create(:user)
user.spree_roles = []
@@ -110,36 +111,52 @@ module Admin
end
describe "bulk updating enterprises" do
let(:profile_enterprise1) { create(:enterprise, type: 'profile') }
let(:profile_enterprise2) { create(:enterprise, type: 'profile') }
let!(:original_owner) do
user = create_enterprise_user
user.enterprise_limit = 2
user.save!
user
end
let!(:new_owner) do
user = create_enterprise_user
user.enterprise_limit = 2
user.save!
user
end
let!(:profile_enterprise1) { create(:enterprise, type: 'profile', owner: original_owner ) }
let!(:profile_enterprise2) { create(:enterprise, type: 'profile', owner: original_owner ) }
context "as manager" do
it "does not allow 'type' to be changed" do
profile_enterprise1.enterprise_roles.build(user: user).save
profile_enterprise2.enterprise_roles.build(user: user).save
controller.stub spree_current_user: user
bulk_enterprise_params = { enterprise_set: { collection_attributes: { '0' => { id: profile_enterprise1.id, type: 'full' }, '1' => { id: profile_enterprise2.id, type: 'full' } } } }
it "does not allow 'type' or 'owner' to be changed" do
profile_enterprise1.enterprise_roles.build(user: new_owner).save
profile_enterprise2.enterprise_roles.build(user: new_owner).save
controller.stub spree_current_user: new_owner
bulk_enterprise_params = { enterprise_set: { collection_attributes: { '0' => { id: profile_enterprise1.id, type: 'full', owner_id: new_owner.id }, '1' => { id: profile_enterprise2.id, type: 'full', owner_id: new_owner.id } } } }
spree_put :bulk_update, bulk_enterprise_params
profile_enterprise1.reload
profile_enterprise2.reload
expect(profile_enterprise1.type).to eq 'profile'
expect(profile_enterprise2.type).to eq 'profile'
expect(profile_enterprise1.owner).to eq original_owner
expect(profile_enterprise2.owner).to eq original_owner
end
end
context "as super admin" do
it "allows 'type' to be changed" do
profile_enterprise1.enterprise_roles.build(user: user).save
profile_enterprise2.enterprise_roles.build(user: user).save
it "allows 'type' and 'owner' to be changed" do
profile_enterprise1.enterprise_roles.build(user: new_owner).save
profile_enterprise2.enterprise_roles.build(user: new_owner).save
controller.stub spree_current_user: admin_user
bulk_enterprise_params = { enterprise_set: { collection_attributes: { '0' => { id: profile_enterprise1.id, type: 'full' }, '1' => { id: profile_enterprise2.id, type: 'full' } } } }
bulk_enterprise_params = { enterprise_set: { collection_attributes: { '0' => { id: profile_enterprise1.id, type: 'full', owner_id: new_owner.id }, '1' => { id: profile_enterprise2.id, type: 'full', owner_id: new_owner.id } } } }
spree_put :bulk_update, bulk_enterprise_params
profile_enterprise1.reload
profile_enterprise2.reload
expect(profile_enterprise1.type).to eq 'full'
expect(profile_enterprise2.type).to eq 'full'
expect(profile_enterprise1.owner).to eq new_owner
expect(profile_enterprise2.owner).to eq new_owner
end
end
end

View File

@@ -0,0 +1,54 @@
require 'spec_helper'
module Api
describe EnterprisesController do
include AuthenticationWorkflow
render_views
let(:enterprise) { create(:distributor_enterprise) }
before do
stub_authentication!
Enterprise.stub(:find).and_return(enterprise)
end
describe "as an enterprise manager" do
let(:enterprise_manager) { create_enterprise_user }
before do
enterprise_manager.enterprise_roles.build(enterprise: enterprise).save
Spree.user_class.stub :find_by_spree_api_key => enterprise_manager
end
describe "submitting a valid image" do
before do
enterprise.stub(:update_attributes).and_return(true)
end
it "I can update enterprise image" do
spree_post :update_image, logo: 'a logo'
response.should be_success
end
end
end
describe "as an non-managing user" do
let(:non_managing_user) { create_enterprise_user }
before do
Spree.user_class.stub :find_by_spree_api_key => non_managing_user
end
describe "submitting a valid image" do
before do
enterprise.stub(:update_attributes).and_return(true)
end
it "I can't update enterprise image" do
spree_post :update_image, logo: 'a logo'
assert_unauthorized!
end
end
end
end
end

View File

@@ -12,4 +12,28 @@ describe RegistrationController do
response.should redirect_to registration_auth_path(anchor: "signup?after_login=/register/store")
end
end
describe "loading data when user is logged in" do
let!(:user) { double(:user) }
before do
controller.stub spree_current_user: user
user.stub spree_api_key: '12345'
user.stub last_incomplete_spree_order: nil
end
describe "index" do
it "loads the spree api key" do
get :index
expect(assigns(:spree_api_key)).to eq '12345'
end
end
describe "store" do
it "loads the spree api key" do
get :store
expect(assigns(:spree_api_key)).to eq '12345'
end
end
end
end

View File

@@ -10,21 +10,29 @@ FactoryGirl.define do
after(:create) do |oc|
# Suppliers
supplier1 = create(:supplier_enterprise)
supplier2 = create(:supplier_enterprise)
# Incoming Exchanges
ex1 = create(:exchange, :order_cycle => oc, :incoming => true,
:sender => create(:supplier_enterprise), :receiver => oc.coordinator)
:sender => supplier1, :receiver => oc.coordinator)
ex2 = create(:exchange, :order_cycle => oc, :incoming => true,
:sender => create(:supplier_enterprise), :receiver => oc.coordinator)
:sender => supplier2, :receiver => oc.coordinator)
ExchangeFee.create!(exchange: ex1,
enterprise_fee: create(:enterprise_fee, enterprise: ex1.sender))
ExchangeFee.create!(exchange: ex2,
enterprise_fee: create(:enterprise_fee, enterprise: ex2.sender))
# Distributors
#Distributors
distributor1 = create(:distributor_enterprise)
distributor2 = create(:distributor_enterprise)
# Outgoing Exchanges
ex3 = create(:exchange, :order_cycle => oc, :incoming => false,
:sender => oc.coordinator, :receiver => create(:distributor_enterprise),
:sender => oc.coordinator, :receiver => distributor1,
:pickup_time => 'time 0', :pickup_instructions => 'instructions 0')
ex4 = create(:exchange, :order_cycle => oc, :incoming => false,
:sender => oc.coordinator, :receiver => create(:distributor_enterprise),
:sender => oc.coordinator, :receiver => distributor2,
:pickup_time => 'time 1', :pickup_instructions => 'instructions 1')
ExchangeFee.create!(exchange: ex3,
enterprise_fee: create(:enterprise_fee, enterprise: ex3.receiver))

View File

@@ -10,7 +10,7 @@ feature %q{
after { Warden.test_reset! }
stub_authorization!
pending "listing orders" do
context "listing orders" do
before :each do
admin_user = quick_login_as_admin
end
@@ -92,7 +92,7 @@ feature %q{
end
end
pending "altering line item properties" do
context "altering line item properties" do
before :each do
admin_user = quick_login_as_admin
end
@@ -140,7 +140,7 @@ feature %q{
end
end
pending "using page controls" do
context "using page controls" do
before :each do
admin_user = quick_login_as_admin
end
@@ -562,7 +562,7 @@ feature %q{
end
end
pending "as an enterprise manager" do
context "as an enterprise manager" do
let(:s1) { create(:supplier_enterprise, name: 'First Supplier') }
let(:d1) { create(:distributor_enterprise, name: 'First Distributor') }
let(:d2) { create(:distributor_enterprise, name: 'Another Distributor') }

View File

@@ -110,10 +110,10 @@ feature %q{
let(:coordinator2) { create(:distributor_enterprise) }
let!(:order_cycle1) { create(:order_cycle, coordinator: coordinator1) }
let!(:order_cycle2) { create(:simple_order_cycle, coordinator: coordinator2) }
let(:supplier1) { order_cycle1.suppliers.first }
let(:supplier2) { order_cycle1.suppliers.last }
let(:distributor1) { order_cycle1.distributors.first }
let(:distributor2) { order_cycle1.distributors.last }
let!(:supplier1) { order_cycle1.suppliers.first }
let!(:supplier2) { order_cycle1.suppliers.last }
let!(:distributor1) { order_cycle1.distributors.first }
let!(:distributor2) { order_cycle1.distributors.reject{ |d| d == distributor1 }.last } # ensure d1 != d2
let(:product) { order_cycle1.products.first }
before(:each) do
@@ -132,19 +132,6 @@ feature %q{
expect(page).to have_content 'ADD PRODUCT'
targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
puts "c1: " + coordinator1.id.to_s + " "+ coordinator1.name
puts "c2: " + coordinator2.id.to_s + " "+ coordinator2.name
puts "s1: " + supplier1.id.to_s + " "+ supplier1.name
puts "s2: " + supplier2.id.to_s + " "+ supplier2.name
puts "d1: " + distributor1.id.to_s + " "+ distributor1.name
puts "d2: " + distributor2.id.to_s + " "+ distributor2.name
order_cycle1.distributors.each do |distributor|
puts "oc1d: " + distributor.id.to_s + " "+ distributor.name
end
Enterprise.is_distributor.managed_by(@enterprise_user).each do |distributor|
puts "eud: " + distributor.id.to_s + " "+ distributor.name
end
click_link 'Add'
page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS
expect(page).to have_selector 'td', text: product.name

View File

@@ -60,15 +60,22 @@ feature "Registration", js: true do
fill_in 'enterprise_acn', with: '54321'
click_button 'Continue'
# Enterprise should be updated
expect(page).to have_content 'Last step!'
# Enterprise should be update
expect(page).to have_content "Let's upload some pretty pictures so your profile looks great!"
e.reload
expect(e.description).to eq "Short description"
expect(e.long_description).to eq "Long description"
expect(e.abn).to eq '12345'
expect(e.acn).to eq '54321'
# Images
# Move from logo page
click_button 'Continue'
# Move from promo page
click_button 'Continue'
# Filling in social
expect(page).to have_content 'Last step!'
fill_in 'enterprise_website', with: 'www.shop.com'
fill_in 'enterprise_facebook', with: 'FaCeBoOk'
fill_in 'enterprise_linkedin', with: 'LiNkEdIn'

View File

@@ -7,7 +7,7 @@ describe "enterpriseCtrl", ->
beforeEach ->
module('admin.enterprises')
Enterprise =
Enterprise =
enterprise:
payment_method_ids: [ 1, 3 ]
shipping_method_ids: [ 2, 4 ]
@@ -15,7 +15,7 @@ describe "enterpriseCtrl", ->
paymentMethods: [ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 } ]
ShippingMethods =
shippingMethods: [ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 } ]
inject ($controller) ->
scope = {}
ctrl = $controller 'enterpriseCtrl', {$scope: scope, Enterprise: Enterprise, PaymentMethods: PaymentMethods, ShippingMethods: ShippingMethods}
@@ -82,4 +82,4 @@ describe "enterpriseCtrl", ->
describe "counting selected shipping methods", ->
it "counts only shipping methods with selected: true", ->
scope.ShippingMethods = [ { selected: true }, { selected: true }, { selected: false }, { selected: true } ]
expect(scope.selectedShippingMethodsCount()).toBe 3
expect(scope.selectedShippingMethodsCount()).toBe 3

View File

@@ -13,6 +13,13 @@ module Spree
let(:enterprise_single) { create(:enterprise, type: 'single') }
let(:enterprise_profile) { create(:enterprise, type: 'profile') }
describe "creating enterprises" do
it "can create enterprises straight off the bat" do
subject.is_new_user?(user).should be_true
expect(user).to have_ability :create, for: Enterprise
end
end
describe "managing enterprises" do
it "can manage enterprises when the user has at least one enterprise assigned" do
user.enterprise_roles.create! enterprise: enterprise_full

View File

@@ -3,20 +3,15 @@ RSpec::Matchers.define :have_table_row do |row|
match_for_should do |node|
@row = row
false_on_timeout_error do
wait_until { rows_under(node).include? row }
end
node.has_selector? "tr", text: row.join(" ").strip # Check for appearance
rows_under(node).include? row # Robust check of columns
end
match_for_should_not do |node|
@row = row
false_on_timeout_error do
# Without this sleep, we trigger capybara's wait when looking up the table, for the full
# period of default_wait_time.
sleep 0.1
wait_until { !rows_under(node).include? row }
end
node.has_no_selector? "tr", text: row.join(" ").strip # Check for appearance
!rows_under(node).include? row # Robust check of columns
end
failure_message_for_should do |text|
@@ -27,17 +22,7 @@ RSpec::Matchers.define :have_table_row do |row|
"expected not to find table row #{@row}"
end
def rows_under(node)
node.all('tr').map { |tr| tr.all('th, td').map(&:text) }
end
def false_on_timeout_error
yield
rescue TimeoutError
false
else
true
end
end