From 3a505abfc723827775c2731aab7310a2c33252df Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 11:25:52 +1100 Subject: [PATCH 01/18] Adding WickedPDF for generation of order invoices --- Gemfile | 3 +++ Gemfile.lock | 5 +++++ config/initializers/wicked_pdf.rb | 5 +++++ 3 files changed, 13 insertions(+) create mode 100644 config/initializers/wicked_pdf.rb diff --git a/Gemfile b/Gemfile index 2b9555705e..8be45b8651 100644 --- a/Gemfile +++ b/Gemfile @@ -54,6 +54,9 @@ gem 'blockenspiel' gem 'acts-as-taggable-on', '~> 3.4' gem 'paper_trail', '~> 3.0.8' +gem 'wicked_pdf' +gem 'wkhtmltopdf-binary' + gem 'foreigner' gem 'immigrant' diff --git a/Gemfile.lock b/Gemfile.lock index 922105c2dc..3dfea17147 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -535,6 +535,9 @@ GEM whenever (0.9.2) activesupport (>= 2.3.4) chronic (>= 0.6.3) + wicked_pdf (0.11.0) + rails + wkhtmltopdf-binary (0.9.9.3) xml-simple (1.1.4) xpath (2.0.0) nokogiri (~> 1.3) @@ -628,3 +631,5 @@ DEPENDENCIES unicorn-rails webmock whenever + wicked_pdf + wkhtmltopdf-binary diff --git a/config/initializers/wicked_pdf.rb b/config/initializers/wicked_pdf.rb new file mode 100644 index 0000000000..d460773073 --- /dev/null +++ b/config/initializers/wicked_pdf.rb @@ -0,0 +1,5 @@ +WickedPdf.config = { + #:wkhtmltopdf => '/usr/local/bin/wkhtmltopdf', + #:layout => "pdf.html", + :exe_path => `bundle exec which wkhtmltopdf`.chomp +} From 104b100fe6eaf4aa1c5e591427fe1afd8c7768a8 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 11:27:25 +1100 Subject: [PATCH 02/18] Pulling distributor signoff out into separate partial --- .../spree/order_mailer/_signoff.html.haml | 15 +++++++++++ .../confirm_email_for_customer.html.haml | 27 ++++--------------- 2 files changed, 20 insertions(+), 22 deletions(-) create mode 100644 app/views/spree/order_mailer/_signoff.html.haml diff --git a/app/views/spree/order_mailer/_signoff.html.haml b/app/views/spree/order_mailer/_signoff.html.haml new file mode 100644 index 0000000000..d832c12a43 --- /dev/null +++ b/app/views/spree/order_mailer/_signoff.html.haml @@ -0,0 +1,15 @@ +%br +%p.callout + Kind regards, + %br + #{@order.distributor.contact} + %br + %br + = @order.distributor.name + %br + = @order.distributor.phone || "" + %br + %a{:href => "mailto:#{@order.distributor.email}", :target => "_blank"} + = @order.distributor.email + %br + = @order.distributor.website || "" diff --git a/app/views/spree/order_mailer/confirm_email_for_customer.html.haml b/app/views/spree/order_mailer/confirm_email_for_customer.html.haml index 0816bd432d..6bd0455a67 100644 --- a/app/views/spree/order_mailer/confirm_email_for_customer.html.haml +++ b/app/views/spree/order_mailer/confirm_email_for_customer.html.haml @@ -4,10 +4,10 @@ %table.column{:align => "left"} %tr %td - %h3 + %h3 Hi #{@order.bill_address.firstname}, %h4 - Thanks for shopping at + Thanks for shopping at %strong= "#{@order.distributor.name}!" %table.column{:align => "left"} %tr @@ -17,31 +17,14 @@ %p   %h4 - Order confirmation + Order confirmation %strong ##{@order.number} %p Here are your order details from - %strong= "#{@order.distributor.name}:" + %strong= "#{@order.distributor.name}:" = render 'order_summary' = render 'payment' = render 'shipping' = render 'special_instructions' - -%br -%p.callout - Kind regards, - %br - #{@order.distributor.contact} - %br - %br - = @order.distributor.name - %br - = @order.distributor.phone || "" - %br - %a{:href => "mailto:#{@order.distributor.email}", :target => "_blank"} - = @order.distributor.email - %br - = @order.distributor.website || "" - - += render 'signoff' From 6e7fc6a0f7e1f484eeb650d54f158ad5320c1ff3 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 13:06:09 +1100 Subject: [PATCH 03/18] Adding invoice action to orders controller, to allow sending of invoice email --- .../admin/orders_controller_decorator.rb | 8 ++++ app/mailers/spree/order_mailer_decorator.rb | 10 +++++ app/models/spree/ability_decorator.rb | 2 +- .../edit/add_invoice_button.html.haml.deface | 3 ++ .../spree/admin/orders/invoice.html.haml | 15 +++++++ .../order_mailer/invoice_email.html.haml | 10 +++++ config/locales/en.yml | 3 +- config/routes.rb | 1 + .../spree/admin/orders_controller_spec.rb | 39 ++++++++++++++++++- 9 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 app/overrides/spree/admin/orders/edit/add_invoice_button.html.haml.deface create mode 100644 app/views/spree/admin/orders/invoice.html.haml create mode 100644 app/views/spree/order_mailer/invoice_email.html.haml diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 87c6f3329a..88b1508a09 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -41,6 +41,14 @@ Spree::Admin::OrdersController.class_eval do respond_with(@order) { |format| format.html { redirect_to :back } } end + def invoice + pdf = render_to_string pdf: "invoice-#{@order.number}.pdf", template: "spree/admin/orders/invoice", formats: [:html], encoding: "UTF-8" + Spree::OrderMailer.invoice_email(@order.id, pdf).deliver + flash[:success] = t(:invoice_email_sent) + + respond_with(@order) { |format| format.html { redirect_to edit_admin_order_path(@order) } } + end + def update_distribution_charge @order.update_distribution_charge! end diff --git a/app/mailers/spree/order_mailer_decorator.rb b/app/mailers/spree/order_mailer_decorator.rb index c6eeb31df8..016b61efa4 100644 --- a/app/mailers/spree/order_mailer_decorator.rb +++ b/app/mailers/spree/order_mailer_decorator.rb @@ -21,4 +21,14 @@ Spree::OrderMailer.class_eval do :from => from_address, :subject => subject) end + + def invoice_email(order, pdf) + find_order(order) # Finds an order instance from an id + attachments["invoice-#{@order.number}.pdf"] = pdf if pdf.present? + subject = "#{Spree::Config[:site_name]} #{t(:invoice)} ##{@order.number}" + mail(:to => @order.email, + :from => from_address, + :subject => subject, + :reply_to => @order.distributor.email) + end end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index fe8995f213..5e6dba10b6 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -142,7 +142,7 @@ class AbilityDecorator def add_order_management_abilities(user) # Enterprise User can only access orders that they are a distributor for can [:index, :create], Spree::Order - can [:read, :update, :fire, :resend], Spree::Order do |order| + can [:read, :update, :fire, :resend, :invoice], Spree::Order do |order| # We allow editing orders with a nil distributor as this state occurs # during the order creation process from the admin backend order.distributor.nil? || user.enterprises.include?(order.distributor) diff --git a/app/overrides/spree/admin/orders/edit/add_invoice_button.html.haml.deface b/app/overrides/spree/admin/orders/edit/add_invoice_button.html.haml.deface new file mode 100644 index 0000000000..919ccad71a --- /dev/null +++ b/app/overrides/spree/admin/orders/edit/add_invoice_button.html.haml.deface @@ -0,0 +1,3 @@ +/ insert_after "code[erb-loud]:contains('button_link_to t(:resend)')" +- if @order.complete? + %li= button_link_to t(:invoice), invoice_admin_order_url(@order), :method => :put, :icon => 'icon-email', :data => { :confirm => t(:are_you_sure) } diff --git a/app/views/spree/admin/orders/invoice.html.haml b/app/views/spree/admin/orders/invoice.html.haml new file mode 100644 index 0000000000..8a301f5869 --- /dev/null +++ b/app/views/spree/admin/orders/invoice.html.haml @@ -0,0 +1,15 @@ += wicked_pdf_stylesheet_link_tag "mail/email" + + +%table{:width => "100%"} + %tbody + %tr + %td{ :align => "left" } + = "Order ##{@order.number}" + %td{ :align => "right" } + - if @order.total_tax > 0 + = "TAX" + = "INVOICE" + += render 'spree/order_mailer/order_summary' += render 'spree/order_mailer/payment' diff --git a/app/views/spree/order_mailer/invoice_email.html.haml b/app/views/spree/order_mailer/invoice_email.html.haml new file mode 100644 index 0000000000..e2a2aa8967 --- /dev/null +++ b/app/views/spree/order_mailer/invoice_email.html.haml @@ -0,0 +1,10 @@ +%table.social.white-bg{:width => "100%"} + %tr + %td + %h3 + Hi #{@order.bill_address.firstname}, + %h4 + Please find attached an invoice for your recent order from + %strong= "#{@order.distributor.name}" + += render 'signoff' diff --git a/config/locales/en.yml b/config/locales/en.yml index 3149620eab..b9a330b20e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -35,4 +35,5 @@ en: footer_email: "Email" footer_links_md: "Links" footer_about_url: "About URL" - footer_tos_url: "Terms of Service URL" \ No newline at end of file + footer_tos_url: "Terms of Service URL" + invoice: "Invoice" diff --git a/config/routes.rb b/config/routes.rb index f2ae6ea78f..ca1c34d611 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -204,6 +204,7 @@ Spree::Core::Engine.routes.prepend do end resources :orders do + put :invoice, on: :member get :managed, on: :collection end end diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb index dae1edcf29..f19ab4cdbb 100644 --- a/spec/controllers/spree/admin/orders_controller_spec.rb +++ b/spec/controllers/spree/admin/orders_controller_spec.rb @@ -29,7 +29,7 @@ describe Spree::Admin::OrdersController do end end - describe "managed" do + describe "#managed" do render_views let(:order_attributes) { [:id, :full_name, :email, :phone, :completed_at, :line_items, :distributor, :order_cycle, :number] } @@ -164,4 +164,41 @@ describe Spree::Admin::OrdersController do end end end + + describe "#invoice" do + let!(:user) { create(:user) } + let!(:enterprise_user) { create(:user) } + let!(:order) { create(:order_with_distributor, bill_address: create(:address), ship_address: create(:address)) } + let!(:distributor) { order.distributor } + let(:params) { { id: order.number } } + + context "as a normal user" do + before { controller.stub spree_current_user: user } + + it "should prevent me from sending order invoices" do + spree_get :invoice, params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "as an enterprise user" do + context "which is not a manager of the distributor for an order" do + before { controller.stub spree_current_user: user } + it "should prevent me from sending order invoices" do + spree_get :invoice, params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "which is a manager of the distributor for an order" do + before { controller.stub spree_current_user: distributor.owner } + it "should allow me to send order invoices" do + # expect do + spree_get :invoice, params + # end.to change{Spree::OrderMailer.deliveries.count}.by(1) + expect(response).to redirect_to spree.edit_admin_order_path(order) + end + end + end + end end From 40d627cb34d6a735d16d3e0fb12a7adb7f38e0a2 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 15:10:08 +1100 Subject: [PATCH 04/18] Adding new route for printing an order to pdf --- .../admin/orders_controller_decorator.rb | 4 +++ app/models/spree/ability_decorator.rb | 2 +- app/views/spree/admin/orders/print.html.haml | 19 ++++++++++ config/routes.rb | 1 + .../spree/admin/orders_controller_spec.rb | 35 +++++++++++++++++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 app/views/spree/admin/orders/print.html.haml diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 88b1508a09..7749950854 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -49,6 +49,10 @@ Spree::Admin::OrdersController.class_eval do respond_with(@order) { |format| format.html { redirect_to edit_admin_order_path(@order) } } end + def print + render pdf: "invoice-#{@order.number}", encoding: "UTF-8" + end + def update_distribution_charge @order.update_distribution_charge! end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 5e6dba10b6..241d1de114 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -142,7 +142,7 @@ class AbilityDecorator def add_order_management_abilities(user) # Enterprise User can only access orders that they are a distributor for can [:index, :create], Spree::Order - can [:read, :update, :fire, :resend, :invoice], Spree::Order do |order| + can [:read, :update, :fire, :resend, :invoice, :print], Spree::Order do |order| # We allow editing orders with a nil distributor as this state occurs # during the order creation process from the admin backend order.distributor.nil? || user.enterprises.include?(order.distributor) diff --git a/app/views/spree/admin/orders/print.html.haml b/app/views/spree/admin/orders/print.html.haml new file mode 100644 index 0000000000..f3fd436b91 --- /dev/null +++ b/app/views/spree/admin/orders/print.html.haml @@ -0,0 +1,19 @@ += wicked_pdf_stylesheet_link_tag "mail/email" + + +%table{:width => "100%"} + %tbody + %tr + %td{ :align => "left" } + %h4 + Order confirmation + %strong ##{@order.number} + %h5 + #{@order.bill_address.firstname} #{@order.bill_address.lastname} + %strong= " <#{@order.email}>" if @order.email + = @order.bill_address.phone if @order.bill_address.phone + %h5= "Customer Code: #{@order.customer.code}" + += render 'spree/order_mailer/order_summary' += render 'spree/order_mailer/payment' += render 'spree/order_mailer/shipping' diff --git a/config/routes.rb b/config/routes.rb index ca1c34d611..32a8c90e37 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -205,6 +205,7 @@ Spree::Core::Engine.routes.prepend do resources :orders do put :invoice, on: :member + get :print, on: :member get :managed, on: :collection end end diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb index f19ab4cdbb..9b65dd1a61 100644 --- a/spec/controllers/spree/admin/orders_controller_spec.rb +++ b/spec/controllers/spree/admin/orders_controller_spec.rb @@ -201,4 +201,39 @@ describe Spree::Admin::OrdersController do end end end + + describe "#print" do + let!(:user) { create(:user) } + let!(:enterprise_user) { create(:user) } + let!(:order) { create(:order_with_distributor, bill_address: create(:address), ship_address: create(:address)) } + let!(:distributor) { order.distributor } + let(:params) { { id: order.number } } + + context "as a normal user" do + before { controller.stub spree_current_user: user } + + it "should prevent me from sending order invoices" do + spree_get :print, params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "as an enterprise user" do + context "which is not a manager of the distributor for an order" do + before { controller.stub spree_current_user: user } + it "should prevent me from sending order invoices" do + spree_get :print, params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "which is a manager of the distributor for an order" do + before { controller.stub spree_current_user: distributor.owner } + it "should allow me to send order invoices" do + spree_get :print, params + expect(response).to render_template :print + end + end + end + end end From f12fd7b4a364c5c243ced437bb8751f91a48a183 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 15:10:36 +1100 Subject: [PATCH 05/18] Adding button for print action to admin orders show page --- .../spree/admin/orders/show/add_print_button.html.haml.deface | 3 +++ config/locales/en.yml | 1 + 2 files changed, 4 insertions(+) create mode 100644 app/overrides/spree/admin/orders/show/add_print_button.html.haml.deface diff --git a/app/overrides/spree/admin/orders/show/add_print_button.html.haml.deface b/app/overrides/spree/admin/orders/show/add_print_button.html.haml.deface new file mode 100644 index 0000000000..e48ad372e9 --- /dev/null +++ b/app/overrides/spree/admin/orders/show/add_print_button.html.haml.deface @@ -0,0 +1,3 @@ +/ insert_after "code[erb-loud]:contains('button_link_to t(:edit)')" +- if @order.complete? + %li= button_link_to t(:print), print_admin_order_url(@order), :method => :get, :icon => 'icon-print', :target => "_blank" diff --git a/config/locales/en.yml b/config/locales/en.yml index b9a330b20e..e6ede20009 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -19,6 +19,7 @@ en: producers: Aussie Producers producers_join: Australian producers are now welcome to join the Open Food Network. charges_sales_tax: Charges GST? + print: "Print" logo: "Logo (640x130)" logo_mobile: "Mobile logo (75x26)" From 47fb2270bd3c40a81afe2c1d944ad21ef07dd079 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 15:14:25 +1100 Subject: [PATCH 06/18] Making spec do the right thing --- spec/controllers/spree/admin/orders_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb index 9b65dd1a61..03907beebf 100644 --- a/spec/controllers/spree/admin/orders_controller_spec.rb +++ b/spec/controllers/spree/admin/orders_controller_spec.rb @@ -193,9 +193,9 @@ describe Spree::Admin::OrdersController do context "which is a manager of the distributor for an order" do before { controller.stub spree_current_user: distributor.owner } it "should allow me to send order invoices" do - # expect do + expect do spree_get :invoice, params - # end.to change{Spree::OrderMailer.deliveries.count}.by(1) + end.to change{Spree::OrderMailer.deliveries.count}.by(1) expect(response).to redirect_to spree.edit_admin_order_path(order) end end From 5b3e052f785d9fa53ccf79565d12f28c3b953876 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 16 Oct 2015 21:36:18 +1100 Subject: [PATCH 07/18] Using a compiled stylesheet for pdf styling --- app/views/spree/admin/orders/invoice.html.haml | 2 +- app/views/spree/admin/orders/print.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/spree/admin/orders/invoice.html.haml b/app/views/spree/admin/orders/invoice.html.haml index 8a301f5869..db94bb060d 100644 --- a/app/views/spree/admin/orders/invoice.html.haml +++ b/app/views/spree/admin/orders/invoice.html.haml @@ -1,4 +1,4 @@ -= wicked_pdf_stylesheet_link_tag "mail/email" += wicked_pdf_stylesheet_link_tag "mail/all" %table{:width => "100%"} diff --git a/app/views/spree/admin/orders/print.html.haml b/app/views/spree/admin/orders/print.html.haml index f3fd436b91..5a42699c98 100644 --- a/app/views/spree/admin/orders/print.html.haml +++ b/app/views/spree/admin/orders/print.html.haml @@ -1,4 +1,4 @@ -= wicked_pdf_stylesheet_link_tag "mail/email" += wicked_pdf_stylesheet_link_tag "mail/all" %table{:width => "100%"} From b35df3c945f1f5ae15940b377ab91420dc1f9e40 Mon Sep 17 00:00:00 2001 From: Maikel Date: Thu, 8 Oct 2015 15:24:48 +1100 Subject: [PATCH 08/18] Travis config for parallel execution on five nodes This Travis configuration runs rspec on five build machines in parallel. Currently, that takes 15 to 20 minutes. --- .travis.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0a0a55517f..fb9f4edf7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,24 @@ language: ruby bundler_args: --without development rvm: - "1.9.3" -services: postgresql -before_install: + +# The test cases are roughly split according to their test times. +# It would be better to use https://github.com/ArturT/knapsack. +env: + - TEST_CASES="./spec/models" + - TEST_CASES="./spec/controllers ./spec/views" + - TEST_CASES="./spec/requests ./spec/helpers ./spec/mailers" + - TEST_CASES="./spec/features/admin" + - TEST_CASES="./spec/features/consumer" + #- TEST_CASES="./spec/routing" + before_script: - cp config/database.travis.yml config/database.yml - - psql -c 'create database open_food_network_test;' -U postgres - cp config/application.yml.example config/application.yml + - RAILS_ENV=test bundle exec rake db:create db:schema:load + script: - - RAILS_ENV=test bundle exec rake db:migrate --trace - - bundle exec rake spec + - "bundle exec rspec $TEST_CASES" + notifications: email: false From a95727b3764e06709583482eed4c5d4b98663c05 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Sun, 11 Oct 2015 11:04:58 +1100 Subject: [PATCH 09/18] running all specs in Travis --- .travis.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb9f4edf7a..6a05fe87b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: ruby +cache: bundler bundler_args: --without development rvm: - "1.9.3" @@ -6,19 +7,27 @@ rvm: # The test cases are roughly split according to their test times. # It would be better to use https://github.com/ArturT/knapsack. env: - - TEST_CASES="./spec/models" - - TEST_CASES="./spec/controllers ./spec/views" - - TEST_CASES="./spec/requests ./spec/helpers ./spec/mailers" - - TEST_CASES="./spec/features/admin" - - TEST_CASES="./spec/features/consumer" - #- TEST_CASES="./spec/routing" + - TEST_CASES="./spec/features/admin" + - TEST_CASES="./spec/features/consumer ./spec/serializers ./spec/performance" + - TEST_CASES="./spec/models" + - TEST_CASES="./spec/controllers ./spec/views ./spec/jobs" + - TEST_CASES="./spec/requests ./spec/helpers ./spec/mailers ./spec/lib" KARMA="true" TIMEZONE="UTC" before_script: - cp config/database.travis.yml config/database.yml - cp config/application.yml.example config/application.yml - RAILS_ENV=test bundle exec rake db:create db:schema:load + - > + if [ "$KARMA" = "true" ]; then + npm install karma@0.12.31 + npm install karma-jasmine@0.1.5 + npm install karma-phantomjs-launcher@0.1.4 + npm install karma-coffee-preprocessor@0.2.1 + npm install -g karma-cli@0.0.4 + fi script: + - '[ "$KARMA" = "true" ] && bundle exec rake karma:run || echo "Skipping karma run"' - "bundle exec rspec $TEST_CASES" notifications: From 2ea1a596664ae28d1feee6b9a7b4ef88b881dbfa Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 9 Oct 2015 15:03:50 +1100 Subject: [PATCH 10/18] depricating db2fog.rb initializer due to invalid bucket name Once everybody changed their server config, we can remove that file. --- .gitignore | 1 + config/initializers/0_depricated_db2fog.rb | 15 +++++++++++++++ config/initializers/db2fog.rb | 6 ------ 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 config/initializers/0_depricated_db2fog.rb delete mode 100644 config/initializers/db2fog.rb diff --git a/.gitignore b/.gitignore index f465ad7306..42107a8e2e 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ config/abr.yml config/heroku_env.rb config/newrelic.yml config/initializers/feature_toggle.rb +config/initializers/db2fog.rb NERD_tree* coverage libpeerconnection.log diff --git a/config/initializers/0_depricated_db2fog.rb b/config/initializers/0_depricated_db2fog.rb new file mode 100644 index 0000000000..f2a2e76bc9 --- /dev/null +++ b/config/initializers/0_depricated_db2fog.rb @@ -0,0 +1,15 @@ +# Depricated: this initializer contains an invalid bucket name. +# Users of DB2fog should be able to configure DB2fog without changing the code. +# +# Name your configuration file `db2fog.rb`. It will be ignored by git. +# And it will overwrite this depricated configuration. +# +# See: https://github.com/yob/db2fog +# +# TODO: Remove this file in a future release. +DB2Fog.config = { + :aws_access_key_id => Spree::Config[:s3_access_key], + :aws_secret_access_key => Spree::Config[:s3_secret], + :directory => "db-backup_#{Spree::Config[:s3_bucket]}", + :provider => 'AWS' +} diff --git a/config/initializers/db2fog.rb b/config/initializers/db2fog.rb deleted file mode 100644 index 4c02b5dbcc..0000000000 --- a/config/initializers/db2fog.rb +++ /dev/null @@ -1,6 +0,0 @@ -DB2Fog.config = { - :aws_access_key_id => Spree::Config[:s3_access_key], - :aws_secret_access_key => Spree::Config[:s3_secret], - :directory => "db-backup_#{Spree::Config[:s3_bucket]}", - :provider => 'AWS' -} From 62d31f79ed18bb91815580239a96014202e1c580 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 9 Oct 2015 15:51:05 +1100 Subject: [PATCH 11/18] Remove obsolete deface --- .../show/rename_extended_description.html.haml.deface | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 app/overrides/admin/enterprises/show/rename_extended_description.html.haml.deface diff --git a/app/overrides/admin/enterprises/show/rename_extended_description.html.haml.deface b/app/overrides/admin/enterprises/show/rename_extended_description.html.haml.deface deleted file mode 100644 index 3571a52472..0000000000 --- a/app/overrides/admin/enterprises/show/rename_extended_description.html.haml.deface +++ /dev/null @@ -1,3 +0,0 @@ -/ replace_contents "[data-hook='long_description']" -%th Profile Info: -%td= @enterprise.long_description.andand.html_safe \ No newline at end of file From f152e4054c00659829e2eadaf40a21ae7a100a8c Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 9 Oct 2015 15:54:59 +1100 Subject: [PATCH 12/18] Remove obsolete deface --- .../_distributor_details/rich_text.html.haml.deface | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 app/overrides/enterprises/_distributor_details/rich_text.html.haml.deface diff --git a/app/overrides/enterprises/_distributor_details/rich_text.html.haml.deface b/app/overrides/enterprises/_distributor_details/rich_text.html.haml.deface deleted file mode 100644 index 15da8738dc..0000000000 --- a/app/overrides/enterprises/_distributor_details/rich_text.html.haml.deface +++ /dev/null @@ -1,10 +0,0 @@ -/ replace_contents "[data-hook='distributor-details']" -%h2= distributor.name -= distributor.distributor_info.andand.html_safe -.next-collection-at - -# Handle both checkout process and show order page - - order_cycle = current_order_cycle || @order.andand.order_cycle - - if order_cycle - = order_cycle.pickup_time_for(distributor) - - else - = distributor.next_collection_at From 8bd78eb1394891e29ee943a25ae39eefb661fec8 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 15 Oct 2015 18:18:26 +1100 Subject: [PATCH 13/18] spec_helper for lib/open_food_network/permissions_spec.rb --- spec/lib/open_food_network/permissions_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/lib/open_food_network/permissions_spec.rb b/spec/lib/open_food_network/permissions_spec.rb index 1b6e23eeb0..f00d8fb284 100644 --- a/spec/lib/open_food_network/permissions_spec.rb +++ b/spec/lib/open_food_network/permissions_spec.rb @@ -1,3 +1,4 @@ +require 'spec_helper' require 'open_food_network/permissions' module OpenFoodNetwork From 2357f46a4ed2cf8b796638434e3c5bfce6b62f69 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 15 Oct 2015 17:17:31 +1100 Subject: [PATCH 14/18] CI scripts use env vars The CI scripts are configurable through the environment. They had hardcoded configurations before. The Australian BuildKite setup will need global environment variables like this: STAGING_SSH_HOST=ofn-staging2 STAGING_CURRENT_PATH=/home/openfoodweb/apps/openfoodweb/current STAGING_SERVICE=unicorn_openfoodweb STAGING_DB_HOST=localhost STAGING_DB_USER=openfoodweb STAGING_DB=openfoodweb_production PRODUCTION_REMOTE=production:/home/openfoodweb/apps/openfoodweb/current --- script/ci/includes.sh | 25 ++++++++++++++++++------ script/ci/load_staging_baseline.sh | 21 +++++++++++++------- script/ci/push_to_production.sh | 17 +++++++++------- script/ci/push_to_staging.sh | 31 ++++++++++++++++++++---------- script/ci/save_staging_baseline.sh | 9 +++++++-- 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/script/ci/includes.sh b/script/ci/includes.sh index 619d03153e..f8ccd7b4b6 100644 --- a/script/ci/includes.sh +++ b/script/ci/includes.sh @@ -5,6 +5,17 @@ function load_environment { fi } +function require_env_vars { + for var in "$@"; do + eval value=\$$var + echo "$var=$value" + if [ -z "$value" ]; then + echo "Environment variable $var missing." + exit 1 + fi + done +} + function master_merged { if [[ `git tag -l "$BUILDKITE_BRANCH"` != '' ]]; then echo "'$BUILDKITE_BRANCH' is a tag." @@ -61,14 +72,16 @@ function checkout_ofn_commit { function drop_and_recreate_database { # Adapted from: http://stackoverflow.com/questions/12924466/capistrano-with-postgresql-error-database-is-being-accessed-by-other-users - psql -U openfoodweb postgres < pg_backend_pid() -AND datname='$1'; -DROP DATABASE $1; -CREATE DATABASE $1; +AND datname='$DB'; +DROP DATABASE $DB; +CREATE DATABASE $DB; EOF } diff --git a/script/ci/load_staging_baseline.sh b/script/ci/load_staging_baseline.sh index ac7d88569f..45a57cf5c0 100755 --- a/script/ci/load_staging_baseline.sh +++ b/script/ci/load_staging_baseline.sh @@ -5,23 +5,30 @@ # current database. set -e -cd /home/openfoodweb/apps/openfoodweb/current -source ./script/ci/includes.sh +source "`dirname $0`/includes.sh" + +# We need ruby to call script/delayed_job +export PATH="$HOME/.rbenv/shims:$PATH" + +echo "Checking environment variables" +require_env_vars CURRENT_PATH SERVICE DB_HOST DB_USER DB + +cd "$CURRENT_PATH" echo "Stopping unicorn and delayed job..." -service unicorn_openfoodweb stop +service "$SERVICE" stop RAILS_ENV=staging script/delayed_job -i 0 stop echo "Backing up current data..." mkdir -p db/backup -pg_dump -h localhost -U openfoodweb openfoodweb_production |gzip > db/backup/staging-`date +%Y%m%d%H%M%S`.sql.gz +pg_dump -h "$DB_HOST" -U "$DB_USER" "$DB" |gzip > db/backup/staging-`date +%Y%m%d%H%M%S`.sql.gz echo "Loading baseline data..." -drop_and_recreate_database "openfoodweb_production" -gunzip -c db/backup/staging-baseline.sql.gz |psql -h localhost -U openfoodweb openfoodweb_production +drop_and_recreate_database "$DB" -U "$DB_USER" +gunzip -c db/backup/staging-baseline.sql.gz |psql -h "$DB_HOST" -U "$DB_USER" "$DB" echo "Restarting unicorn..." -service unicorn_openfoodweb start +service "$SERVICE" start # Delayed job is restarted by monit echo "Done!" diff --git a/script/ci/push_to_production.sh b/script/ci/push_to_production.sh index 9294bcb492..413aeeabf8 100755 --- a/script/ci/push_to_production.sh +++ b/script/ci/push_to_production.sh @@ -1,18 +1,21 @@ #!/bin/bash set -e -source ./script/ci/includes.sh +source "`dirname $0`/includes.sh" -# Add production git remote if required -PROD_TEST=`git remote | grep -s 'production' || true` -if [[ "$PROD_TEST" != *production* ]]; then - git remote add production ubuntu@ofn-prod:apps/openfoodweb/current +OFN_COMMIT=$(get_ofn_commit) +if [ "$OFN_COMMIT" = 'OFN_COMMIT_NOT_FOUND' ]; then + OFN_COMMIT=$(git rev-parse $BUILDKITE_COMMIT) fi +echo "--- Checking environment variables" +require_env_vars OFN_COMMIT STAGING_SSH_HOST STAGING_CURRENT_PATH STAGING_SERVICE STAGING_DB_HOST STAGING_DB_USER STAGING_DB PRODUCTION_REMOTE + echo "--- Saving baseline data for staging" -ssh ofn-staging2 "/home/openfoodweb/apps/openfoodweb/current/script/ci/save_staging_baseline.sh `get_ofn_commit`" +VARS="CURRENT_PATH='$STAGING_CURRENT_PATH' SERVICE='$STAGING_SERVICE' DB_HOST='$STAGING_DB_HOST' DB_USER='$STAGING_DB_USER' DB='$STAGING_DB'" +ssh "$STAGING_SSH_HOST" "$VARS $STAGING_CURRENT_PATH/script/ci/save_staging_baseline.sh $OFN_COMMIT" echo "--- Pushing to production" exec 5>&1 -OUTPUT=$(git push production `get_ofn_commit`:master --force 2>&1 |tee /dev/fd/5) +OUTPUT=$(git push "$PRODUCTION_REMOTE" "$OFN_COMMIT":master --force 2>&1 |tee /dev/fd/5) [[ $OUTPUT =~ "Done" ]] diff --git a/script/ci/push_to_staging.sh b/script/ci/push_to_staging.sh index 7ace392276..c2ba9827da 100755 --- a/script/ci/push_to_staging.sh +++ b/script/ci/push_to_staging.sh @@ -1,21 +1,32 @@ #!/bin/bash set -e -source ./script/ci/includes.sh +source "`dirname $0`/includes.sh" -# Add staging git remote if required -ST2_TEST=`git remote | grep -s 'staging2' || true` -if [[ "$ST2_TEST" != *staging2* ]]; then - git remote add staging2 openfoodweb@ofn-staging2:apps/openfoodweb/current +OFN_COMMIT=$(get_ofn_commit) +if [ "$OFN_COMMIT" = 'OFN_COMMIT_NOT_FOUND' ]; then + OFN_COMMIT=$(git rev-parse $BUILDKITE_COMMIT) +fi +STAGING_REMOTE="${STAGING_REMOTE:-$STAGING_SSH_HOST:$STAGING_CURRENT_PATH}" + +echo "--- Checking environment variables" +require_env_vars OFN_COMMIT STAGING_SSH_HOST STAGING_CURRENT_PATH STAGING_REMOTE STAGING_SERVICE STAGING_DB_HOST STAGING_DB_USER STAGING_DB + +if [ "$REQUIRE_MASTER_MERGED" = false ]; then + echo "--- NOT verifying branch is based on current master" +else + echo "--- Verifying branch is based on current master" + exit_unless_master_merged fi -echo "--- Verifying branch is based on current master" -exit_unless_master_merged - +# TODO: Optimise staging deployment +# This is stopping and re-starting unicorn and delayed job. echo "--- Loading baseline data" -ssh ofn-staging2 "/home/openfoodweb/apps/openfoodweb/current/script/ci/load_staging_baseline.sh" +VARS="CURRENT_PATH='$STAGING_CURRENT_PATH' SERVICE='$STAGING_SERVICE' DB_HOST='$STAGING_DB_HOST' DB_USER='$STAGING_DB_USER' DB='$STAGING_DB'" +ssh "$STAGING_SSH_HOST" "$VARS $STAGING_CURRENT_PATH/script/ci/load_staging_baseline.sh" +# This is stopping and re-starting unicorn and delayed job again. echo "--- Pushing to staging" exec 5>&1 -OUTPUT=$(git push staging2 `get_ofn_commit`:master --force 2>&1 |tee /dev/fd/5) +OUTPUT=$(git push "$STAGING_REMOTE" "$OFN_COMMIT":master --force 2>&1 |tee /dev/fd/5) [[ $OUTPUT =~ "Done" ]] diff --git a/script/ci/save_staging_baseline.sh b/script/ci/save_staging_baseline.sh index 9fcc6c373b..37ff60bf17 100755 --- a/script/ci/save_staging_baseline.sh +++ b/script/ci/save_staging_baseline.sh @@ -9,12 +9,17 @@ # current code checked out. set -e +source "`dirname $0`/includes.sh" -cd /home/openfoodweb/apps/openfoodweb/current +echo "Checking environment variables" +require_env_vars CURRENT_PATH SERVICE DB_HOST DB_USER DB + +cd "$CURRENT_PATH" if [[ `git rev-parse HEAD` == $1 ]]; then mkdir -p db/backup - pg_dump -h localhost -U openfoodweb openfoodweb_production |gzip > db/backup/staging-baseline.sql.gz + pg_dump -h "$DB_HOST" -U "$DB_USER" "$DB" |gzip > db/backup/staging-baseline.sql.gz echo "Staging baseline data saved." else echo "Staging SHA does not match production, we will not save staging baseline data." + echo "'`git rev-parse HEAD`' is not '$1'" fi From 6781051fe6e6eff1cf9e79484ae68fcf03a2a26f Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 21 Oct 2015 10:27:16 +1100 Subject: [PATCH 15/18] enabling Travis container-based infrastucture --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6a05fe87b4..7a7209d417 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: ruby +sudo: false cache: bundler bundler_args: --without development rvm: From adf0a8466934f68de3a1087b03d44e364aec3b60 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 21 Oct 2015 15:42:28 +1100 Subject: [PATCH 16/18] Use ! version of find_by_permalink to recover on missing resource --- app/controllers/admin/enterprise_groups_controller.rb | 10 ++++++---- .../admin/producer_properties_controller.rb | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/admin/enterprise_groups_controller.rb b/app/controllers/admin/enterprise_groups_controller.rb index cb3ac80935..022b2f7d61 100644 --- a/app/controllers/admin/enterprise_groups_controller.rb +++ b/app/controllers/admin/enterprise_groups_controller.rb @@ -9,7 +9,7 @@ module Admin def move_up EnterpriseGroup.with_isolation_level_serializable do - @enterprise_group = EnterpriseGroup.find_by_permalink params[:enterprise_group_id] + @enterprise_group = find_resource @enterprise_group.move_higher end redirect_to main_app.admin_enterprise_groups_path @@ -17,7 +17,7 @@ module Admin def move_down EnterpriseGroup.with_isolation_level_serializable do - @enterprise_group = EnterpriseGroup.find_by_permalink params[:enterprise_group_id] + @enterprise_group = find_resource @enterprise_group.move_lower end redirect_to main_app.admin_enterprise_groups_path @@ -34,9 +34,11 @@ module Admin alias_method_chain :build_resource, :address # Overriding method on Spree's resource controller, - # so that resources are found using permalink + # so that resources are found using permalink. + # The ! version is important to raise a RecordNotFound error. def find_resource - EnterpriseGroup.find_by_permalink(params[:id]) + permalink = params[:id] || params[:enterprise_group_id] + EnterpriseGroup.find_by_permalink!(permalink) end private diff --git a/app/controllers/admin/producer_properties_controller.rb b/app/controllers/admin/producer_properties_controller.rb index 66656d9aa0..aca3e3f418 100644 --- a/app/controllers/admin/producer_properties_controller.rb +++ b/app/controllers/admin/producer_properties_controller.rb @@ -12,7 +12,7 @@ module Admin end def load_enterprise - @enterprise = Enterprise.find_by_permalink params[:enterprise_id] + @enterprise = Enterprise.find_by_permalink! params[:enterprise_id] end def load_properties From dc8166ec84663a021c4de1cc5356cfd8d188cbf5 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 21 Oct 2015 16:29:41 +1100 Subject: [PATCH 17/18] New CI script to check test state via GitHub API --- script/ci/check_github_status.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 script/ci/check_github_status.sh diff --git a/script/ci/check_github_status.sh b/script/ci/check_github_status.sh new file mode 100755 index 0000000000..c4ce47c6fa --- /dev/null +++ b/script/ci/check_github_status.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e +source "`dirname $0`/includes.sh" + +OFN_COMMIT=$(get_ofn_commit) +if [ "$OFN_COMMIT" = 'OFN_COMMIT_NOT_FOUND' ]; then + OFN_COMMIT=$(git rev-parse $BUILDKITE_COMMIT) +fi + +GITHUB_REPO="$(echo $BUILDKITE_REPO | sed 's/git@github.com:\(.*\).git/\1/')" +GITHUB_API_URL="https://api.github.com/repos/$GITHUB_REPO/commits/$OFN_COMMIT/status" + +echo "--- Checking environment variables" +require_env_vars OFN_COMMIT BUILDKITE_REPO + +echo "--- Checking GitHub status" +echo "Visiting $GITHUB_API_URL" +curl -s "$GITHUB_API_URL" | head -n 2 | grep '^ *"state": "success",$' From 0fd29dd32eb25e9d3ae5b29db7b9e7e472c06052 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 22 Oct 2015 13:43:15 +1100 Subject: [PATCH 18/18] use expect in bulk_order_management_spec --- .../admin/bulk_order_management_spec.rb | 348 +++++++++--------- 1 file changed, 172 insertions(+), 176 deletions(-) diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 8d52f21b48..5bcca783bd 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -14,7 +14,7 @@ feature %q{ it "displays a message when number of line items is zero" do visit '/admin/orders/bulk_management' - page.should have_text "No orders found." + expect(page).to have_text 'No orders found.' end context "displaying the list of line items" do @@ -29,14 +29,10 @@ feature %q{ visit '/admin/orders/bulk_management' end - #it "displays a 'loading' splash for line items" do - # page.should have_selector "div.loading", :text => "Loading Line Items..." - #end - it "displays a list of line items" do - page.should have_selector "tr#li_#{li1.id}" - page.should have_selector "tr#li_#{li2.id}" - page.should_not have_selector "tr#li_#{li3.id}" + expect(page).to have_selector "tr#li_#{li1.id}" + expect(page).to have_selector "tr#li_#{li2.id}" + expect(page).to_not have_selector "tr#li_#{li3.id}" end end @@ -51,39 +47,39 @@ feature %q{ end it "displays a column for user's full name" do - page.should have_selector "th.full_name", text: "NAME", :visible => true - page.should have_selector "td.full_name", text: o1.bill_address.full_name, :visible => true - page.should have_selector "td.full_name", text: "", :visible => true + expect(page).to have_selector "th.full_name", text: "NAME", :visible => true + expect(page).to have_selector "td.full_name", text: o1.bill_address.full_name, :visible => true + expect(page).to have_selector "td.full_name", text: "", :visible => true end it "displays a column for order date" do - page.should have_selector "th.date", text: "ORDER DATE", :visible => true - page.should have_selector "td.date", text: o1.completed_at.strftime("%F %T"), :visible => true - page.should have_selector "td.date", text: o2.completed_at.strftime("%F %T"), :visible => true + expect(page).to have_selector "th.date", text: "ORDER DATE", :visible => true + expect(page).to have_selector "td.date", text: o1.completed_at.strftime("%F %T"), :visible => true + expect(page).to have_selector "td.date", text: o2.completed_at.strftime("%F %T"), :visible => true end it "displays a column for producer" do - page.should have_selector "th.producer", text: "PRODUCER", :visible => true - page.should have_selector "td.producer", text: li1.product.supplier.name, :visible => true - page.should have_selector "td.producer", text: li2.product.supplier.name, :visible => true + expect(page).to have_selector "th.producer", text: "PRODUCER", :visible => true + expect(page).to have_selector "td.producer", text: li1.product.supplier.name, :visible => true + expect(page).to have_selector "td.producer", text: li2.product.supplier.name, :visible => true end it "displays a column for variant description, which shows only product name when options text is blank" do - page.should have_selector "th.variant", text: "PRODUCT: UNIT", :visible => true - page.should have_selector "td.variant", text: li1.product.name, :visible => true - page.should have_selector "td.variant", text: (li2.product.name + ": " + li2.variant.options_text), :visible => true + expect(page).to have_selector "th.variant", text: "PRODUCT: UNIT", :visible => true + expect(page).to have_selector "td.variant", text: li1.product.name, :visible => true + expect(page).to have_selector "td.variant", text: (li2.product.name + ": " + li2.variant.options_text), :visible => true end it "displays a field for quantity" do - page.should have_selector "th.quantity", text: "QUANTITY", :visible => true - page.should have_field "quantity", with: li1.quantity.to_s, :visible => true - page.should have_field "quantity", with: li2.quantity.to_s, :visible => true + expect(page).to have_selector "th.quantity", text: "QUANTITY", :visible => true + expect(page).to have_field "quantity", with: li1.quantity.to_s, :visible => true + expect(page).to have_field "quantity", with: li2.quantity.to_s, :visible => true end it "displays a column for max quantity" do - page.should have_selector "th.max", text: "MAX", :visible => true - page.should have_selector "td.max", text: li1.max_quantity.to_s, :visible => true - page.should have_selector "td.max", text: li2.max_quantity.to_s, :visible => true + expect(page).to have_selector "th.max", text: "MAX", :visible => true + expect(page).to have_selector "td.max", text: li1.max_quantity.to_s, :visible => true + expect(page).to have_selector "td.max", text: li2.max_quantity.to_s, :visible => true end end end @@ -102,17 +98,17 @@ feature %q{ end it "adds the class 'update-pending' to input elements when value is altered" do - page.should_not have_css "input[name='quantity'].update-pending" + expect(page).to_not have_css "input[name='quantity'].update-pending" fill_in "quantity", :with => 2 - page.should have_css "input[name='quantity'].update-pending" + expect(page).to have_css "input[name='quantity'].update-pending" end it "removes the class 'update-pending' from input elements when initial (DB) value is entered" do - page.should_not have_css "input[name='quantity'].update-pending" + expect(page).to_not have_css "input[name='quantity'].update-pending" fill_in "quantity", :with => 2 - page.should have_css "input[name='quantity'].update-pending" + expect(page).to have_css "input[name='quantity'].update-pending" fill_in "quantity", :with => 5 - page.should_not have_css "input[name='quantity'].update-pending" + expect(page).to_not have_css "input[name='quantity'].update-pending" end end @@ -126,14 +122,14 @@ feature %q{ it "displays an update button which submits pending changes" do fill_in "quantity", :with => 2 - page.should have_selector "input[name='quantity'].update-pending" - page.should_not have_selector "input[name='quantity'].update-success" - page.should have_button "Update" + expect(page).to have_selector "input[name='quantity'].update-pending" + expect(page).to_not have_selector "input[name='quantity'].update-success" + expect(page).to have_button "Update" click_button "Update" - page.should_not have_selector "input[name='quantity'].update-pending" - page.should have_selector "input[name='quantity'].update-success" - page.should have_selector "input[name='final_weight_volume'].update-success", visible: false - page.should have_selector "input[name='price'].update-success", visible: false + expect(page).to_not have_selector "input[name='quantity'].update-pending" + expect(page).to have_selector "input[name='quantity'].update-success" + expect(page).to have_selector "input[name='final_weight_volume'].update-success", visible: false + expect(page).to have_selector "input[name='price'].update-success", visible: false end end end @@ -153,10 +149,10 @@ feature %q{ visit '/admin/orders/bulk_management' first("div#columns_dropdown", :text => "COLUMNS").click first("div#columns_dropdown div.menu div.menu_item", text: "Weight/Volume").click - page.should_not have_css "input[name='price'].update-pending" + expect(page).to_not have_css "input[name='price'].update-pending" li1_final_weight_volume_column = find("tr#li_#{li1.id} td.final_weight_volume") li1_final_weight_volume_column.fill_in "final_weight_volume", :with => 1200 - page.should have_css "input[name='price'].update-pending", :visible => false + expect(page).to have_css "input[name='price'].update-pending", :visible => false end end @@ -165,10 +161,10 @@ feature %q{ visit '/admin/orders/bulk_management' #first("div#columns_dropdown", :text => "COLUMNS").click #first("div#columns_dropdown div.menu div.menu_item", text: "Quantity").click - page.should_not have_css "input[name='price'].update-pending" + expect(page).to_not have_css "input[name='price'].update-pending" li1_quantity_column = find("tr#li_#{li1.id} td.quantity") li1_quantity_column.fill_in "quantity", :with => 6 - page.should have_css "input[name='price'].update-pending", :visible => false + expect(page).to have_css "input[name='price'].update-pending", :visible => false end end @@ -177,10 +173,10 @@ feature %q{ visit '/admin/orders/bulk_management' first("div#columns_dropdown", :text => "COLUMNS").click first("div#columns_dropdown div.menu div.menu_item", text: "Weight/Volume").click - page.should_not have_css "input[name='price'].update-pending" + expect(page).to_not have_css "input[name='price'].update-pending" li1_quantity_column = find("tr#li_#{li1.id} td.quantity") li1_quantity_column.fill_in "quantity", :with => 6 - page.should have_css "input[name='final_weight_volume'].update-pending", :visible => false + expect(page).to have_css "input[name='final_weight_volume'].update-pending", :visible => false end end @@ -188,22 +184,22 @@ feature %q{ it "shows a column display toggle button, which shows a list of columns when clicked" do visit '/admin/orders/bulk_management' - page.should have_selector "th", :text => "NAME" - page.should have_selector "th", :text => "ORDER DATE" - page.should have_selector "th", :text => "PRODUCER" - page.should have_selector "th", :text => "PRODUCT: UNIT" - page.should have_selector "th", :text => "QUANTITY" - page.should have_selector "th", :text => "MAX" + expect(page).to have_selector "th", :text => "NAME" + expect(page).to have_selector "th", :text => "ORDER DATE" + expect(page).to have_selector "th", :text => "PRODUCER" + expect(page).to have_selector "th", :text => "PRODUCT: UNIT" + expect(page).to have_selector "th", :text => "QUANTITY" + expect(page).to have_selector "th", :text => "MAX" first("div#columns_dropdown", :text => "COLUMNS").click first("div#columns_dropdown div.menu div.menu_item", text: "Producer").click - page.should_not have_selector "th", :text => "PRODUCER" - page.should have_selector "th", :text => "NAME" - page.should have_selector "th", :text => "ORDER DATE" - page.should have_selector "th", :text => "PRODUCT: UNIT" - page.should have_selector "th", :text => "QUANTITY" - page.should have_selector "th", :text => "MAX" + expect(page).to_not have_selector "th", :text => "PRODUCER" + expect(page).to have_selector "th", :text => "NAME" + expect(page).to have_selector "th", :text => "ORDER DATE" + expect(page).to have_selector "th", :text => "PRODUCT: UNIT" + expect(page).to have_selector "th", :text => "QUANTITY" + expect(page).to have_selector "th", :text => "MAX" end end @@ -223,22 +219,22 @@ feature %q{ supplier_names = ["All"] Enterprise.is_primary_producer.each{ |e| supplier_names << e.name } find("div.select2-container#s2id_supplier_filter").click - supplier_names.each { |sn| page.should have_selector "div.select2-drop-active ul.select2-results li", text: sn } + supplier_names.each { |sn| expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: sn } find("div.select2-container#s2id_supplier_filter").click - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true select2_select s1.name, from: "supplier_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}" + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}" end it "displays all line items when 'All' is selected from supplier filter" do select2_select s1.name, from: "supplier_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true select2_select "All", from: "supplier_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true end end @@ -258,22 +254,22 @@ feature %q{ distributor_names = ["All"] Enterprise.is_distributor.each{ |e| distributor_names << e.name } find("div.select2-container#s2id_distributor_filter").click - distributor_names.each { |dn| page.should have_selector "div.select2-drop-active ul.select2-results li", text: dn } + distributor_names.each { |dn| expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: dn } find("div.select2-container#s2id_distributor_filter").click - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true select2_select d1.name, from: "distributor_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true end it "displays all line items when 'All' is selected from distributor filter" do select2_select d1.name, from: "distributor_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true select2_select "All", from: "distributor_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true end end @@ -293,24 +289,24 @@ feature %q{ it "displays a select box for order cycles, which filters line items by the selected order cycle" do order_cycle_names = OrderCycle.pluck(:name).push "All" find("div.select2-container#s2id_order_cycle_filter").click - order_cycle_names.each { |ocn| page.should have_selector "div.select2-drop-active ul.select2-results li", text: ocn } + order_cycle_names.each { |ocn| expect(page).to have_selector "div.select2-drop-active ul.select2-results li", text: ocn } find("div.select2-container#s2id_order_cycle_filter").click - page.should have_selector "tr#li_#{li1.id}" - page.should have_selector "tr#li_#{li2.id}" + expect(page).to have_selector "tr#li_#{li1.id}" + expect(page).to have_selector "tr#li_#{li2.id}" select2_select oc1.name, from: "order_cycle_filter" - page.should have_selector "#loading img.spinner" - page.should_not have_selector "#loading img.spinner" - page.should have_selector "tr#li_#{li1.id}" - page.should_not have_selector "tr#li_#{li2.id}" + expect(page).to have_selector "#loading img.spinner" + expect(page).to_not have_selector "#loading img.spinner" + expect(page).to have_selector "tr#li_#{li1.id}" + expect(page).to_not have_selector "tr#li_#{li2.id}" end it "displays all line items when 'All' is selected from order_cycle filter" do select2_select oc1.name, from: "order_cycle_filter" - page.should have_selector "tr#li_#{li1.id}" - page.should_not have_selector "tr#li_#{li2.id}" + expect(page).to have_selector "tr#li_#{li1.id}" + expect(page).to_not have_selector "tr#li_#{li2.id}" select2_select "All", from: "order_cycle_filter" - page.should have_selector "tr#li_#{li1.id}" - page.should have_selector "tr#li_#{li2.id}" + expect(page).to have_selector "tr#li_#{li1.id}" + expect(page).to have_selector "tr#li_#{li2.id}" end end @@ -334,34 +330,34 @@ feature %q{ it "allows filters to be used in combination" do select2_select oc1.name, from: "order_cycle_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true select2_select d1.name, from: "distributor_filter" select2_select s1.name, from: "supplier_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true select2_select d2.name, from: "distributor_filter" select2_select s2.name, from: "supplier_filter" - page.should_not have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true select2_select oc2.name, from: "order_cycle_filter" - page.should_not have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true end it "displays a 'Clear All' button which sets all select filters to 'All'" do select2_select oc1.name, from: "order_cycle_filter" select2_select d1.name, from: "distributor_filter" select2_select s1.name, from: "supplier_filter" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true - page.should have_button "Clear All" + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_button "Clear All" click_button "Clear All" - page.should have_selector "div#s2id_order_cycle_filter a.select2-choice", text: "All" - page.should have_selector "div#s2id_supplier_filter a.select2-choice", text: "All" - page.should have_selector "div#s2id_distributor_filter a.select2-choice", text: "All" - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "div#s2id_order_cycle_filter a.select2-choice", text: "All" + expect(page).to have_selector "div#s2id_supplier_filter a.select2-choice", text: "All" + expect(page).to have_selector "div#s2id_distributor_filter a.select2-choice", text: "All" + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true end end end @@ -379,17 +375,17 @@ feature %q{ end it "displays a quick search input" do - page.should have_field "quick_search" + expect(page).to have_field "quick_search" end it "filters line items based on their attributes and the contents of the quick search input" do - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true - page.should have_selector "tr#li_#{li3.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li3.id}", visible: true fill_in "quick_search", :with => o1.email - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true - page.should_not have_selector "tr#li_#{li3.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li3.id}", visible: true end end @@ -408,37 +404,37 @@ feature %q{ it "displays date fields for filtering orders, with default values set" do one_week_ago = Date.today.prev_day(7).strftime("%F") tonight = Date.tomorrow.strftime("%F") - page.should have_field "start_date_filter", with: one_week_ago - page.should have_field "end_date_filter", with: tonight + expect(page).to have_field "start_date_filter", with: one_week_ago + expect(page).to have_field "end_date_filter", with: tonight end it "only loads line items whose orders meet the date restriction criteria" do - page.should_not have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true - page.should_not have_selector "tr#li_#{li3.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li3.id}", visible: true end it "displays only line items whose orders meet the date restriction criteria, when changed" do fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F") - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true - page.should_not have_selector "tr#li_#{li3.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li3.id}", visible: true fill_in "end_date_filter", :with => (Date.today + 3).strftime("%F") - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true - page.should have_selector "tr#li_#{li3.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li3.id}", visible: true end context "when pending changes exist" do it "alerts the user when dates are altered" do li2_quantity_column = find("tr#li_#{li2.id} td.quantity") li2_quantity_column.fill_in "quantity", :with => li2.quantity + 1 - page.should_not have_button "IGNORE" - page.should_not have_button "SAVE" + expect(page).to_not have_button "IGNORE" + expect(page).to_not have_button "SAVE" fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") - page.should have_button "IGNORE" - page.should have_button "SAVE" + expect(page).to have_button "IGNORE" + expect(page).to have_button "SAVE" end it "saves pendings changes when 'SAVE' button is clicked" do @@ -446,12 +442,12 @@ feature %q{ page.fill_in "quantity", :with => (li2.quantity + 1).to_s end fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") - page.should have_selector "input[name='quantity'].update-pending" + expect(page).to have_selector "input[name='quantity'].update-pending" click_button "SAVE" - page.should have_no_selector "input.update-pending" - page.should have_selector "input[name='quantity'].update-success" + expect(page).to have_no_selector "input.update-pending" + expect(page).to have_selector "input[name='quantity'].update-success" within("tr#li_#{li2.id} td.quantity") do - page.should have_field "quantity", :with => ( li2.quantity + 1 ).to_s + expect(page).to have_field "quantity", :with => ( li2.quantity + 1 ).to_s end end @@ -461,9 +457,9 @@ feature %q{ end fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") click_button "IGNORE" - page.should_not have_selector "input[name='quantity'].update-pending" + expect(page).to_not have_selector "input[name='quantity'].update-pending" within("tr#li_#{li2.id} td.quantity") do - page.should have_field "quantity", :with => ( li2.quantity ).to_s + expect(page).to have_field "quantity", :with => ( li2.quantity ).to_s end end end @@ -480,36 +476,36 @@ feature %q{ end it "displays a checkbox for each line item in the list" do - page.should have_selector "tr#li_#{li1.id} input[type='checkbox'][name='bulk']" - page.should have_selector "tr#li_#{li2.id} input[type='checkbox'][name='bulk']" + expect(page).to have_selector "tr#li_#{li1.id} input[type='checkbox'][name='bulk']" + expect(page).to have_selector "tr#li_#{li2.id} input[type='checkbox'][name='bulk']" end it "displays a checkbox to which toggles the 'checked' state of all checkboxes" do check "toggle_bulk" - page.all("input[type='checkbox'][name='bulk']").each{ |checkbox| checkbox.checked?.should == true } + page.all("input[type='checkbox'][name='bulk']").each{ |checkbox| expect(checkbox.checked?).to be true } uncheck "toggle_bulk" - page.all("input[type='checkbox'][name='bulk']").each{ |checkbox| checkbox.checked?.should == false } + page.all("input[type='checkbox'][name='bulk']").each{ |checkbox| expect(checkbox.checked?).to be false } end it "displays a bulk action select box with a list of actions" do list_of_actions = ['Delete Selected'] find("div#bulk_actions_dropdown").click within("div#bulk_actions_dropdown") do - list_of_actions.each { |action_name| page.should have_selector "div.menu_item", text: action_name } + list_of_actions.each { |action_name| expect(page).to have_selector "div.menu_item", text: action_name } end end context "performing actions" do it "deletes selected items" do - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true within("tr#li_#{li2.id} td.bulk") do check "bulk" end find("div#bulk_actions_dropdown").click find("div#bulk_actions_dropdown div.menu_item", :text => "Delete Selected" ).click - page.should have_selector "tr#li_#{li1.id}", visible: true - page.should_not have_selector "tr#li_#{li2.id}", visible: true + expect(page).to have_selector "tr#li_#{li1.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true end end @@ -518,9 +514,9 @@ feature %q{ fill_in "quick_search", with: o1.number check "toggle_bulk" fill_in "quick_search", with: '' - find("tr#li_#{li1.id} input[type='checkbox'][name='bulk']").checked?.should == true - find("tr#li_#{li2.id} input[type='checkbox'][name='bulk']").checked?.should == false - find("input[type='checkbox'][name='toggle_bulk']").checked?.should == false + expect(find("tr#li_#{li1.id} input[type='checkbox'][name='bulk']").checked?).to be true + expect(find("tr#li_#{li2.id} input[type='checkbox'][name='bulk']").checked?).to be false + expect(find("input[type='checkbox'][name='toggle_bulk']").checked?).to be false end it "only applies the delete action to filteredLineItems" do @@ -529,8 +525,8 @@ feature %q{ find("div#bulk_actions_dropdown").click find("div#bulk_actions_dropdown div.menu_item", :text => "Delete Selected" ).click fill_in "quick_search", with: '' - page.should_not have_selector "tr#li_#{li1.id}", visible: true - page.should have_selector "tr#li_#{li2.id}", visible: true + expect(page).to_not have_selector "tr#li_#{li1.id}", visible: true + expect(page).to have_selector "tr#li_#{li2.id}", visible: true end end end @@ -547,11 +543,11 @@ feature %q{ end it "shows an edit button for line_items, which takes the user to the standard edit page for the order" do - page.should have_selector "a.edit-order", :count => 2 + expect(page).to have_selector "a.edit-order", :count => 2 first("a.edit-order").click - URI.parse(current_url).path.should == "/admin/orders/#{o1.number}/edit" + expect(URI.parse(current_url).path).to eq "/admin/orders/#{o1.number}/edit" end end @@ -566,15 +562,15 @@ feature %q{ end it "shows a delete button for each line item" do - page.should have_selector "a.delete-line-item", :count => 2 + expect(page).to have_selector "a.delete-line-item", :count => 2 end it "removes a line item when the relevant delete button is clicked" do first("a.delete-line-item").click - page.should_not have_selector "a.delete-line-item", :count => 2 - page.should have_selector "a.delete-line-item", :count => 1 + expect(page).to_not have_selector "a.delete-line-item", :count => 2 + expect(page).to have_selector "a.delete-line-item", :count => 1 visit '/admin/orders/bulk_management' - page.should have_selector "a.delete-line-item", :count => 1 + expect(page).to have_selector "a.delete-line-item", :count => 1 end end end @@ -598,32 +594,32 @@ feature %q{ end it "displays group buy calc box" do - page.should have_selector "div#group_buy_calculation", :visible => true + expect(page).to have_selector "div#group_buy_calculation", :visible => true within "div#group_buy_calculation" do - page.should have_text "Group Buy Unit Size" - page.should have_text "5 kg" - page.should have_text "Total Quantity Ordered" - page.should have_text "4 kg" - page.should have_text "Max Quantity Ordered" - page.should have_text "9 kg" - page.should have_text "Current Fulfilled Units" - page.should have_text "0.8" - page.should have_text "Max Fulfilled Units" - page.should have_text "1.8" - page.should have_selector "div.shared_resource", :visible => true + expect(page).to have_text "Group Buy Unit Size" + expect(page).to have_text "5 kg" + expect(page).to have_text "Total Quantity Ordered" + expect(page).to have_text "4 kg" + expect(page).to have_text "Max Quantity Ordered" + expect(page).to have_text "9 kg" + expect(page).to have_text "Current Fulfilled Units" + expect(page).to have_text "0.8" + expect(page).to have_text "Max Fulfilled Units" + expect(page).to have_text "1.8" + expect(page).to have_selector "div.shared_resource", :visible => true within "div.shared_resource" do - page.should have_selector "span", :text => "Shared Resource?" - page.should have_selector "input#shared_resource" + expect(page).to have_selector "span", :text => "Shared Resource?" + expect(page).to have_selector "input#shared_resource" end end end it "all line items of the same variant" do - page.should_not have_selector "tr#li_#{li1.id}", :visible => true - page.should_not have_selector "tr#li_#{li2.id}", :visible => true - page.should have_selector "tr#li_#{li3.id}", :visible => true - page.should have_selector "tr#li_#{li4.id}", :visible => true + expect(page).to_not have_selector "tr#li_#{li1.id}", :visible => true + expect(page).to_not have_selector "tr#li_#{li2.id}", :visible => true + expect(page).to have_selector "tr#li_#{li3.id}", :visible => true + expect(page).to have_selector "tr#li_#{li4.id}", :visible => true end context "clicking 'Clear' in group buy box" do @@ -632,11 +628,11 @@ feature %q{ end it "shows all products and clears group buy box" do - page.should_not have_selector "div#group_buy_calculation", :visible => true - page.should have_selector "tr#li_#{li1.id}", :visible => true - page.should have_selector "tr#li_#{li2.id}", :visible => true - page.should have_selector "tr#li_#{li3.id}", :visible => true - page.should have_selector "tr#li_#{li4.id}", :visible => true + expect(page).to_not have_selector "div#group_buy_calculation", :visible => true + expect(page).to have_selector "tr#li_#{li1.id}", :visible => true + expect(page).to have_selector "tr#li_#{li2.id}", :visible => true + expect(page).to have_selector "tr#li_#{li3.id}", :visible => true + expect(page).to have_selector "tr#li_#{li4.id}", :visible => true end end end @@ -661,16 +657,16 @@ feature %q{ it "displays a Bulk Management Tab under the Orders item" do visit '/admin/orders' - page.should have_link "Bulk Order Management" + expect(page).to have_link "Bulk Order Management" click_link "Bulk Order Management" - page.should have_selector "h1.page-title", text: "Bulk Order Management" + expect(page).to have_selector "h1.page-title", text: "Bulk Order Management" end it "shows only line item from orders that I distribute, and not those that I supply" do visit '/admin/orders/bulk_management' - page.should have_selector "tr#li_#{line_item_distributed.id}", :visible => true - page.should_not have_selector "tr#li_#{line_item_not_distributed.id}", :visible => true + expect(page).to have_selector "tr#li_#{line_item_distributed.id}", :visible => true + expect(page).to_not have_selector "tr#li_#{line_item_not_distributed.id}", :visible => true end end end