mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Merge branch 'victornava-legacy-login-fix'
This commit is contained in:
@@ -5,8 +5,10 @@ module Admin
|
||||
class OrderCyclesController < ResourceController
|
||||
include OrderCyclesHelper
|
||||
|
||||
before_filter :load_order_cycle_set, :only => :index
|
||||
before_filter :load_data_for_index, :only => :index
|
||||
before_filter :require_coordinator, only: :new
|
||||
around_filter :protect_invalid_destroy, only: :destroy
|
||||
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
@@ -73,18 +75,20 @@ module Admin
|
||||
|
||||
|
||||
protected
|
||||
def collection
|
||||
def collection(show_more=false)
|
||||
ocs = OrderCycle.managed_by(spree_current_user)
|
||||
|
||||
ocs.undated +
|
||||
ocs.soonest_closing +
|
||||
ocs.soonest_opening +
|
||||
ocs.most_recently_closed
|
||||
(show_more ? ocs.closed : ocs.recently_closed)
|
||||
end
|
||||
|
||||
private
|
||||
def load_order_cycle_set
|
||||
@order_cycle_set = OrderCycleSet.new :collection => collection
|
||||
def load_data_for_index
|
||||
@show_more = !!params[:show_more]
|
||||
@order_cycle_enterprises = OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises
|
||||
@order_cycle_set = OrderCycleSet.new :collection => collection(@show_more)
|
||||
end
|
||||
|
||||
def require_coordinator
|
||||
@@ -104,5 +108,14 @@ module Admin
|
||||
render :set_coordinator
|
||||
end
|
||||
end
|
||||
|
||||
def protect_invalid_destroy
|
||||
begin
|
||||
yield
|
||||
rescue ActiveRecord::InvalidForeignKey
|
||||
redirect_to main_app.admin_order_cycles_url
|
||||
flash[:error] = "That order cycle has been selected by a customer and cannot be deleted. To prevent customers from accessing it, please close it instead."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,10 +3,6 @@ module OrderCyclesHelper
|
||||
@current_order_cycle ||= current_order(false).andand.order_cycle
|
||||
end
|
||||
|
||||
def order_cycle_permitted_in(enterprises)
|
||||
enterprises.merge(order_cycle_permitted_enterprises)
|
||||
end
|
||||
|
||||
def order_cycle_permitted_enterprises
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises
|
||||
end
|
||||
@@ -79,6 +75,10 @@ module OrderCyclesHelper
|
||||
order_cycle.exchanges.to_enterprises(current_distributor).outgoing.first.pickup_time
|
||||
end
|
||||
|
||||
def can_delete?(order_cycle)
|
||||
Spree::Order.where(order_cycle_id: order_cycle).none?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validated_enterprise_options(enterprises, options={})
|
||||
|
||||
@@ -19,7 +19,14 @@ class OrderCycle < ActiveRecord::Base
|
||||
scope :undated, where(orders_open_at: nil, orders_close_at: nil)
|
||||
|
||||
scope :soonest_closing, lambda { active.order('order_cycles.orders_close_at ASC') }
|
||||
# TODO This method returns all the closed orders. So maybe we can replace it with :recently_closed.
|
||||
scope :most_recently_closed, lambda { closed.order('order_cycles.orders_close_at DESC') }
|
||||
|
||||
scope :recently_closed, -> {
|
||||
closed.
|
||||
where("order_cycles.orders_close_at >= ?", 31.days.ago).
|
||||
order("order_cycles.orders_close_at DESC") }
|
||||
|
||||
scope :soonest_opening, lambda { upcoming.order('order_cycles.orders_open_at ASC') }
|
||||
|
||||
scope :distributing_product, lambda { |product|
|
||||
|
||||
@@ -132,7 +132,7 @@ class AbilityDecorator
|
||||
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|
|
||||
can [:admin, :index, :read, :edit, :update, :bulk_update, :clone, :destroy], OrderCycle do |order_cycle|
|
||||
user.enterprises.include? order_cycle.coordinator
|
||||
end
|
||||
can [:for_order_cycle], Enterprise
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
- order_cycle = order_cycle_form.object
|
||||
- klass = "order-cycle-#{order_cycle.id} #{order_cycle_status_class order_cycle}"
|
||||
|
||||
%tr{class: klass}
|
||||
%td= link_to order_cycle.name, main_app.edit_admin_order_cycle_path(order_cycle)
|
||||
%td= order_cycle_form.text_field :orders_open_at, :class => 'datetimepicker', :value => order_cycle.orders_open_at
|
||||
@@ -7,7 +8,7 @@
|
||||
|
||||
- unless order_cycles_simple_index
|
||||
%td.suppliers
|
||||
- suppliers = order_cycle_permitted_in(order_cycle.suppliers)
|
||||
- suppliers = order_cycle.suppliers.merge(@order_cycle_enterprises)
|
||||
- supplier_list = suppliers.map(&:name).sort.join ', '
|
||||
- if suppliers.count > 3
|
||||
%span.with-tip{'data-powertip' => supplier_list}
|
||||
@@ -17,7 +18,7 @@
|
||||
= supplier_list
|
||||
%td= order_cycle.coordinator.name
|
||||
%td.distributors
|
||||
- distributors = order_cycle_permitted_in(order_cycle.distributors)
|
||||
- distributors = order_cycle.distributors.merge(@order_cycle_enterprises)
|
||||
- distributor_list = distributors.map(&:name).sort.join ', '
|
||||
- if distributors.count > 3
|
||||
%span.with-tip{'data-powertip' => distributor_list}
|
||||
@@ -25,16 +26,14 @@
|
||||
distributors
|
||||
- else
|
||||
= distributor_list
|
||||
%br/
|
||||
|
||||
%td.products
|
||||
- variant_images = capture do
|
||||
- order_cycle.variants.each do |v|
|
||||
= image_tag(v.images.first.attachment.url(:mini)) if v.images.present?
|
||||
%br/
|
||||
%span.with-tip{'data-powertip' => variant_images}= "#{order_cycle.variants.count} variants"
|
||||
%span= "#{order_cycle.variants.count} variants"
|
||||
|
||||
%td.actions
|
||||
= link_to '', main_app.edit_admin_order_cycle_path(order_cycle), class: 'edit-order-cycle icon-edit no-text'
|
||||
%td.actions
|
||||
= link_to '', main_app.clone_admin_order_cycle_path(order_cycle), class: 'clone-order-cycle icon-copy no-text'
|
||||
= link_to '', main_app.clone_admin_order_cycle_path(order_cycle), class: 'clone-order-cycle icon-copy no-text'
|
||||
- if can_delete?(order_cycle)
|
||||
%td.actions
|
||||
= link_to '', main_app.admin_order_cycle_path(order_cycle), class: 'delete-order-cycle icon-trash no-text', :method => :delete, data: { confirm: "Are you sure?" }
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
= content_for :page_actions do
|
||||
%li#new_order_cycle_link
|
||||
= button_link_to "New Order Cycle", main_app.new_admin_order_cycle_path, :icon => 'icon-plus', :id => 'admin_new_order_cycle_link'
|
||||
- if @show_more
|
||||
%li
|
||||
= button_link_to "Show less", main_app.admin_order_cycles_path
|
||||
- else
|
||||
%li
|
||||
= button_link_to "Show more", main_app.admin_order_cycles_path(params: { show_more: true })
|
||||
|
||||
= form_for @order_cycle_set, :url => main_app.bulk_update_admin_order_cycles_path do |f|
|
||||
%table.index#listing_order_cycles
|
||||
@@ -18,6 +24,7 @@
|
||||
%col
|
||||
%col
|
||||
%col
|
||||
%col
|
||||
|
||||
%thead
|
||||
%tr
|
||||
@@ -25,12 +32,13 @@
|
||||
%th Open
|
||||
%th Close
|
||||
- unless order_cycles_simple_index
|
||||
%th Suppliers
|
||||
%th Supplier
|
||||
%th Coordinator
|
||||
%th Distributors
|
||||
%th Products
|
||||
%th.actions
|
||||
%th.actions
|
||||
%th.actions
|
||||
|
||||
%tbody
|
||||
= f.fields_for :collection do |order_cycle_form|
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
Openfoodnetwork::Application.routes.draw do
|
||||
root :to => 'home#index'
|
||||
|
||||
|
||||
get "/#/login", to: "home#index", as: :spree_login
|
||||
get "/login", to: redirect("/#/login")
|
||||
|
||||
get "/map", to: "map#index", as: :map
|
||||
|
||||
|
||||
@@ -56,5 +56,21 @@ module Admin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "destroy" do
|
||||
let!(:distributor) { create(:distributor_enterprise, owner: distributor_owner) }
|
||||
|
||||
describe "when an order cycle becomes non-deletable, and we attempt to delete it" do
|
||||
let!(:oc) { create(:simple_order_cycle, coordinator: distributor) }
|
||||
let!(:order) { create(:order, order_cycle: oc) }
|
||||
|
||||
before { spree_get :destroy, id: oc.id }
|
||||
|
||||
it "displays an error message" do
|
||||
expect(response).to redirect_to admin_order_cycles_path
|
||||
expect(flash[:error]).to eq "That order cycle has been selected by a customer and cannot be deleted. To prevent customers from accessing it, please close it instead."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,8 +83,8 @@ feature %q{
|
||||
|
||||
# And I fill in the basic fields
|
||||
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2012-11-06 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2012-11-13 17:00:00'
|
||||
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'
|
||||
select 'My coordinator', from: 'order_cycle_coordinator_id'
|
||||
|
||||
# And I add a coordinator fee
|
||||
@@ -127,8 +127,8 @@ feature %q{
|
||||
|
||||
page.should have_selector 'a', text: 'Plums & Avos'
|
||||
|
||||
page.should have_selector "input[value='2012-11-06 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2012-11-13 17:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-11-06 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-11-13 17:00:00 +1100']"
|
||||
page.should have_content 'My coordinator'
|
||||
|
||||
page.should have_selector 'td.suppliers', text: 'My supplier'
|
||||
@@ -272,8 +272,8 @@ feature %q{
|
||||
|
||||
# And I update it
|
||||
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2012-11-06 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2012-11-13 17:00:00'
|
||||
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'
|
||||
select 'My coordinator', from: 'order_cycle_coordinator_id'
|
||||
|
||||
# And I configure some coordinator fees
|
||||
@@ -336,8 +336,8 @@ feature %q{
|
||||
|
||||
page.should have_selector 'a', text: 'Plums & Avos'
|
||||
|
||||
page.should have_selector "input[value='2012-11-06 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2012-11-13 17:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-11-06 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-11-13 17:00:00 +1100']"
|
||||
page.should have_content 'My coordinator'
|
||||
|
||||
page.should have_selector 'td.suppliers', text: 'My supplier'
|
||||
@@ -374,18 +374,18 @@ feature %q{
|
||||
|
||||
# And I fill in some new opening/closing times and save them
|
||||
within("tr.order-cycle-#{oc1.id}") do
|
||||
all('input').first.set '2012-12-01 12:00:00'
|
||||
all('input').last.set '2012-12-01 12:00:01'
|
||||
all('input').first.set '2040-12-01 12:00:00'
|
||||
all('input').last.set '2040-12-01 12:00:01'
|
||||
end
|
||||
|
||||
within("tr.order-cycle-#{oc2.id}") do
|
||||
all('input').first.set '2012-12-01 12:00:02'
|
||||
all('input').last.set '2012-12-01 12:00:03'
|
||||
all('input').first.set '2040-12-01 12:00:02'
|
||||
all('input').last.set '2040-12-01 12:00:03'
|
||||
end
|
||||
|
||||
within("tr.order-cycle-#{oc3.id}") do
|
||||
all('input').first.set '2012-12-01 12:00:04'
|
||||
all('input').last.set '2012-12-01 12:00:05'
|
||||
all('input').first.set '2040-12-01 12:00:04'
|
||||
all('input').last.set '2040-12-01 12:00:05'
|
||||
end
|
||||
|
||||
click_button 'Update'
|
||||
@@ -529,8 +529,8 @@ feature %q{
|
||||
save_screenshot '/Users/rob/Desktop/ss1.png'
|
||||
|
||||
fill_in 'order_cycle_name', with: 'My order cycle'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2012-11-06 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2012-11-13 17:00:00'
|
||||
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'
|
||||
|
||||
select 'Managed supplier', from: 'new_supplier_id'
|
||||
click_button 'Add supplier'
|
||||
@@ -651,8 +651,8 @@ feature %q{
|
||||
|
||||
# And I fill in the basic fields
|
||||
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2014-10-17 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2014-10-24 17:00:00'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2040-10-17 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2040-10-24 17:00:00'
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions'
|
||||
|
||||
@@ -677,8 +677,8 @@ feature %q{
|
||||
# Then my order cycle should have been created
|
||||
page.should have_content 'Your order cycle has been created.'
|
||||
page.should have_selector 'a', text: 'Plums & Avos'
|
||||
page.should have_selector "input[value='2014-10-17 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2014-10-24 17:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-10-17 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-10-24 17:00:00 +1100']"
|
||||
|
||||
# And it should have some variants selected
|
||||
oc = OrderCycle.last
|
||||
@@ -738,8 +738,8 @@ feature %q{
|
||||
|
||||
# And I fill in the basic fields
|
||||
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2014-10-17 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2014-10-24 17:00:00'
|
||||
fill_in 'order_cycle_orders_open_at', with: '2040-10-17 06:00:00'
|
||||
fill_in 'order_cycle_orders_close_at', with: '2040-10-24 17:00:00'
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'xy'
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'zzy'
|
||||
|
||||
@@ -760,8 +760,8 @@ feature %q{
|
||||
# Then my order cycle should have been updated
|
||||
page.should have_content 'Your order cycle has been updated.'
|
||||
page.should have_selector 'a', text: 'Plums & Avos'
|
||||
page.should have_selector "input[value='2014-10-17 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2014-10-24 17:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-10-17 06:00:00 +1100']"
|
||||
page.should have_selector "input[value='2040-10-24 17:00:00 +1100']"
|
||||
|
||||
# And it should have a variant selected
|
||||
oc = OrderCycle.last
|
||||
@@ -778,6 +778,15 @@ feature %q{
|
||||
end
|
||||
end
|
||||
|
||||
scenario "deleting an order cycle" do
|
||||
create(:simple_order_cycle, name: "Translusent Berries")
|
||||
login_to_admin_section
|
||||
click_link 'Order Cycles'
|
||||
page.should have_content("Translusent Berries")
|
||||
first('a.delete-order-cycle').click
|
||||
page.should_not have_content("Translusent Berries")
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ require 'spec_helper'
|
||||
|
||||
feature "Authentication", js: true do
|
||||
include UIComponentHelper
|
||||
|
||||
describe "login" do
|
||||
let(:user) { create(:user, password: "password", password_confirmation: "password") }
|
||||
|
||||
@@ -32,7 +33,7 @@ feature "Authentication", js: true do
|
||||
scenario "failing to login" do
|
||||
fill_in "Email", with: user.email
|
||||
click_login_button
|
||||
page.should have_content "Invalid email or password"
|
||||
page.should have_content "Invalid email or password"
|
||||
end
|
||||
|
||||
scenario "logging in successfully" do
|
||||
@@ -70,7 +71,7 @@ feature "Authentication", js: true do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
select_login_tab "Forgot Password?"
|
||||
end
|
||||
|
||||
|
||||
scenario "failing to reset password" do
|
||||
fill_in "Your email", with: "notanemail@myemail.com"
|
||||
click_reset_password_button
|
||||
@@ -78,7 +79,7 @@ feature "Authentication", js: true do
|
||||
end
|
||||
|
||||
scenario "resetting password" do
|
||||
fill_in "Your email", with: user.email
|
||||
fill_in "Your email", with: user.email
|
||||
click_reset_password_button
|
||||
page.should have_reset_password
|
||||
ActionMailer::Base.deliveries.last.subject.should =~ /Password Reset/
|
||||
@@ -90,29 +91,17 @@ feature "Authentication", js: true do
|
||||
browse_as_medium
|
||||
end
|
||||
scenario "showing login" do
|
||||
open_off_canvas
|
||||
open_off_canvas
|
||||
open_login_modal
|
||||
page.should have_login_modal
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "oldskool" do
|
||||
scenario "with valid credentials" do
|
||||
visit "/login"
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "Password", with: "password"
|
||||
click_button "Login"
|
||||
current_path.should == "/"
|
||||
end
|
||||
|
||||
scenario "with invalid credentials" do
|
||||
visit "/login"
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "Password", with: "this isn't my password"
|
||||
click_button "Login"
|
||||
page.should have_content "Invalid email or password"
|
||||
end
|
||||
scenario "Loggin by typing login/ redirects to /#/login" do
|
||||
visit "/login"
|
||||
uri = URI.parse(current_url)
|
||||
(uri.path + "#" + uri.fragment).should == '/#/login'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -90,6 +90,17 @@ describe OrderCycle do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#recently_closed" do
|
||||
it "finds the orders closed in the last 30 days sorted in descending order" do
|
||||
create(:simple_order_cycle, orders_close_at: 3.days.from_now)
|
||||
oc1 = create(:simple_order_cycle, orders_close_at: 1.day.ago)
|
||||
oc2 = create(:simple_order_cycle, orders_close_at: 30.days.ago)
|
||||
create(:simple_order_cycle, orders_close_at: 31.days.ago)
|
||||
|
||||
OrderCycle.recently_closed.should == [oc1 , oc2]
|
||||
end
|
||||
end
|
||||
|
||||
it "finds the most recently closed order cycles" do
|
||||
oc1 = create(:simple_order_cycle, orders_close_at: 2.hours.ago)
|
||||
oc2 = create(:simple_order_cycle, orders_close_at: 1.hour.ago)
|
||||
|
||||
@@ -371,11 +371,11 @@ module Spree
|
||||
let(:oc2) { create(:simple_order_cycle) }
|
||||
|
||||
it "should be able to read/write OrderCycles they are the co-ordinator of" do
|
||||
should have_ability([:admin, :index, :read, :edit, :update, :clone], for: oc1)
|
||||
should have_ability([:admin, :index, :read, :edit, :update, :clone, :destroy], for: oc1)
|
||||
end
|
||||
|
||||
it "should not be able to read/write OrderCycles they are not the co-ordinator of" do
|
||||
should_not have_ability([:admin, :index, :read, :create, :edit, :update, :clone], for: oc2)
|
||||
should_not have_ability([:admin, :index, :read, :create, :edit, :update, :clone, :destroy], for: oc2)
|
||||
end
|
||||
|
||||
it "should be able to create OrderCycles" do
|
||||
|
||||
Reference in New Issue
Block a user