From d3e72b5a2a4383e95c41503dfaa91ebd5db2106e Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 12:34:48 +1000 Subject: [PATCH 01/14] Adding images to registration process --- Gemfile | 1 + Gemfile.lock | 2 + .../javascripts/darkswarm/all.js.coffee | 2 + .../enterprise_image_controller.js.coffee | 13 +++++ .../registration_form_controller.js.coffee | 2 +- .../javascripts/darkswarm/darkswarm.js.coffee | 20 +++---- .../enterprise_image_service.js.coffee | 13 +++++ .../enterprise_registration_service.js.coffee | 2 +- .../services/registration_service.js.coffee | 4 +- .../templates/registration/about.html.haml | 2 +- .../templates/registration/images.html.haml | 24 +++++---- .../registration/images/logo.html.haml | 41 ++++++++++++++ .../registration/images/promo.html.haml | 39 ++++++++++++++ .../registration/introduction.html.haml | 19 ++++--- .../templates/registration/social.html.haml | 4 +- .../darkswarm/registration.css.sass | 48 ++++++++++++++++- app/controllers/api/enterprises_controller.rb | 17 +++++- app/models/enterprise.rb | 2 +- app/models/spree/ability_decorator.rb | 2 +- config/routes.rb | 1 + .../api/enterprises_controller_spec.rb | 54 +++++++++++++++++++ spec/features/consumer/registration_spec.rb | 11 +++- .../enterprise_controller_spec.js.coffee | 6 +-- 23 files changed, 283 insertions(+), 46 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/controllers/enterprise_image_controller.js.coffee create mode 100644 app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee create mode 100644 app/assets/javascripts/templates/registration/images/logo.html.haml create mode 100644 app/assets/javascripts/templates/registration/images/promo.html.haml create mode 100644 spec/controllers/api/enterprises_controller_spec.rb diff --git a/Gemfile b/Gemfile index 456234f554..2e03d65a35 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index 9bb6e501db..c1a2c66522 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee index f529ac3255..45acfd6523 100644 --- a/app/assets/javascripts/darkswarm/all.js.coffee +++ b/app/assets/javascripts/darkswarm/all.js.coffee @@ -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 diff --git a/app/assets/javascripts/darkswarm/controllers/enterprise_image_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/enterprise_image_controller.js.coffee new file mode 100644 index 0000000000..e12d55b50c --- /dev/null +++ b/app/assets/javascripts/darkswarm/controllers/enterprise_image_controller.js.coffee @@ -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 diff --git a/app/assets/javascripts/darkswarm/controllers/registration_form_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/registration_form_controller.js.coffee index 84f133da54..fabc2c382a 100644 --- a/app/assets/javascripts/darkswarm/controllers/registration_form_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/registration_form_controller.js.coffee @@ -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) \ No newline at end of file + RegistrationService.select(nextStep) if $scope.valid(form) diff --git a/app/assets/javascripts/darkswarm/darkswarm.js.coffee b/app/assets/javascripts/darkswarm/darkswarm.js.coffee index 1e58fe7294..e8ea9dce3c 100644 --- a/app/assets/javascripts/darkswarm/darkswarm.js.coffee +++ b/app/assets/javascripts/darkswarm/darkswarm.js.coffee @@ -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() - diff --git a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee new file mode 100644 index 0000000000..fbefabcfa8 --- /dev/null +++ b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee @@ -0,0 +1,13 @@ +Darkswarm.factory "EnterpriseImageService", (EnterpriseRegistrationService, FileUploader, spreeApiKey) -> + new class EnterpriseImageService + imageSrc: null + + imageUploader: new FileUploader + headers: + 'X-Spree-Token': spreeApiKey + url: "/api/enterprises/#{EnterpriseRegistrationService.enterprise.id}/update_image" + autoUpload: true + + constructor: -> + @imageUploader.onSuccessItem = (image, response) => + @imageSrc = response diff --git a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee index 68915193ee..5aa2f3e8bf 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee @@ -54,4 +54,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 \ No newline at end of file + enterprise diff --git a/app/assets/javascripts/darkswarm/services/registration_service.js.coffee b/app/assets/javascripts/darkswarm/services/registration_service.js.coffee index a2a1fe2dc4..530d118025 100644 --- a/app/assets/javascripts/darkswarm/services/registration_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/registration_service.js.coffee @@ -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 "/" \ No newline at end of file + Navigation.go "/" diff --git a/app/assets/javascripts/templates/registration/about.html.haml b/app/assets/javascripts/templates/registration/about.html.haml index 07e631345f..57f7c482e6 100644 --- a/app/assets/javascripts/templates/registration/about.html.haml +++ b/app/assets/javascripts/templates/registration/about.html.haml @@ -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" => ""} diff --git a/app/assets/javascripts/templates/registration/images.html.haml b/app/assets/javascripts/templates/registration/images.html.haml index efd3688076..889bc4596f 100644 --- a/app/assets/javascripts/templates/registration/images.html.haml +++ b/app/assets/javascripts/templates/registration/images.html.haml @@ -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')" } } - - \ No newline at end of file + .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" } diff --git a/app/assets/javascripts/templates/registration/images/logo.html.haml b/app/assets/javascripts/templates/registration/images/logo.html.haml new file mode 100644 index 0000000000..803b103a58 --- /dev/null +++ b/app/assets/javascripts/templates/registration/images/logo.html.haml @@ -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 diff --git a/app/assets/javascripts/templates/registration/images/promo.html.haml b/app/assets/javascripts/templates/registration/images/promo.html.haml new file mode 100644 index 0000000000..f134834d5c --- /dev/null +++ b/app/assets/javascripts/templates/registration/images/promo.html.haml @@ -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 diff --git a/app/assets/javascripts/templates/registration/introduction.html.haml b/app/assets/javascripts/templates/registration/introduction.html.haml index 8a4f4f7e02..ccefdefbe0 100644 --- a/app/assets/javascripts/templates/registration/introduction.html.haml +++ b/app/assets/javascripts/templates/registration/introduction.html.haml @@ -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')" } } - \ No newline at end of file diff --git a/app/assets/javascripts/templates/registration/social.html.haml b/app/assets/javascripts/templates/registration/social.html.haml index 2aa12bd08b..1b3490ffa0 100644 --- a/app/assets/javascripts/templates/registration/social.html.haml +++ b/app/assets/javascripts/templates/registration/social.html.haml @@ -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" } \ No newline at end of file + %input.button.primary{ type: "submit", value: "Continue" } diff --git a/app/assets/stylesheets/darkswarm/registration.css.sass b/app/assets/stylesheets/darkswarm/registration.css.sass index 3e851709bc..3261fc0fd4 100644 --- a/app/assets/stylesheets/darkswarm/registration.css.sass +++ b/app/assets/stylesheets/darkswarm/registration.css.sass @@ -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 - diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index 9a3b715093..76320b0750 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -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 diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 537ac78295..e75d18dae9 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -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' diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 79019f3e8a..5ded33f463 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -71,7 +71,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 diff --git a/config/routes.rb b/config/routes.rb index f95b0c07df..3e063641dd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb new file mode 100644 index 0000000000..e21a879d4f --- /dev/null +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -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 diff --git a/spec/features/consumer/registration_spec.rb b/spec/features/consumer/registration_spec.rb index 3500736100..7ac46a8970 100644 --- a/spec/features/consumer/registration_spec.rb +++ b/spec/features/consumer/registration_spec.rb @@ -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' diff --git a/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee index b1b019276b..8f6bd64a5f 100644 --- a/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee @@ -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 \ No newline at end of file + expect(scope.selectedShippingMethodsCount()).toBe 3 From 544e6e074a3df1af83ed313ca4282426a4327a50 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 14:38:59 +1000 Subject: [PATCH 02/14] Stop being lazy --- spec/features/admin/orders_spec.rb | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index d45778635a..3ed4c4ca2f 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -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.last } 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 From eeb54f3f76d781a24f39ffe114a312c683532c7d Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 15:30:53 +1000 Subject: [PATCH 03/14] Allow new user to create enterprises --- app/models/spree/ability_decorator.rb | 8 ++++++++ spec/models/spree/ability_spec.rb | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 5ded33f463..08fc4407ce 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -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) diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb index cf17d7fe3a..78ca1db909 100644 --- a/spec/models/spree/ability_spec.rb +++ b/spec/models/spree/ability_spec.rb @@ -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 From c6acbc6810a8875290c14932629736fa0741ddb3 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 16:09:26 +1000 Subject: [PATCH 04/14] Assigning @spree_api_key for store --- app/controllers/registration_controller.rb | 2 +- app/views/layouts/registration.html.haml | 2 +- lib/open_food_network/spree_api_key_loader.rb | 2 +- .../registration_controller_spec.rb | 24 +++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/app/controllers/registration_controller.rb b/app/controllers/registration_controller.rb index d58b10bd0b..47a1537b57 100644 --- a/app/controllers/registration_controller.rb +++ b/app/controllers/registration_controller.rb @@ -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' diff --git a/app/views/layouts/registration.html.haml b/app/views/layouts/registration.html.haml index 8946a27de1..d6122cdc3b 100644 --- a/app/views/layouts/registration.html.haml +++ b/app/views/layouts/registration.html.haml @@ -31,6 +31,6 @@ %section{ role: "main" } = yield - + #footer %loading diff --git a/lib/open_food_network/spree_api_key_loader.rb b/lib/open_food_network/spree_api_key_loader.rb index 36fa4b9961..5eb7236221 100644 --- a/lib/open_food_network/spree_api_key_loader.rb +++ b/lib/open_food_network/spree_api_key_loader.rb @@ -9,4 +9,4 @@ module OpenFoodNetwork end end end -end \ No newline at end of file +end diff --git a/spec/controllers/registration_controller_spec.rb b/spec/controllers/registration_controller_spec.rb index 49efc005f6..13babdf89e 100644 --- a/spec/controllers/registration_controller_spec.rb +++ b/spec/controllers/registration_controller_spec.rb @@ -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 From 17ce80a417643923806616e24c37523d6939682b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 15:30:53 +1000 Subject: [PATCH 05/14] Allow new user to create enterprises --- app/models/spree/ability_decorator.rb | 8 ++++++++ spec/models/spree/ability_spec.rb | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 5ded33f463..08fc4407ce 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -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) diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb index cf17d7fe3a..78ca1db909 100644 --- a/spec/models/spree/ability_spec.rb +++ b/spec/models/spree/ability_spec.rb @@ -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 From 5d2d619d6668215377e1c2ff319686bb634eac87 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 16:09:26 +1000 Subject: [PATCH 06/14] Assigning @spree_api_key for store --- app/controllers/registration_controller.rb | 2 +- app/views/layouts/registration.html.haml | 2 +- lib/open_food_network/spree_api_key_loader.rb | 2 +- .../registration_controller_spec.rb | 24 +++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/app/controllers/registration_controller.rb b/app/controllers/registration_controller.rb index d58b10bd0b..47a1537b57 100644 --- a/app/controllers/registration_controller.rb +++ b/app/controllers/registration_controller.rb @@ -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' diff --git a/app/views/layouts/registration.html.haml b/app/views/layouts/registration.html.haml index 8946a27de1..d6122cdc3b 100644 --- a/app/views/layouts/registration.html.haml +++ b/app/views/layouts/registration.html.haml @@ -31,6 +31,6 @@ %section{ role: "main" } = yield - + #footer %loading diff --git a/lib/open_food_network/spree_api_key_loader.rb b/lib/open_food_network/spree_api_key_loader.rb index 36fa4b9961..5eb7236221 100644 --- a/lib/open_food_network/spree_api_key_loader.rb +++ b/lib/open_food_network/spree_api_key_loader.rb @@ -9,4 +9,4 @@ module OpenFoodNetwork end end end -end \ No newline at end of file +end diff --git a/spec/controllers/registration_controller_spec.rb b/spec/controllers/registration_controller_spec.rb index 49efc005f6..13babdf89e 100644 --- a/spec/controllers/registration_controller_spec.rb +++ b/spec/controllers/registration_controller_spec.rb @@ -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 From 07275574b616f6f50ae4f1548426bd9c3a2da6e6 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 17:51:49 +1000 Subject: [PATCH 07/14] Manager can't bulk update owner --- .../admin/enterprises_controller.rb | 11 +++++- app/views/admin/enterprises/index.html.haml | 9 +++-- .../admin/enterprises_controller_spec.rb | 39 +++++++++++++------ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 64ba997950..bde7bff431 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -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 diff --git a/app/views/admin/enterprises/index.html.haml b/app/views/admin/enterprises/index.html.haml index 44008b3bd2..03e5335155 100644 --- a/app/views/admin/enterprises/index.html.haml +++ b/app/views/admin/enterprises/index.html.haml @@ -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? diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb index 44421aad8e..a522624489 100644 --- a/spec/controllers/admin/enterprises_controller_spec.rb +++ b/spec/controllers/admin/enterprises_controller_spec.rb @@ -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 From 509cf6250a48438f68b5ea574f0e1a6410378c2e Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 17:59:31 +1000 Subject: [PATCH 08/14] Explicitly sort managed products --- app/controllers/spree/api/products_controller_decorator.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/spree/api/products_controller_decorator.rb b/app/controllers/spree/api/products_controller_decorator.rb index 65765e03ca..111f36962c 100644 --- a/app/controllers/spree/api/products_controller_decorator.rb +++ b/app/controllers/spree/api/products_controller_decorator.rb @@ -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]) From 5bceb81479c5c2375a31527353481f9117d594da Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 19 Sep 2014 23:37:02 +1000 Subject: [PATCH 09/14] Fixing image upload in onboarding --- .../services/enterprise_image_service.js.coffee | 9 ++++----- .../services/enterprise_registration_service.js.coffee | 3 ++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee index fbefabcfa8..c8cd64e93a 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_image_service.js.coffee @@ -1,13 +1,12 @@ -Darkswarm.factory "EnterpriseImageService", (EnterpriseRegistrationService, FileUploader, spreeApiKey) -> +Darkswarm.factory "EnterpriseImageService", (FileUploader, spreeApiKey) -> new class EnterpriseImageService imageSrc: null imageUploader: new FileUploader headers: 'X-Spree-Token': spreeApiKey - url: "/api/enterprises/#{EnterpriseRegistrationService.enterprise.id}/update_image" autoUpload: true - constructor: -> - @imageUploader.onSuccessItem = (image, response) => - @imageSrc = response + configure: (enterprise) => + @imageUploader.url = "/api/enterprises/#{enterprise.id}/update_image" + @imageUploader.onSuccessItem = (image, response) => @imageSrc = response diff --git a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee index 5aa2f3e8bf..77b2204316 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_registration_service.js.coffee @@ -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() From c6d463bf254d62d0974643253338aaa8a1905a7f Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Sat, 20 Sep 2014 18:06:42 +1000 Subject: [PATCH 10/14] Revert "Pending bulk order mgmt specs" This reverts commit eead8d665f4ed0251b3f3adee51dfc03db3e9f28. --- spec/features/admin/bulk_order_management_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 5db9eee86d..fe18f1a9bf 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -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') } From 1a86206e1fab390cf86f0179b87c60e5e416ae10 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 24 Sep 2014 13:01:40 +1000 Subject: [PATCH 11/14] Fixing super annoying server reload bug --- config/initializers/spree.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb index bbee30379a..f722c60f1a 100644 --- a/config/initializers/spree.rb +++ b/config/initializers/spree.rb @@ -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 From f0f165a1290beac5c9614bfba7073c8289628bbf Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 24 Sep 2014 14:00:08 +1000 Subject: [PATCH 12/14] Explicitly create enterprises in order_cycle factory to fix intermittent fail --- spec/factories.rb | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index d605b5b759..db035ba16a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -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)) From b5ef24bacb63319a37c39770b40b43c89ea4fdc8 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 24 Sep 2014 16:18:59 +1000 Subject: [PATCH 13/14] table matchers use capybara matchers rather than wait_until with micro-sleep --- spec/support/matchers/table_matchers.rb | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/spec/support/matchers/table_matchers.rb b/spec/support/matchers/table_matchers.rb index 146002b751..053562b9e4 100644 --- a/spec/support/matchers/table_matchers.rb +++ b/spec/support/matchers/table_matchers.rb @@ -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 From ed91cd646305fcb4ba743e96266e30b6ce5b5f85 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 24 Sep 2014 20:48:52 +1000 Subject: [PATCH 14/14] Make sure d1 != d2 --- spec/features/admin/orders_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 3ed4c4ca2f..908ce4042e 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -113,7 +113,7 @@ feature %q{ 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!(:distributor2) { order_cycle1.distributors.reject{ |d| d == distributor1 }.last } # ensure d1 != d2 let(:product) { order_cycle1.products.first } before(:each) do