From 733dc76c6ccece69ba8a2eaa48274bfac5bb221a Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 31 Aug 2016 17:22:22 +1000 Subject: [PATCH] Order Cycles can be assigned to schedules via new/edit form --- .../order_cycles/controllers/create.js.coffee | 6 +- .../order_cycles/controllers/edit.js.coffee | 5 +- .../controllers/simple_create.js.coffee | 5 +- .../controllers/simple_edit.js.coffee | 5 +- .../directives/schedule_list.js.coffee | 15 +++ .../admin/order_cycles_controller.rb | 14 ++- .../api/admin/order_cycle_serializer.rb | 2 +- .../_name_and_timing_form.html.haml | 15 +++ .../column_preference_defaults.rb | 6 +- .../admin/order_cycles_controller_spec.rb | 113 +++++++++++------- spec/features/admin/order_cycles_spec.rb | 28 +++++ spec/features/admin/schedules_spec.rb | 13 ++ .../unit/order_cycle_spec.js.coffee | 24 ++-- spec/support/request/web_helper.rb | 5 + 14 files changed, 191 insertions(+), 65 deletions(-) create mode 100644 app/assets/javascripts/admin/order_cycles/directives/schedule_list.js.coffee diff --git a/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee index ed81318004..7e0cb5a336 100644 --- a/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee @@ -1,10 +1,11 @@ angular.module('admin.orderCycles') - .controller 'AdminCreateOrderCycleCtrl', ($scope, $filter, $window, OrderCycle, Enterprise, EnterpriseFee, ocInstance, StatusMessage) -> + .controller 'AdminCreateOrderCycleCtrl', ($scope, $filter, $window, OrderCycle, Enterprise, EnterpriseFee, Schedules, RequestMonitor, ocInstance, StatusMessage) -> $scope.enterprises = Enterprise.index(coordinator_id: ocInstance.coordinator_id) $scope.supplier_enterprises = Enterprise.producer_enterprises $scope.distributor_enterprises = Enterprise.hub_enterprises $scope.supplied_products = Enterprise.supplied_products $scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id) + $scope.schedules = Schedules.index() $scope.OrderCycle = OrderCycle $scope.order_cycle = OrderCycle.new({ coordinator_id: ocInstance.coordinator_id}) @@ -18,7 +19,7 @@ angular.module('admin.orderCycles') StatusMessage.setValidation(isValid) $scope.loaded = -> - Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded + Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded && !RequestMonitor.loading $scope.suppliedVariants = (enterprise_id) -> Enterprise.suppliedVariants(enterprise_id) @@ -89,4 +90,3 @@ angular.module('admin.orderCycles') $scope.cancel = (destination) -> $window.location = destination - diff --git a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee index a907e82a14..581b414fb6 100644 --- a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee @@ -1,11 +1,12 @@ angular.module('admin.orderCycles') - .controller 'AdminEditOrderCycleCtrl', ($scope, $filter, $location, $window, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) -> + .controller 'AdminEditOrderCycleCtrl', ($scope, $filter, $location, $window, OrderCycle, Enterprise, EnterpriseFee, StatusMessage, Schedules, RequestMonitor) -> order_cycle_id = $location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1] $scope.enterprises = Enterprise.index(order_cycle_id: order_cycle_id) $scope.supplier_enterprises = Enterprise.producer_enterprises $scope.distributor_enterprises = Enterprise.hub_enterprises $scope.supplied_products = Enterprise.supplied_products $scope.enterprise_fees = EnterpriseFee.index(order_cycle_id: order_cycle_id) + $scope.schedules = Schedules.index() $scope.OrderCycle = OrderCycle $scope.order_cycle = OrderCycle.load(order_cycle_id) @@ -19,7 +20,7 @@ angular.module('admin.orderCycles') StatusMessage.setValidation(isValid) $scope.loaded = -> - Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded + Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded && !RequestMonitor.loading $scope.suppliedVariants = (enterprise_id) -> Enterprise.suppliedVariants(enterprise_id) diff --git a/app/assets/javascripts/admin/order_cycles/controllers/simple_create.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/simple_create.js.coffee index 701587998a..2bf008b427 100644 --- a/app/assets/javascripts/admin/order_cycles/controllers/simple_create.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/controllers/simple_create.js.coffee @@ -1,6 +1,7 @@ -angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl", ($scope, $window, OrderCycle, Enterprise, EnterpriseFee, StatusMessage, ocInstance) -> +angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl", ($scope, $window, OrderCycle, Enterprise, EnterpriseFee, StatusMessage, Schedules, RequestMonitor, ocInstance) -> $scope.StatusMessage = StatusMessage $scope.OrderCycle = OrderCycle + $scope.schedules = Schedules.index() $scope.order_cycle = OrderCycle.new {coordinator_id: ocInstance.coordinator_id}, => # TODO: make this a get method, which only fetches one enterprise $scope.enterprises = Enterprise.index {coordinator_id: ocInstance.coordinator_id}, (enterprises) => @@ -26,7 +27,7 @@ angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl" OrderCycle.order_cycle.coordinator_id = enterprise.id $scope.loaded = -> - Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded + Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded && !RequestMonitor.loading $scope.removeDistributionOfVariant = angular.noop diff --git a/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee index 0869a1030e..ba0f986407 100644 --- a/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee @@ -1,10 +1,11 @@ -angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl", ($scope, $location, $window, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) -> +angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl", ($scope, $location, $window, OrderCycle, Enterprise, EnterpriseFee, Schedules, RequestMonitor, StatusMessage) -> $scope.orderCycleId = -> $location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1] $scope.StatusMessage = StatusMessage $scope.enterprises = Enterprise.index(order_cycle_id: $scope.orderCycleId()) $scope.enterprise_fees = EnterpriseFee.index(order_cycle_id: $scope.orderCycleId()) + $scope.schedules = Schedules.index() $scope.OrderCycle = OrderCycle $scope.order_cycle = OrderCycle.load $scope.orderCycleId(), (order_cycle) => $scope.init() @@ -16,7 +17,7 @@ angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl", StatusMessage.setValidation(isValid) $scope.loaded = -> - Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded + Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded && !RequestMonitor.loading $scope.init = -> $scope.outgoing_exchange = OrderCycle.order_cycle.outgoing_exchanges[0] diff --git a/app/assets/javascripts/admin/order_cycles/directives/schedule_list.js.coffee b/app/assets/javascripts/admin/order_cycles/directives/schedule_list.js.coffee new file mode 100644 index 0000000000..dea2eac7db --- /dev/null +++ b/app/assets/javascripts/admin/order_cycles/directives/schedule_list.js.coffee @@ -0,0 +1,15 @@ +angular.module("admin.orderCycles").directive 'scheduleList', (RequestMonitor, Schedules) -> + restrict: 'E' + scope: + orderCycle: '=' + template: "
{{ schedule.name + ($last ? '' : ', ')}}
" + link: (scope, element, attr) -> + scope.schedules = [] + + scope.$watchCollection 'orderCycle.schedule_ids', (newValue, oldValue) -> + return unless newValue? && RequestMonitor.loadId > 0 # Request for schedules needs to have been sent + scope.schedules = [] + RequestMonitor.loadQueue.then -> + for id in scope.orderCycle.schedule_ids + schedule = Schedules.byID[id] + scope.schedules.push schedule if schedule? diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 39f306976e..ee253561fb 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -1,4 +1,4 @@ -require 'open_food_network/order_cycle_permissions' +require 'open_food_network/permissions' require 'open_food_network/order_cycle_form_applicator' module Admin @@ -9,6 +9,7 @@ module Admin before_filter :require_coordinator, only: :new before_filter :remove_protected_attrs, only: [:update] before_filter :remove_unauthorized_bulk_attrs, only: [:bulk_update] + before_filter :check_editable_schedule_ids, only: [:create, :update] around_filter :protect_invalid_destroy, only: :destroy def index @@ -182,6 +183,17 @@ module Admin end end + def check_editable_schedule_ids + return unless params[:order_cycle][:schedule_ids] + requested = params[:order_cycle][:schedule_ids].map(&:to_i) + existing = @order_cycle.schedule_ids + permitted = Schedule.where(id: requested | existing).merge(OpenFoodNetwork::Permissions.new(spree_current_user).editable_schedules).pluck(:id) + result = existing + result |= (requested & permitted) # add any requested & permitted ids + result -= ((result & permitted) - requested) # remove any existing and permitted ids that were not specifically requested + params[:order_cycle][:schedule_ids] = result + end + def ams_prefix_whitelist [:basic, :index] end diff --git a/app/serializers/api/admin/order_cycle_serializer.rb b/app/serializers/api/admin/order_cycle_serializer.rb index 8068055df2..9b5ff7a7cb 100644 --- a/app/serializers/api/admin/order_cycle_serializer.rb +++ b/app/serializers/api/admin/order_cycle_serializer.rb @@ -4,7 +4,7 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer attributes :id, :name, :orders_open_at, :orders_close_at, :coordinator_id, :exchanges attributes :editable_variants_for_incoming_exchanges, :editable_variants_for_outgoing_exchanges attributes :visible_variants_for_outgoing_exchanges - attributes :viewing_as_coordinator + attributes :viewing_as_coordinator, :schedule_ids has_many :coordinator_fees, serializer: Api::IdSerializer diff --git a/app/views/admin/order_cycles/_name_and_timing_form.html.haml b/app/views/admin/order_cycles/_name_and_timing_form.html.haml index d081120210..75b983aae0 100644 --- a/app/views/admin/order_cycles/_name_and_timing_form.html.haml +++ b/app/views/admin/order_cycles/_name_and_timing_form.html.haml @@ -26,3 +26,18 @@ = f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-disabled' => '!loaded()' - else {{ order_cycle.orders_close_at }} + +.row + .two.columns.alpha + = f.label :schedule_ids, t('admin.order_cycles.schedules') + .twelve.columns + - if viewing_as_coordinator_of?(@order_cycle) + %input.fullwidth.ofn-select2#schedule_ids{ name: 'order_cycle[schedule_ids]', + data: 'schedules', + multiple: 'true', + filter: '{viewing_as_coordinator: true}', + ng: { model: 'order_cycle.schedule_ids' } } + - else + %schedule-list{ 'order-cycle' => 'order_cycle' } + .two.columns.omega +   diff --git a/lib/open_food_network/column_preference_defaults.rb b/lib/open_food_network/column_preference_defaults.rb index 4e089e6365..65415ee305 100644 --- a/lib/open_food_network/column_preference_defaults.rb +++ b/lib/open_food_network/column_preference_defaults.rb @@ -87,12 +87,12 @@ module OpenFoodNetwork node = "admin.order_cycles.index" { name: { name: I18n.t("admin.name"), visible: true }, - schedules: { name: I18n.t("#{node}.schedules"), visible: true }, + schedules: { name: I18n.t("#{node}.schedules"), visible: false }, open: { name: I18n.t("open"), visible: true }, close: { name: I18n.t("close"), visible: true }, - producers: { name: I18n.t("label_producers"), visible: true }, + producers: { name: I18n.t("label_producers"), visible: false }, coordinator: { name: I18n.t("coordinator"), visible: true }, - shops: { name: I18n.t("label_shops"), visible: true }, + shops: { name: I18n.t("label_shops"), visible: false }, products: { name: I18n.t("products"), visible: true } } end diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb index 4cc643d756..e80e89dcc1 100644 --- a/spec/controllers/admin/order_cycles_controller_spec.rb +++ b/spec/controllers/admin/order_cycles_controller_spec.rb @@ -98,59 +98,58 @@ module Admin describe "update" do let(:order_cycle) { create(:simple_order_cycle) } + let(:producer) { create(:supplier_enterprise) } + let(:coordinator) { order_cycle.coordinator } + let(:hub) { create(:distributor_enterprise) } + let(:v) { create(:variant) } + let!(:incoming_exchange) { create(:exchange, order_cycle: order_cycle, sender: producer, receiver: coordinator, incoming: true, variants: [v]) } + let!(:outgoing_exchange) { create(:exchange, order_cycle: order_cycle, sender: coordinator, receiver: hub, incoming: false, variants: [v]) } - before { login_as_admin } + context "as a manager of the coordinator" do + before { login_as_enterprise_user([coordinator]) } - it "sets flash message when page is reloading" do - spree_put :update, id: order_cycle.id, reloading: '1', order_cycle: {} - flash[:notice].should == 'Your order cycle has been updated.' - end - - it "does not set flash message otherwise" do - flash[:notice].should be_nil - end - - context "when updating without explicitly submitting exchanges" do - let(:form_applicator_mock) { double(:form_applicator) } - let(:incoming_exchange) { create(:exchange, order_cycle: order_cycle, incoming: true) } - let(:outgoing_exchange) { create(:exchange, order_cycle: order_cycle, incoming: false) } - - - before do - allow(OpenFoodNetwork::OrderCycleFormApplicator).to receive(:new) { form_applicator_mock } - allow(form_applicator_mock).to receive(:go!) { nil } + it "sets flash message when page is reloading" do + spree_put :update, id: order_cycle.id, reloading: '1', order_cycle: {} + flash[:notice].should == 'Your order cycle has been updated.' end - it "does not run the OrderCycleFormApplicator" do - expect(order_cycle.exchanges.incoming).to eq [incoming_exchange] - expect(order_cycle.exchanges.outgoing).to eq [outgoing_exchange] - expect(order_cycle.prefers_product_selection_from_coordinator_inventory_only?).to be false - spree_put :update, id: order_cycle.id, order_cycle: { name: 'Some new name', preferred_product_selection_from_coordinator_inventory_only: true } - expect(form_applicator_mock).to_not have_received(:go!) - order_cycle.reload - expect(order_cycle.exchanges.incoming).to eq [incoming_exchange] - expect(order_cycle.exchanges.outgoing).to eq [outgoing_exchange] - expect(order_cycle.name).to eq 'Some new name' - expect(order_cycle.prefers_product_selection_from_coordinator_inventory_only?).to be true - end + it "does not set flash message otherwise" do + flash[:notice].should be_nil + end + + context "when updating without explicitly submitting exchanges" do + let(:form_applicator_mock) { double(:form_applicator) } + + before do + allow(OpenFoodNetwork::OrderCycleFormApplicator).to receive(:new) { form_applicator_mock } + allow(form_applicator_mock).to receive(:go!) { nil } + end + + it "does not run the OrderCycleFormApplicator" do + expect(order_cycle.exchanges.incoming).to eq [incoming_exchange] + expect(order_cycle.exchanges.outgoing).to eq [outgoing_exchange] + expect(order_cycle.prefers_product_selection_from_coordinator_inventory_only?).to be false + spree_put :update, id: order_cycle.id, order_cycle: { name: 'Some new name', preferred_product_selection_from_coordinator_inventory_only: true } + expect(form_applicator_mock).to_not have_received(:go!) + order_cycle.reload + expect(order_cycle.exchanges.incoming).to eq [incoming_exchange] + expect(order_cycle.exchanges.outgoing).to eq [outgoing_exchange] + expect(order_cycle.name).to eq 'Some new name' + expect(order_cycle.prefers_product_selection_from_coordinator_inventory_only?).to be true + end + end end context "as a producer supplying to an order cycle" do - let(:producer) { create(:supplier_enterprise) } - let(:coordinator) { order_cycle.coordinator } - let(:hub) { create(:distributor_enterprise) } - - before { login_as_enterprise_user [producer] } + before do + login_as_enterprise_user [producer] + end describe "removing a variant from incoming" do - let(:v) { create(:variant) } - let!(:ex_i) { create(:exchange, order_cycle: order_cycle, sender: producer, receiver: coordinator, incoming: true, variants: [v]) } - let!(:ex_o) { create(:exchange, order_cycle: order_cycle, sender: coordinator, receiver: hub, incoming: false, variants: [v]) } - let(:params) do {order_cycle: { - incoming_exchanges: [{id: ex_i.id, enterprise_id: producer.id, sender_id: producer.id, variants: {v.id => false}}], - outgoing_exchanges: [{id: ex_o.id, enterprise_id: hub.id, receiver_id: hub.id, variants: {v.id => false}}] } + incoming_exchanges: [{id: incoming_exchange.id, enterprise_id: producer.id, sender_id: producer.id, variants: {v.id => false}}], + outgoing_exchanges: [{id: outgoing_exchange.id, enterprise_id: hub.id, receiver_id: hub.id, variants: {v.id => false}}] } } end @@ -162,6 +161,36 @@ module Admin end end + describe "updating schedules" do + let(:user) { create(:user, enterprise_limit: 10) } + let!(:managed_coordinator) { create(:enterprise, owner: user) } + let!(:managed_enterprise) { create(:enterprise, owner: user) } + let!(:coordinated_order_cycle) { create(:simple_order_cycle, coordinator: managed_coordinator ) } + let!(:coordinated_order_cycle2) { create(:simple_order_cycle, coordinator: managed_enterprise ) } + let!(:uncoordinated_order_cycle) { create(:simple_order_cycle, coordinator: create(:enterprise) ) } + let!(:coordinated_schedule) { create(:schedule, order_cycles: [coordinated_order_cycle] ) } + let!(:coordinated_schedule2) { create(:schedule, order_cycles: [coordinated_order_cycle2] ) } + let!(:uncoordinated_schedule) { create(:schedule, order_cycles: [uncoordinated_order_cycle] ) } + + context "where I manage the order_cycle's coordinator" do + render_views + + before do + controller.stub spree_current_user: user + end + + it "allows me to assign only schedules that already I coordinate to the order cycle" do + schedule_ids = [coordinated_schedule2.id, uncoordinated_schedule.id ] + spree_put :update, format: :json, id: coordinated_order_cycle.id, order_cycle: { schedule_ids: schedule_ids } + expect(assigns(:order_cycle)).to eq coordinated_order_cycle + # coordinated_order_cycle2 is added + expect(coordinated_order_cycle.reload.schedules).to include coordinated_schedule2 + # coordinated_order_cycle is removed, uncoordinated_order_cycle is NOT added + expect(coordinated_order_cycle.reload.schedules).to_not include coordinated_schedule, uncoordinated_schedule + end + end + end + describe "bulk_update" do let(:oc) { create(:simple_order_cycle) } let!(:coordinator) { oc.coordinator } diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 7893453699..5bd9df832b 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -43,6 +43,11 @@ feature %q{ page.should have_selector "#listing_order_cycles tr.order-cycle-#{oc5.id}.closed" page.should have_selector "#listing_order_cycles tr.order-cycle-#{oc6.id}.closed" + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Producers").click + first("div#columns-dropdown div.menu div.menu_item", text: "Shops").click + first("div#columns-dropdown", :text => "COLUMNS").click + # And I should see all the details for an order cycle within('table#listing_order_cycles tbody tr:nth-child(2)') do # Then I should see the basic fields @@ -235,6 +240,11 @@ feature %q{ oc = OrderCycle.last + find("div#columns-dropdown", :text => "COLUMNS").click + find("div#columns-dropdown div.menu div.menu_item", text: "Producers").click + find("div#columns-dropdown div.menu div.menu_item", text: "Shops").click + find("div#columns-dropdown", :text => "COLUMNS").click + page.should have_selector 'a', text: 'Plums & Avos' page.should have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time page.should have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time @@ -370,6 +380,11 @@ feature %q{ oc = OrderCycle.last + find("div#columns-dropdown", :text => "COLUMNS").click + find("div#columns-dropdown div.menu div.menu_item", text: "Producers").click + find("div#columns-dropdown div.menu div.menu_item", text: "Shops").click + find("div#columns-dropdown", :text => "COLUMNS").click + page.should have_selector 'a', text: 'Plums & Avos' page.should have_input "oc#{oc.id}[orders_open_at]", value: order_cycle_opening_time page.should have_input "oc#{oc.id}[orders_close_at]", value: order_cycle_closing_time @@ -638,6 +653,7 @@ feature %q{ let!(:variant_managed) { product_managed.variants.first } let!(:product_permitted) { create(:product, supplier: supplier_permitted) } let!(:variant_permitted) { product_permitted.variants.first } + let!(:schedule) { create(:schedule, name: 'Schedule1', order_cycles: [create(:simple_order_cycle, coordinator: distributor_managed)]) } before do # Relationships required for interface to work @@ -672,6 +688,12 @@ feature %q{ page.should have_content oc_user_coordinating.name page.should_not have_content oc_for_other_user.name + + find("div#columns-dropdown", :text => "COLUMNS").click + find("div#columns-dropdown div.menu div.menu_item", text: "Producers").click + find("div#columns-dropdown div.menu div.menu_item", text: "Shops").click + find("div#columns-dropdown", :text => "COLUMNS").click + # The order cycle should show all enterprises in the order cycle page.should have_selector 'td.producers', text: supplier_managed.name page.should have_selector 'td.shops', text: distributor_managed.name @@ -689,6 +711,7 @@ feature %q{ fill_in 'order_cycle_name', with: 'My order cycle' fill_in 'order_cycle_orders_open_at', with: '2040-11-06 06:00:00' fill_in 'order_cycle_orders_close_at', with: '2040-11-13 17:00:00' + multi_select2_select schedule.name, from: 'schedule_ids' select 'Managed supplier', from: 'new_supplier_id' click_button 'Add supplier' @@ -732,6 +755,7 @@ feature %q{ order_cycle.suppliers.should match_array [supplier_managed, supplier_permitted] order_cycle.coordinator.should == distributor_managed order_cycle.distributors.should match_array [distributor_managed, distributor_permitted] + order_cycle.schedules.should == [schedule] exchange = order_cycle.exchanges.outgoing.to_enterprise(distributor_managed).first exchange.tag_list.should == ["wholesale"] end @@ -774,6 +798,9 @@ feature %q{ visit edit_admin_order_cycle_path(oc) + expect(page).to have_field 'order_cycle_name', with: oc.name + multi_select2_select schedule.name, from: 'schedule_ids' + # When I remove all the exchanges and save page.find("tr.supplier-#{supplier_managed.id} a.remove-exchange").click page.find("tr.supplier-#{supplier_permitted.id} a.remove-exchange").click @@ -788,6 +815,7 @@ feature %q{ oc.suppliers.should == [supplier_unmanaged] oc.coordinator.should == distributor_managed oc.distributors.should == [distributor_unmanaged] + oc.schedules.should == [schedule] end scenario "cloning an order cycle" do diff --git a/spec/features/admin/schedules_spec.rb b/spec/features/admin/schedules_spec.rb index 478a29284c..17823bd7d7 100644 --- a/spec/features/admin/schedules_spec.rb +++ b/spec/features/admin/schedules_spec.rb @@ -33,6 +33,10 @@ feature 'Schedules', js: true do click_button "Create Schedule" end + find("div#columns-dropdown", :text => "COLUMNS").click + find("div#columns-dropdown div.menu div.menu_item", text: "Schedules").click + find("div#columns-dropdown", :text => "COLUMNS").click + within ".order-cycle-#{oc1.id} td.schedules" do expect(page).to have_selector "a", text: "Weekly" expect(page).to have_selector "a", text: "Fortnightly" @@ -56,6 +60,10 @@ feature 'Schedules', js: true do it "immediately shows updated schedule lists for order cycles" do click_link 'Order Cycles' + find("div#columns-dropdown", :text => "COLUMNS").click + find("div#columns-dropdown div.menu div.menu_item", text: "Schedules").click + find("div#columns-dropdown", :text => "COLUMNS").click + within ".order-cycle-#{oc1.id} td.schedules" do find('a', text: "Weekly").click end @@ -85,6 +93,11 @@ feature 'Schedules', js: true do describe "deleting a schedule" do it "immediately removes deleted schedules from order cycles" do click_link 'Order Cycles' + + find("div#columns-dropdown", :text => "COLUMNS").click + find("div#columns-dropdown div.menu div.menu_item", text: "Schedules").click + find("div#columns-dropdown", :text => "COLUMNS").click + within ".order-cycle-#{oc1.id} td.schedules" do find('a', text: "Weekly").click end diff --git a/spec/javascripts/unit/order_cycle_spec.js.coffee b/spec/javascripts/unit/order_cycle_spec.js.coffee index ac7e52a366..93fe10c6f8 100644 --- a/spec/javascripts/unit/order_cycle_spec.js.coffee +++ b/spec/javascripts/unit/order_cycle_spec.js.coffee @@ -59,14 +59,17 @@ describe 'OrderCycle controllers', -> expect(scope.order_cycle).toEqual('my order cycle') describe 'Reporting when all resources are loaded', -> - it 'returns true when Enterprise and EnterpriseFee are loaded', -> - Enterprise.loaded = EnterpriseFee.loaded = OrderCycle.loaded = true + beforeEach inject (RequestMonitor) -> + RequestMonitor.loading = false + Enterprise.loaded = true + EnterpriseFee.loaded = true + OrderCycle.loaded = true + + it 'returns true when all resources are loaded', -> expect(scope.loaded()).toBe(true) it 'returns false otherwise', -> - Enterprise.loaded = true EnterpriseFee.loaded = false - OrderCycle.loaded = true expect(scope.loaded()).toBe(false) it "delegates suppliedVariants to Enterprise", -> @@ -220,14 +223,17 @@ describe 'OrderCycle controllers', -> expect(OrderCycle.load).toHaveBeenCalledWith('27') describe 'Reporting when all resources are loaded', -> - it 'returns true when Enterprise, EnterpriseFee and OrderCycle are loaded', -> - Enterprise.loaded = EnterpriseFee.loaded = OrderCycle.loaded = true + beforeEach inject (RequestMonitor) -> + RequestMonitor.loading = false + Enterprise.loaded = true + EnterpriseFee.loaded = true + OrderCycle.loaded = true + + it 'returns true when all resources are loaded', -> expect(scope.loaded()).toBe(true) it 'returns false otherwise', -> - Enterprise.loaded = true - EnterpriseFee.loaded = true - OrderCycle.loaded = false + EnterpriseFee.loaded = false expect(scope.loaded()).toBe(false) it "delegates suppliedVariants to Enterprise", -> diff --git a/spec/support/request/web_helper.rb b/spec/support/request/web_helper.rb index cc6edc51c0..e95d02ede7 100644 --- a/spec/support/request/web_helper.rb +++ b/spec/support/request/web_helper.rb @@ -163,6 +163,11 @@ module WebHelper targetted_select2(value, options) end + def multi_select2_select(value, options) + find("#s2id_#{options[:from]}").find('ul li.select2-search-field').click + select_select2_result(value) + end + # Deprecated: Use have_select2 instead (spec/support/matchers/select2_matchers.rb) def have_select2_option(value, options) container = options[:dropdown_css] || ".select2-with-searchbox"