Merge branch 'victornava-legacy-login-fix'

This commit is contained in:
Rohan Mitchell
2015-03-25 10:37:14 +11:00
12 changed files with 120 additions and 66 deletions

View File

@@ -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

View File

@@ -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={})

View File

@@ -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|

View File

@@ -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

View File

@@ -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?" }

View File

@@ -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|

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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