mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-12 18:36:49 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0ee4aab01 | ||
|
|
452593b6f1 | ||
|
|
23740ef908 | ||
|
|
ba04208999 | ||
|
|
590ce67f38 | ||
|
|
e11ea929c3 | ||
|
|
6d283ac839 | ||
|
|
725807f66d | ||
|
|
149df6569c | ||
|
|
7daa7032aa | ||
|
|
8b7119beea | ||
|
|
201e87bf12 | ||
|
|
0fffd6b4e3 | ||
|
|
c516d40d4a | ||
|
|
b69c3fd826 | ||
|
|
1a450733a3 | ||
|
|
ffde7a38df | ||
|
|
8b4b0621db | ||
|
|
69fb8b2afe |
@@ -341,7 +341,6 @@ Metrics/LineLength:
|
||||
- spec/performance/orders_controller_spec.rb
|
||||
- spec/performance/shop_controller_spec.rb
|
||||
- spec/requests/checkout/failed_checkout_spec.rb
|
||||
- spec/requests/checkout/stripe_connect_spec.rb
|
||||
- spec/requests/embedded_shopfronts_headers_spec.rb
|
||||
- spec/requests/shop_spec.rb
|
||||
- spec/serializers/admin/customer_serializer_spec.rb
|
||||
@@ -482,63 +481,26 @@ Metrics/AbcSize:
|
||||
|
||||
Metrics/BlockLength:
|
||||
Max: 25
|
||||
ExcludedMethods: ["class_eval", "collection", "context", "describe", "it", "member", "namespace", "resource", "resources"]
|
||||
ExcludedMethods: [
|
||||
"class_eval",
|
||||
"collection",
|
||||
"context",
|
||||
"describe",
|
||||
"feature",
|
||||
"it",
|
||||
"member",
|
||||
"namespace",
|
||||
"resource",
|
||||
"resources",
|
||||
"scenario"
|
||||
]
|
||||
Exclude:
|
||||
- lib/tasks/data.rake
|
||||
- lib/tasks/dev.rake
|
||||
- spec/controllers/spree/admin/invoices_controller_spec.rb
|
||||
- spec/factories/variant_factory.rb
|
||||
- spec/features/admin/adjustments_spec.rb
|
||||
- spec/features/admin/bulk_order_management_spec.rb
|
||||
- spec/features/admin/bulk_product_update_spec.rb
|
||||
- spec/features/admin/caching_spec.rb
|
||||
- spec/features/admin/content_spec.rb
|
||||
- spec/features/admin/customers_spec.rb
|
||||
- spec/features/admin/enterprise_fees_spec.rb
|
||||
- spec/features/admin/enterprise_groups_spec.rb
|
||||
- spec/features/admin/enterprise_relationships_spec.rb
|
||||
- spec/features/admin/enterprise_roles_spec.rb
|
||||
- spec/features/admin/enterprises/images_spec.rb
|
||||
- spec/features/admin/enterprises/index_spec.rb
|
||||
- spec/features/admin/enterprises_spec.rb
|
||||
- spec/features/admin/enterprise_user_spec.rb
|
||||
- spec/features/admin/multilingual_spec.rb
|
||||
- spec/features/admin/order_cycles_spec.rb
|
||||
- spec/features/admin/orders_spec.rb
|
||||
- spec/features/admin/overview_spec.rb
|
||||
- spec/features/admin/payment_method_spec.rb
|
||||
- spec/features/admin/product_import_spec.rb
|
||||
- spec/features/admin/products_spec.rb
|
||||
- spec/features/admin/reports/enterprise_fee_summaries_spec.rb
|
||||
- spec/features/admin/reports_spec.rb
|
||||
- spec/features/admin/schedules_spec.rb
|
||||
- spec/features/admin/shipping_methods_spec.rb
|
||||
- spec/features/admin/subscriptions_spec.rb
|
||||
- spec/features/admin/tag_rules_spec.rb
|
||||
- spec/features/admin/tax_settings_spec.rb
|
||||
- spec/features/admin/users_spec.rb
|
||||
- spec/features/admin/variant_overrides_spec.rb
|
||||
- spec/features/admin/variants_spec.rb
|
||||
- spec/features/consumer/account/cards_spec.rb
|
||||
- spec/features/consumer/account/settings_spec.rb
|
||||
- spec/features/consumer/account_spec.rb
|
||||
- spec/features/consumer/authentication_spec.rb
|
||||
- spec/features/consumer/cookies_spec.rb
|
||||
- spec/features/consumer/external_services_spec.rb
|
||||
- spec/features/consumer/groups_spec.rb
|
||||
- spec/features/consumer/multilingual_spec.rb
|
||||
- spec/features/consumer/producers_spec.rb
|
||||
- spec/features/consumer/registration_spec.rb
|
||||
- spec/features/consumer/shopping/cart_spec.rb
|
||||
- spec/features/consumer/shopping/checkout_auth_spec.rb
|
||||
- spec/features/consumer/shopping/checkout_spec.rb
|
||||
- spec/features/consumer/shopping/embedded_groups_spec.rb
|
||||
- spec/features/consumer/shopping/embedded_shopfronts_spec.rb
|
||||
- spec/features/consumer/shopping/orders_spec.rb
|
||||
- spec/features/consumer/shopping/products_spec.rb
|
||||
- spec/features/consumer/shopping/shopping_spec.rb
|
||||
- spec/features/consumer/shopping/variant_overrides_spec.rb
|
||||
- spec/features/consumer/shops_spec.rb
|
||||
- spec/lib/open_food_network/group_buy_report_spec.rb
|
||||
- spec/models/tag_rule/discount_order_spec.rb
|
||||
- spec/spec_helper.rb
|
||||
|
||||
@@ -186,7 +186,19 @@ Metrics/AbcSize:
|
||||
|
||||
Metrics/BlockLength:
|
||||
Max: 25
|
||||
ExcludedMethods: ["class_eval", "collection", "context", "describe", "it", "member", "namespace", "resource", "resources"]
|
||||
ExcludedMethods: [
|
||||
"class_eval",
|
||||
"collection",
|
||||
"context",
|
||||
"describe",
|
||||
"feature",
|
||||
"it",
|
||||
"member",
|
||||
"namespace",
|
||||
"resource",
|
||||
"resources",
|
||||
"scenario"
|
||||
]
|
||||
|
||||
Metrics/BlockNesting:
|
||||
Max: 3
|
||||
|
||||
10
Gemfile.lock
10
Gemfile.lock
@@ -141,8 +141,8 @@ GEM
|
||||
activerecord (>= 3.2, < 5)
|
||||
acts_as_list (0.2.0)
|
||||
activerecord (>= 3.0)
|
||||
addressable (2.6.0)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
andand (1.3.3)
|
||||
angular-rails-templates (0.3.0)
|
||||
railties (>= 3.1)
|
||||
@@ -164,7 +164,7 @@ GEM
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.5.0)
|
||||
bugsnag (6.11.1)
|
||||
bugsnag (6.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.0.4)
|
||||
byebug (9.0.6)
|
||||
@@ -210,7 +210,7 @@ GEM
|
||||
compass (~> 1.0.0)
|
||||
sass-rails (< 5.1)
|
||||
sprockets (< 4.0)
|
||||
concurrent-ruby (1.1.4)
|
||||
concurrent-ruby (1.1.5)
|
||||
connection_pool (2.2.2)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
@@ -739,7 +739,7 @@ GEM
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (~> 1.0)
|
||||
selenium-webdriver (~> 3.0)
|
||||
webmock (3.6.2)
|
||||
webmock (3.7.1)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
|
||||
@@ -127,6 +127,9 @@ module Api
|
||||
|
||||
render text: {
|
||||
products: serializer,
|
||||
# This line is used by the PagedFetcher JS service (inventory).
|
||||
pages: products.num_pages,
|
||||
# This hash is used by the BulkProducts JS service.
|
||||
pagination: pagination_data(products)
|
||||
}.to_json
|
||||
end
|
||||
|
||||
@@ -14,7 +14,9 @@ en_US:
|
||||
spree/product:
|
||||
primary_taxon: "Product Category"
|
||||
supplier: "Supplier"
|
||||
shipping_category_id: "Shipping Category"
|
||||
variant_unit: "Variant Unit"
|
||||
variant_unit_name: "Variant Unit Name"
|
||||
order_cycle:
|
||||
orders_close_at: Close Date
|
||||
errors:
|
||||
@@ -75,6 +77,8 @@ en_US:
|
||||
user_confirmations:
|
||||
spree_user:
|
||||
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
|
||||
confirmation_sent: "Email confirmation sent"
|
||||
confirmation_not_sent: "Error sending confirmation email"
|
||||
user_registrations:
|
||||
spree_user:
|
||||
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
|
||||
@@ -85,9 +89,12 @@ en_US:
|
||||
Were you a guest last time? Perhaps you need to create an account or reset your password.
|
||||
unconfirmed: "You have to confirm your account before continuing."
|
||||
already_registered: "This email address is already registered. Please log in to continue, or go back and use another email address."
|
||||
success:
|
||||
logged_in_succesfully: "Logged in successfully"
|
||||
user_passwords:
|
||||
spree_user:
|
||||
updated_not_active: "Your password has been reset, but your email has not been confirmed yet."
|
||||
updated: "Your password was changed successfully. You are now signed in."
|
||||
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
|
||||
models:
|
||||
order_cycle:
|
||||
@@ -237,6 +244,7 @@ en_US:
|
||||
reset_password_token: Reset password token
|
||||
expired: has expired, please request a new one
|
||||
back_to_payments_list: "Back to Payments List"
|
||||
maestro_or_solo_cards: "Debit cards"
|
||||
actions:
|
||||
create_and_add_another: "Create and Add Another"
|
||||
create: "Create"
|
||||
@@ -321,6 +329,7 @@ en_US:
|
||||
invoice_settings:
|
||||
edit:
|
||||
title: "Invoice Settings"
|
||||
enable_invoices?: "Enable Invoices?"
|
||||
invoice_style2?: "Use the alternative invoice model that includes total tax breakdown per rate and tax rate info per item (not yet suitable for countries displaying prices excluding tax)"
|
||||
enable_receipt_printing?: "Show options for printing receipts using thermal printers in order dropdown?"
|
||||
stripe_connect_settings:
|
||||
@@ -389,6 +398,7 @@ en_US:
|
||||
calculator: "Calculator"
|
||||
calculator_values: "Calculator Values"
|
||||
search: "Search"
|
||||
name_placeholder: "e.g. packing fee"
|
||||
enterprise_groups:
|
||||
index:
|
||||
new_button: New Enterprise Group
|
||||
@@ -443,6 +453,8 @@ en_US:
|
||||
encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding"
|
||||
unexpected_error: "Product Import encountered an unexpected error when opening the file: %{error_message}"
|
||||
index:
|
||||
notice: "Notice"
|
||||
beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support."
|
||||
select_file: Select a spreadsheet to upload
|
||||
spreadsheet: Spreadsheet
|
||||
choose_import_type: Select import type
|
||||
@@ -647,6 +659,8 @@ en_US:
|
||||
permalink_tip: "This permalink is used to create the url to your shop: %{link}your-shop-name/shop"
|
||||
link_to_front: Link to shop front
|
||||
link_to_front_tip: A direct link to your shopfront on the Open Food Network.
|
||||
ofn_uid: OFN UID
|
||||
ofn_uid_tip: The unique id used to identify the enterprise on Open Food Network.
|
||||
shipping_methods:
|
||||
name: Name
|
||||
applies: Applies?
|
||||
@@ -828,6 +842,7 @@ en_US:
|
||||
add_distributor: 'Add distributor'
|
||||
advanced_settings:
|
||||
title: Advanced Settings
|
||||
choose_product_tip: You can restrict products incoming and outgoing to only %{inventory}'s inventory.
|
||||
preferred_product_selection_from_coordinator_inventory_only_here: Coordinator's Inventory Only
|
||||
preferred_product_selection_from_coordinator_inventory_only_all: All Available Products
|
||||
save_reload: Save and Reload Page
|
||||
@@ -963,6 +978,8 @@ en_US:
|
||||
pause_subscription: Pause Subscription
|
||||
unpause_subscription: Unpause Subscription
|
||||
cancel_subscription: Cancel Subscription
|
||||
filters:
|
||||
query_placeholder: "Search by email..."
|
||||
setup_explanation:
|
||||
just_a_few_more_steps: 'Just a few more steps before you can begin:'
|
||||
enable_subscriptions: "Enable subscriptions for at least one of your shops"
|
||||
@@ -999,6 +1016,8 @@ en_US:
|
||||
charges_not_allowed: Charges are not allowed by this customer
|
||||
no_default_card: Customer has no cards available to charge
|
||||
card_ok: Customer has a card available to charge
|
||||
begins_at_placeholder: "Select a Date"
|
||||
ends_at_placeholder: "Optional"
|
||||
loading_flash:
|
||||
loading: LOADING SUBSCRIPTIONS
|
||||
review:
|
||||
@@ -1012,6 +1031,7 @@ en_US:
|
||||
saved: "SAVED"
|
||||
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
|
||||
stock:
|
||||
insufficient_stock: "Insufficient stock available"
|
||||
out_of_stock: "Out of Stock"
|
||||
orders:
|
||||
number: Number
|
||||
@@ -1020,6 +1040,7 @@ en_US:
|
||||
cancel_failure_msg: "Sorry, cancellation failed!"
|
||||
confirm_pause_msg: "Are you sure you want to pause this subscription?"
|
||||
pause_failure_msg: "Sorry, pausing failed!"
|
||||
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
|
||||
unpause_failure_msg: "Sorry, unpausing failed!"
|
||||
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
|
||||
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
|
||||
@@ -1057,8 +1078,12 @@ en_US:
|
||||
show_on_map: "Show all on the map"
|
||||
shared:
|
||||
menu:
|
||||
cart:
|
||||
cart: "Cart"
|
||||
signed_in:
|
||||
profile: "Profile"
|
||||
mobile_menu:
|
||||
cart: "Cart"
|
||||
joyride:
|
||||
checkout: "Checkout now"
|
||||
already_ordered_products: "Already ordered in this order cycle"
|
||||
@@ -1095,7 +1120,11 @@ en_US:
|
||||
shop:
|
||||
messages:
|
||||
login: "login"
|
||||
signup: "signup"
|
||||
contact: "contact"
|
||||
require_customer_login: "Only approved customers can access this shop."
|
||||
require_login_html: "If you're already an approved customer, %{login} or %{signup} to proceed. Want to start shopping here? Please %{contact} %{enterprise} and ask about joining."
|
||||
require_customer_html: "If you'd like to start shopping here, please %{contact} %{enterprise} to ask about joining."
|
||||
card_could_not_be_updated: Card could not be updated
|
||||
card_could_not_be_saved: card could not be saved
|
||||
spree_gateway_error_flash_for_checkout: "There was a problem with your payment information: %{error}"
|
||||
@@ -1685,6 +1714,7 @@ en_US:
|
||||
introduction:
|
||||
registration_greeting: "Hi there!"
|
||||
registration_intro: "You can now create a profile for your Producer or Hub"
|
||||
registration_checklist: "What do I need?"
|
||||
registration_time: "5-10 minutes"
|
||||
registration_enterprise_address: "Address"
|
||||
registration_contact_details: "Primary contact details"
|
||||
@@ -1939,6 +1969,7 @@ en_US:
|
||||
spree_admin_supplier: Supplier
|
||||
spree_admin_product_category: Product Category
|
||||
spree_admin_variant_unit_name: Variant unit name
|
||||
unit_name: "Unit name"
|
||||
change_package: "Change Package"
|
||||
spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under"
|
||||
spree_admin_eg_pickup_from_school: "eg. 'Pick up at Community Center'"
|
||||
@@ -2174,6 +2205,7 @@ en_US:
|
||||
payment_methods: "Payment Methods"
|
||||
payment_method_fee: "Transaction fee"
|
||||
payment_processing_failed: "Payment could not be processed, please check the details you entered"
|
||||
payment_method_not_supported: "That payment method is unsupported. Please choose another one."
|
||||
payment_updated: "Payment Updated"
|
||||
inventory_settings: "Inventory Settings"
|
||||
tag_rules: "Tag Rules"
|
||||
@@ -2364,8 +2396,18 @@ en_US:
|
||||
severity: Severity
|
||||
description: Description
|
||||
resolve: Resolve
|
||||
tag_rules:
|
||||
shipping_method_tagged_top: "Shipping methods tagged"
|
||||
shipping_method_tagged_bottom: "are:"
|
||||
payment_method_tagged_top: "Payment methods tagged"
|
||||
payment_method_tagged_bottom: "are:"
|
||||
order_cycle_tagged_top: "Order Cycles tagged"
|
||||
order_cycle_tagged_bottom: "are:"
|
||||
inventory_tagged_top: "Inventory variants tagged"
|
||||
inventory_tagged_bottom: "are:"
|
||||
new_tag_rule_dialog:
|
||||
select_rule_type: "Select a rule type:"
|
||||
add_rule: "Add Rule"
|
||||
enterprise_fees:
|
||||
inherit_from_product: "Inherit From Product"
|
||||
orders:
|
||||
@@ -2622,6 +2664,7 @@ en_US:
|
||||
fill_in_customer_info: "Please fill in customer info"
|
||||
new_payment: "New Payment"
|
||||
capture: "Capture"
|
||||
void: "Void"
|
||||
configurations: "Configurations"
|
||||
general_settings: "General Settings"
|
||||
site_name: "Site Name"
|
||||
@@ -2723,7 +2766,16 @@ en_US:
|
||||
no_results: "No results"
|
||||
create: "Create"
|
||||
loading: "Loading"
|
||||
flat_percent: "Flat Percent"
|
||||
per_kg: "Per Kg"
|
||||
amount: "Amount"
|
||||
currency: "Currency"
|
||||
first_item: "First Item Cost"
|
||||
additional_item: "Additional Item Cost"
|
||||
max_items: "Max Items"
|
||||
minimal_amount: "Minimal Amount"
|
||||
normal_amount: "Normal Amount"
|
||||
discount_amount: "Discount Amount"
|
||||
email: Email
|
||||
account_updated: "Account updated!"
|
||||
my_account: "My account"
|
||||
@@ -2733,6 +2785,7 @@ en_US:
|
||||
inventory: Inventory
|
||||
zipcode: Zipcode
|
||||
weight: Weight (per lb)
|
||||
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
|
||||
actions:
|
||||
update: "Update"
|
||||
errors:
|
||||
@@ -2871,6 +2924,7 @@ en_US:
|
||||
error_saving_payment: Error saving payment
|
||||
submitting_payment: Submitting payment...
|
||||
products:
|
||||
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
|
||||
new:
|
||||
title: 'New Product'
|
||||
unit_name_placeholder: 'eg. bunches'
|
||||
|
||||
@@ -1512,7 +1512,7 @@ en_ZA:
|
||||
components_filters_clearfilters: "Clear all filters"
|
||||
groups_title: Groups
|
||||
groups_headline: Groups / regions
|
||||
groups_text: "Every producer is unique. Every business has something different to offer. Our groups are collectives of producers, hubs and distributors who share something in common like location, farmers market or philosophy. This makes your shopping experience easier. So explore our groups and have the curating done for you."
|
||||
groups_text: "OFN groups are collectives of producers, hubs and distributors who share something in common such as location or philosophy. Groups also enable consumers to browse producers that are registered with various industry bodies e.g. organic / biodynamic certification. Specifically in South Africa, groups also enable non-profit organisations to highlight emerging farmers or enterprises that they may be assisting. In this way we can help these producers to enjoy the benefits of the wider OFN network."
|
||||
groups_search: "Search name or keyword"
|
||||
groups_no_groups: "No groups found"
|
||||
groups_about: "About Us"
|
||||
|
||||
@@ -12,7 +12,7 @@ job_type :run_file, "cd :path; :environment_variable=:environment bundle exec sc
|
||||
job_type :enqueue_job, "cd :path; :environment_variable=:environment bundle exec script/enqueue :task :priority :output"
|
||||
|
||||
|
||||
every 1.hour do
|
||||
every 1.day, at: '01:00am' do
|
||||
rake 'ofn:cache:check_products_integrity'
|
||||
end
|
||||
|
||||
|
||||
@@ -54,14 +54,16 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def all_variants_for_shop
|
||||
# We use the in_stock? method here instead of the in_stock scope because we need to
|
||||
# look up the stock as overridden by VariantOverrides, and the scope method is not affected
|
||||
# by them.
|
||||
scoper = OpenFoodNetwork::ScopeVariantToHub.new(@distributor)
|
||||
Spree::Variant.
|
||||
for_distribution(@order_cycle, @distributor).
|
||||
each { |v| scoper.scope(v) }.
|
||||
select(&:in_stock?)
|
||||
@all_variants_for_shop ||= begin
|
||||
# We use the in_stock? method here instead of the in_stock scope
|
||||
# because we need to look up the stock as overridden by
|
||||
# VariantOverrides, and the scope method is not affected by them.
|
||||
scoper = OpenFoodNetwork::ScopeVariantToHub.new(@distributor)
|
||||
Spree::Variant.
|
||||
for_distribution(@order_cycle, @distributor).
|
||||
each { |v| scoper.scope(v) }.
|
||||
select(&:in_stock?)
|
||||
end
|
||||
end
|
||||
|
||||
def variants_for_shop_by_id
|
||||
|
||||
34
spec/features/admin/inventory_spec.rb
Normal file
34
spec/features/admin/inventory_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
require "spec_helper"
|
||||
|
||||
feature "Managing inventory", js: true do
|
||||
include AdminHelper
|
||||
include AuthenticationWorkflow
|
||||
include WebHelper
|
||||
|
||||
it "shows more than 100 products" do
|
||||
supplier = create(:supplier_enterprise, sells: "own")
|
||||
inventory_items = (1..101).map do
|
||||
product = create(:simple_product, supplier: supplier)
|
||||
InventoryItem.create!(
|
||||
enterprise: supplier,
|
||||
variant: product.variants.first,
|
||||
visible: true
|
||||
)
|
||||
end
|
||||
first_variant = inventory_items.first.variant
|
||||
last_variant = inventory_items.last.variant
|
||||
first_variant.product.update_attributes!(name: "A First Product")
|
||||
last_variant.product.update_attributes!(name: "Z Last Product")
|
||||
quick_login_as supplier.users.first
|
||||
visit admin_inventory_path
|
||||
|
||||
expect(page).to have_text first_variant.name
|
||||
expect(page).to have_selector "tr.product", count: 10
|
||||
expect(page).to have_button "Show more"
|
||||
expect(page).to have_button "Show all (91 More)"
|
||||
|
||||
click_button "Show all (91 More)"
|
||||
expect(page).to have_selector "tr.product", count: 101
|
||||
expect(page).to have_text last_variant.name
|
||||
end
|
||||
end
|
||||
@@ -3,11 +3,27 @@ require 'spec_helper'
|
||||
describe "checking out an order with a Stripe Connect payment method", type: :request do
|
||||
include ShopWorkflow
|
||||
include AuthenticationWorkflow
|
||||
include OpenFoodNetwork::ApiHelper
|
||||
|
||||
let!(:order_cycle) { create(:simple_order_cycle) }
|
||||
let!(:enterprise) { create(:distributor_enterprise) }
|
||||
let!(:exchange) { create(:exchange, order_cycle: order_cycle, sender: order_cycle.coordinator, receiver: enterprise, incoming: false, pickup_time: "Monday") }
|
||||
let!(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 0), distributors: [enterprise]) }
|
||||
let!(:exchange) do
|
||||
create(
|
||||
:exchange,
|
||||
order_cycle: order_cycle,
|
||||
sender: order_cycle.coordinator,
|
||||
receiver: enterprise,
|
||||
incoming: false,
|
||||
pickup_time: "Monday"
|
||||
)
|
||||
end
|
||||
let!(:shipping_method) do
|
||||
create(
|
||||
:shipping_method,
|
||||
calculator: Spree::Calculator::FlatRate.new(preferred_amount: 0),
|
||||
distributors: [enterprise]
|
||||
)
|
||||
end
|
||||
let!(:payment_method) { create(:stripe_payment_method, distributors: [enterprise]) }
|
||||
let!(:stripe_account) { create(:stripe_account, enterprise: enterprise) }
|
||||
let!(:line_item) { create(:line_item, price: 12.34) }
|
||||
@@ -17,19 +33,48 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
let(:new_token) { "newtoken123" }
|
||||
let(:card_id) { "card_XyZ456" }
|
||||
let(:customer_id) { "cus_A123" }
|
||||
let(:payments_attributes) do
|
||||
{
|
||||
payment_method_id: payment_method.id,
|
||||
source_attributes: {
|
||||
gateway_payment_profile_id: token,
|
||||
cc_type: "visa",
|
||||
last_digits: "4242",
|
||||
month: 10,
|
||||
year: 2025,
|
||||
first_name: 'Jill',
|
||||
last_name: 'Jeffreys'
|
||||
}
|
||||
}
|
||||
end
|
||||
let(:allowed_address_attributes) do
|
||||
[
|
||||
"firstname",
|
||||
"lastname",
|
||||
"address1",
|
||||
"address2",
|
||||
"phone",
|
||||
"city",
|
||||
"zipcode",
|
||||
"state_id",
|
||||
"country_id"
|
||||
]
|
||||
end
|
||||
let(:params) do
|
||||
{ format: :json, order: {
|
||||
shipping_method_id: shipping_method.id,
|
||||
payments_attributes: [{ payment_method_id: payment_method.id, source_attributes: { gateway_payment_profile_id: token, cc_type: "visa", last_digits: "4242", month: 10, year: 2025, first_name: 'Jill', last_name: 'Jeffreys' } }],
|
||||
bill_address_attributes: address.attributes.slice("firstname", "lastname", "address1", "address2", "phone", "city", "zipcode", "state_id", "country_id"),
|
||||
ship_address_attributes: address.attributes.slice("firstname", "lastname", "address1", "address2", "phone", "city", "zipcode", "state_id", "country_id")
|
||||
} }
|
||||
{
|
||||
format: :json, order: {
|
||||
shipping_method_id: shipping_method.id,
|
||||
payments_attributes: [payments_attributes],
|
||||
bill_address_attributes: address.attributes.slice(*allowed_address_attributes),
|
||||
ship_address_attributes: address.attributes.slice(*allowed_address_attributes)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
order_cycle_distributed_variants = double(:order_cycle_distributed_variants)
|
||||
allow(OrderCycleDistributedVariants).to receive(:new).and_return(order_cycle_distributed_variants)
|
||||
allow(order_cycle_distributed_variants).to receive(:distributes_order_variants?).and_return(true)
|
||||
allow(OrderCycleDistributedVariants).to receive(:new) { order_cycle_distributed_variants }
|
||||
allow(order_cycle_distributed_variants).to receive(:distributes_order_variants?) { true }
|
||||
|
||||
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
|
||||
order.update_attributes(distributor_id: enterprise.id, order_cycle_id: order_cycle.id)
|
||||
@@ -38,9 +83,22 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
end
|
||||
|
||||
context "when a new card is submitted" do
|
||||
let(:store_response_mock) { { status: 200, body: JSON.generate(id: customer_id, default_card: card_id, sources: { data: [{ id: "1" }] }) } }
|
||||
let(:token_response_mock) { { status: 200, body: JSON.generate(id: new_token) } }
|
||||
let(:charge_response_mock) { { status: 200, body: JSON.generate(id: "ch_1234", object: "charge", amount: 2000) } }
|
||||
let(:store_response_mock) do
|
||||
{
|
||||
status: 200,
|
||||
body: JSON.generate(
|
||||
id: customer_id,
|
||||
default_card: card_id,
|
||||
sources: { data: [{ id: "1" }] }
|
||||
)
|
||||
}
|
||||
end
|
||||
let(:token_response_mock) do
|
||||
{ status: 200, body: JSON.generate(id: new_token) }
|
||||
end
|
||||
let(:charge_response_mock) do
|
||||
{ status: 200, body: JSON.generate(id: "ch_1234", object: "charge", amount: 2000) }
|
||||
end
|
||||
|
||||
context "and the user doesn't request that the card is saved for later" do
|
||||
before do
|
||||
@@ -53,10 +111,12 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
context "and the charge request is successful" do
|
||||
it "should process the payment without storing card details" do
|
||||
put update_checkout_path, params
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["path"]).to eq spree.order_path(order)
|
||||
expect(order.payments.completed.count).to be 1
|
||||
|
||||
card = order.payments.completed.first.source
|
||||
|
||||
expect(card.gateway_customer_profile_id).to eq nil
|
||||
expect(card.gateway_payment_profile_id).to eq token
|
||||
expect(card.cc_type).to eq "visa"
|
||||
@@ -67,12 +127,15 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:charge_response_mock) { { status: 402, body: JSON.generate(error: { message: "charge-failure" }) } }
|
||||
let(:charge_response_mock) do
|
||||
{ status: 402, body: JSON.generate(error: { message: "charge-failure" }) }
|
||||
end
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["flash"]["error"]).to eq "charge-failure"
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
@@ -81,7 +144,8 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
|
||||
context "and the customer requests that the card is saved for later" do
|
||||
before do
|
||||
params[:order][:payments_attributes][0][:source_attributes][:save_requested_by_customer] = '1'
|
||||
source_attributes = params[:order][:payments_attributes][0][:source_attributes]
|
||||
source_attributes[:save_requested_by_customer] = '1'
|
||||
|
||||
# Saves the card against the user
|
||||
stub_request(:post, "https://api.stripe.com/v1/customers")
|
||||
@@ -95,16 +159,21 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
|
||||
# Charges the card
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges")
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /#{token}.*#{order.number}/).to_return(charge_response_mock)
|
||||
.with(
|
||||
basic_auth: ["sk_test_12345", ""],
|
||||
body: /#{token}.*#{order.number}/
|
||||
).to_return(charge_response_mock)
|
||||
end
|
||||
|
||||
context "and the store, token and charge requests are successful" do
|
||||
it "should process the payment, and stores the card/customer details" do
|
||||
put update_checkout_path, params
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["path"]).to eq spree.order_path(order)
|
||||
expect(order.payments.completed.count).to be 1
|
||||
|
||||
card = order.payments.completed.first.source
|
||||
|
||||
expect(card.gateway_customer_profile_id).to eq customer_id
|
||||
expect(card.gateway_payment_profile_id).to eq card_id
|
||||
expect(card.cc_type).to eq "visa"
|
||||
@@ -115,37 +184,47 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
end
|
||||
|
||||
context "when the store request returns an error message" do
|
||||
let(:store_response_mock) { { status: 402, body: JSON.generate(error: { message: "store-failure" }) } }
|
||||
let(:store_response_mock) do
|
||||
{ status: 402, body: JSON.generate(error: { message: "store-failure" }) }
|
||||
end
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response["flash"]["error"]).to eq I18n.t(:spree_gateway_error_flash_for_checkout, error: 'store-failure')
|
||||
|
||||
expect(json_response["flash"]["error"])
|
||||
.to eq(I18n.t(:spree_gateway_error_flash_for_checkout, error: 'store-failure'))
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:charge_response_mock) { { status: 402, body: JSON.generate(error: { message: "charge-failure" }) } }
|
||||
let(:charge_response_mock) do
|
||||
{ status: 402, body: JSON.generate(error: { message: "charge-failure" }) }
|
||||
end
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["flash"]["error"]).to eq "charge-failure"
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
|
||||
context "when the token request returns an error message" do
|
||||
let(:token_response_mock) { { status: 402, body: JSON.generate(error: { message: "token-failure" }) } }
|
||||
let(:token_response_mock) do
|
||||
{ status: 402, body: JSON.generate(error: { message: "token-failure" }) }
|
||||
end
|
||||
|
||||
# Note, no requests have been stubbed
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["flash"]["error"]).to eq "token-failure"
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
@@ -169,7 +248,9 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
end
|
||||
|
||||
let(:token_response_mock) { { status: 200, body: JSON.generate(id: new_token) } }
|
||||
let(:charge_response_mock) { { status: 200, body: JSON.generate(id: "ch_1234", object: "charge", amount: 2000) } }
|
||||
let(:charge_response_mock) do
|
||||
{ status: 200, body: JSON.generate(id: "ch_1234", object: "charge", amount: 2000) }
|
||||
end
|
||||
|
||||
before do
|
||||
params[:order][:existing_card_id] = credit_card.id
|
||||
@@ -189,10 +270,12 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
context "and the charge and token requests are accepted" do
|
||||
it "should process the payment, and keep the profile ids and other card details" do
|
||||
put update_checkout_path, params
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["path"]).to eq spree.order_path(order)
|
||||
expect(order.payments.completed.count).to be 1
|
||||
|
||||
card = order.payments.completed.first.source
|
||||
|
||||
expect(card.gateway_customer_profile_id).to eq customer_id
|
||||
expect(card.gateway_payment_profile_id).to eq card_id
|
||||
expect(card.cc_type).to eq "master"
|
||||
@@ -203,24 +286,30 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
|
||||
end
|
||||
|
||||
context "when the charge request returns an error message" do
|
||||
let(:charge_response_mock) { { status: 402, body: JSON.generate(error: { message: "charge-failure" }) } }
|
||||
let(:charge_response_mock) do
|
||||
{ status: 402, body: JSON.generate(error: { message: "charge-failure" }) }
|
||||
end
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["flash"]["error"]).to eq "charge-failure"
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
end
|
||||
|
||||
context "when the token request returns an error message" do
|
||||
let(:token_response_mock) { { status: 402, body: JSON.generate(error: { message: "token-error" }) } }
|
||||
let(:token_response_mock) do
|
||||
{ status: 402, body: JSON.generate(error: { message: "token-error" }) }
|
||||
end
|
||||
|
||||
it "should not process the payment" do
|
||||
put update_checkout_path, params
|
||||
|
||||
expect(response.status).to be 400
|
||||
json_response = JSON.parse(response.body)
|
||||
|
||||
expect(json_response["flash"]["error"]).to eq "token-error"
|
||||
expect(order.payments.completed.count).to be 0
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user