spree_api 5.2.5 → 5.3.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/concerns/spree/api/v2/product_list_includes.rb +10 -21
- data/app/controllers/concerns/spree/api/v2/storefront/order_concern.rb +2 -2
- data/app/controllers/spree/api/v2/base_controller.rb +2 -2
- data/app/controllers/spree/api/v2/data_feeds/google_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/addresses_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/adjustments_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/classifications_controller.rb +2 -2
- data/app/controllers/spree/api/v2/platform/countries_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/data_feeds_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/digital_links_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/digitals_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/gift_cards_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/line_items_controller.rb +4 -4
- data/app/controllers/spree/api/v2/platform/option_types_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/option_values_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/orders_controller.rb +11 -11
- data/app/controllers/spree/api/v2/platform/payment_methods_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/payments_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/products_controller.rb +2 -2
- data/app/controllers/spree/api/v2/platform/promotion_actions_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/promotion_categories_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/promotion_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/promotions_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/roles_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/shipments_controller.rb +6 -6
- data/app/controllers/spree/api/v2/platform/shipping_categories_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/shipping_methods_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/states_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/stock_items_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/stock_locations_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/store_credit_categories_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/store_credit_types_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/store_credits_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/tax_categories_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/tax_rates_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/taxonomies_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/taxons_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/users_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/variants_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/wished_items_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/wishlists_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/zones_controller.rb +1 -1
- data/app/controllers/spree/api/v2/resource_controller.rb +9 -6
- data/app/controllers/spree/api/v2/storefront/account/addresses_controller.rb +5 -5
- data/app/controllers/spree/api/v2/storefront/account/credit_cards_controller.rb +4 -4
- data/app/controllers/spree/api/v2/storefront/account/orders_controller.rb +4 -4
- data/app/controllers/spree/api/v2/storefront/account_controller.rb +3 -3
- data/app/controllers/spree/api/v2/storefront/cart_controller.rb +13 -13
- data/app/controllers/spree/api/v2/storefront/checkout_controller.rb +12 -12
- data/app/controllers/spree/api/v2/storefront/countries_controller.rb +3 -3
- data/app/controllers/spree/api/v2/storefront/order_status_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/policies_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/posts_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/products_controller.rb +5 -8
- data/app/controllers/spree/api/v2/storefront/stores_controller.rb +1 -1
- data/app/controllers/spree/api/v2/storefront/taxons_controller.rb +3 -3
- data/app/controllers/spree/api/v2/storefront/variants_controller.rb +2 -2
- data/app/helpers/spree/api/v2/display_money_helper.rb +30 -10
- data/app/jobs/spree/webhook_delivery_job.rb +16 -0
- data/app/paginators/spree/api/paginate.rb +68 -0
- data/app/serializers/concerns/spree/api/v2/public_metafields_concern.rb +1 -1
- data/app/serializers/concerns/spree/api/v2/resource_serializer_concern.rb +1 -1
- data/app/serializers/spree/api/v2/platform/address_serializer.rb +3 -3
- data/app/serializers/spree/api/v2/platform/adjustment_serializer.rb +5 -5
- data/app/serializers/spree/api/v2/platform/classification_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/country_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/credit_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/customer_return_serializer.rb +4 -4
- data/app/serializers/spree/api/v2/platform/digital_link_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/digital_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/gift_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/inventory_unit_serializer.rb +7 -7
- data/app/serializers/spree/api/v2/platform/line_item_serializer.rb +6 -6
- data/app/serializers/spree/api/v2/platform/option_type_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/option_value_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/order_promotion_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/order_serializer.rb +15 -15
- data/app/serializers/spree/api/v2/platform/payment_capture_event_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/payment_method_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/payment_serializer.rb +7 -7
- data/app/serializers/spree/api/v2/platform/payment_source_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/product_serializer.rb +20 -12
- data/app/serializers/spree/api/v2/platform/promotion_action_line_item_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/promotion_action_serializer.rb +3 -3
- data/app/serializers/spree/api/v2/platform/promotion_category_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/promotion_rule_serializer.rb +4 -4
- data/app/serializers/spree/api/v2/platform/promotion_serializer.rb +4 -4
- data/app/serializers/spree/api/v2/platform/prototype_serializer.rb +3 -3
- data/app/serializers/spree/api/v2/platform/refund_serializer.rb +5 -5
- data/app/serializers/spree/api/v2/platform/reimbursement_serializer.rb +6 -6
- data/app/serializers/spree/api/v2/platform/return_authorization_serializer.rb +4 -4
- data/app/serializers/spree/api/v2/platform/return_item_serializer.rb +4 -4
- data/app/serializers/spree/api/v2/platform/shipment_serializer.rb +8 -8
- data/app/serializers/spree/api/v2/platform/shipping_method_serializer.rb +4 -4
- data/app/serializers/spree/api/v2/platform/shipping_rate_serializer.rb +3 -3
- data/app/serializers/spree/api/v2/platform/state_change_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/state_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/stock_item_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/stock_location_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/stock_transfer_serializer.rb +3 -3
- data/app/serializers/spree/api/v2/platform/store_credit_event_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/store_credit_serializer.rb +5 -5
- data/app/serializers/spree/api/v2/platform/store_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/tax_category_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/tax_rate_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/taxon_serializer.rb +5 -5
- data/app/serializers/spree/api/v2/platform/taxonomy_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/user_serializer.rb +2 -2
- data/app/serializers/spree/api/v2/platform/variant_serializer.rb +19 -11
- data/app/serializers/spree/api/v2/platform/wished_item_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/wishlist_serializer.rb +1 -1
- data/app/serializers/spree/api/v2/platform/zone_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/cart_serializer.rb +9 -9
- data/app/serializers/spree/v2/storefront/credit_card_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/estimated_shipping_rate_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/line_item_serializer.rb +2 -2
- data/app/serializers/spree/v2/storefront/option_type_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/option_value_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/payment_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/payment_source_serializer.rb +2 -2
- data/app/serializers/spree/v2/storefront/post_category_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/post_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/product_serializer.rb +20 -12
- data/app/serializers/spree/v2/storefront/shipment_serializer.rb +4 -4
- data/app/serializers/spree/v2/storefront/shipping_rate_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/store_credit_serializer.rb +3 -3
- data/app/serializers/spree/v2/storefront/store_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/taxon_serializer.rb +6 -6
- data/app/serializers/spree/v2/storefront/user_serializer.rb +2 -2
- data/app/serializers/spree/v2/storefront/variant_serializer.rb +15 -7
- data/app/serializers/spree/v2/storefront/wished_item_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/wishlist_serializer.rb +1 -1
- data/app/services/spree/webhooks/deliver_webhook.rb +83 -0
- data/app/subscribers/spree/webhook_event_subscriber.rb +67 -0
- data/config/routes.rb +0 -2
- data/lib/generators/spree/api/install/install_generator.rb +24 -0
- data/lib/spree/api/configuration.rb +3 -0
- data/lib/spree/api/dependencies.rb +1 -1
- data/lib/spree/api/engine.rb +6 -0
- data/lib/spree/api/testing_support/matchers/webhooks.rb +1 -67
- data/lib/spree/api/testing_support/spree_webhooks.rb +1 -9
- data/lib/spree/api/testing_support/v2/current_order.rb +1 -2
- data/lib/spree/api.rb +3 -0
- data/lib/spree_api.rb +0 -2
- metadata +25 -33
- data/app/controllers/spree/api/v2/platform/webhooks/events_controller.rb +0 -25
- data/app/controllers/spree/api/v2/platform/webhooks/subscribers_controller.rb +0 -25
- data/app/jobs/spree/webhooks/subscribers/make_request_job.rb +0 -17
- data/app/models/concerns/spree/webhooks/has_webhooks.rb +0 -95
- data/app/models/spree/order/webhooks.rb +0 -39
- data/app/models/spree/payment/webhooks.rb +0 -23
- data/app/models/spree/product/webhooks.rb +0 -42
- data/app/models/spree/shipment/webhooks.rb +0 -19
- data/app/models/spree/stock_item/webhooks.rb +0 -40
- data/app/models/spree/stock_movement/webhooks.rb +0 -49
- data/app/models/spree/variant/webhooks.rb +0 -25
- data/app/models/spree/webhooks/base.rb +0 -11
- data/app/models/spree/webhooks/event.rb +0 -20
- data/app/models/spree/webhooks/event_signature.rb +0 -33
- data/app/models/spree/webhooks/subscriber.rb +0 -88
- data/app/serializers/spree/api/v2/platform/webhooks/event_serializer.rb +0 -15
- data/app/serializers/spree/api/v2/platform/webhooks/subscriber_serializer.rb +0 -13
- data/app/services/spree/webhooks/subscribers/handle_request.rb +0 -77
- data/app/services/spree/webhooks/subscribers/make_request.rb +0 -83
- data/app/services/spree/webhooks/subscribers/queue_requests.rb +0 -27
- data/db/migrate/20210902162826_create_spree_webhooks_tables.rb +0 -16
- data/db/migrate/20211025162826_create_spree_webhooks_events.rb +0 -14
- data/db/migrate/20221221122100_add_secret_key_to_spree_webhooks_subscribers.rb +0 -5
- data/db/migrate/20230116204600_backfill_secret_key_for_spree_webhooks_subscribers.rb +0 -5
- data/db/migrate/20230116205000_change_secret_key_to_non_null_column.rb +0 -5
- data/lib/spree/api/testing_support/factories/webhook_event_factory.rb +0 -27
- data/lib/spree/api/testing_support/factories/webhook_subscriber_factory.rb +0 -13
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
# Listens to Spree events and queues webhook deliveries for enabled endpoints.
|
|
5
|
+
#
|
|
6
|
+
# This subscriber listens to all Spree events and for each event, finds
|
|
7
|
+
# all enabled webhook endpoints that are subscribed to that event and queues
|
|
8
|
+
# a delivery job for each one.
|
|
9
|
+
#
|
|
10
|
+
# The event payload is passed through directly without transformation.
|
|
11
|
+
# Events should already be serialized by the EventSerializer.
|
|
12
|
+
#
|
|
13
|
+
# @example
|
|
14
|
+
# # Webhooks are automatically delivered when events are published
|
|
15
|
+
# Spree::Events.publish('order.completed', order: order)
|
|
16
|
+
#
|
|
17
|
+
class WebhookEventSubscriber < Spree::Subscriber
|
|
18
|
+
subscribes_to '*'
|
|
19
|
+
|
|
20
|
+
def handle(event)
|
|
21
|
+
return unless Spree::Api::Config.webhooks_enabled
|
|
22
|
+
return if event.store_id.blank?
|
|
23
|
+
|
|
24
|
+
# Find all active endpoints for this store subscribed to this event
|
|
25
|
+
endpoints = Spree::WebhookEndpoint.active.where(store_id: event.store_id).select { |endpoint| endpoint.subscribed_to?(event.name) }
|
|
26
|
+
|
|
27
|
+
return if endpoints.empty?
|
|
28
|
+
|
|
29
|
+
# Queue delivery for each endpoint
|
|
30
|
+
endpoints.each do |endpoint|
|
|
31
|
+
queue_delivery(endpoint, event)
|
|
32
|
+
end
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
Rails.logger.error "[Spree Webhooks] Error processing event: #{e.message}"
|
|
35
|
+
Rails.error.report(e)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def queue_delivery(endpoint, event)
|
|
41
|
+
# Build base payload (without delivery ID)
|
|
42
|
+
payload = build_payload(event)
|
|
43
|
+
|
|
44
|
+
# Create delivery record
|
|
45
|
+
delivery = endpoint.webhook_deliveries.create!(
|
|
46
|
+
event_name: event.name,
|
|
47
|
+
payload: payload
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Queue the delivery job
|
|
51
|
+
Spree::WebhookDeliveryJob.perform_later(delivery.id, endpoint.secret_key)
|
|
52
|
+
rescue StandardError => e
|
|
53
|
+
Rails.logger.error "[Spree Webhooks] Error queuing delivery for endpoint #{endpoint.id}: #{e.message}"
|
|
54
|
+
Rails.error.report(e)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_payload(event)
|
|
58
|
+
{
|
|
59
|
+
id: event.id,
|
|
60
|
+
name: event.name,
|
|
61
|
+
created_at: event.created_at.iso8601,
|
|
62
|
+
data: event.payload,
|
|
63
|
+
metadata: event.metadata
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Api
|
|
5
|
+
module Generators
|
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
|
7
|
+
class_option :migrate, type: :boolean, default: true
|
|
8
|
+
|
|
9
|
+
def add_migrations
|
|
10
|
+
run 'bundle exec rake railties:install:migrations FROM=spree_api'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run_migrations
|
|
14
|
+
run_migrations = options[:migrate] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
|
|
15
|
+
if run_migrations
|
|
16
|
+
run 'bin/rails db:migrate'
|
|
17
|
+
else
|
|
18
|
+
puts 'Skipping rails db:migrate, don\'t forget to run it!'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -8,6 +8,9 @@ module Spree
|
|
|
8
8
|
preference :api_v2_collection_cache_namespace, :string, default: 'api_v2_collection_cache'
|
|
9
9
|
preference :api_v2_content_type, :string, default: 'application/vnd.api+json'
|
|
10
10
|
preference :api_v2_per_page_limit, :integer, default: 500
|
|
11
|
+
|
|
12
|
+
preference :webhooks_enabled, :boolean, default: true
|
|
13
|
+
preference :webhooks_verify_ssl, :boolean, default: !Rails.env.development?
|
|
11
14
|
end
|
|
12
15
|
end
|
|
13
16
|
end
|
|
@@ -101,7 +101,7 @@ module Spree
|
|
|
101
101
|
storefront_posts_sorter: -> { Spree::Dependencies.posts_sorter },
|
|
102
102
|
|
|
103
103
|
# paginators
|
|
104
|
-
storefront_collection_paginator:
|
|
104
|
+
storefront_collection_paginator: 'Spree::Api::Paginate',
|
|
105
105
|
|
|
106
106
|
# finders
|
|
107
107
|
storefront_address_finder: -> { Spree::Dependencies.address_finder },
|
data/lib/spree/api/engine.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'rails/engine'
|
|
2
|
+
require 'pagy'
|
|
2
3
|
|
|
3
4
|
require_relative 'dependencies'
|
|
4
5
|
require_relative 'configuration'
|
|
@@ -18,6 +19,11 @@ module Spree
|
|
|
18
19
|
Migrations.new(config, engine_name).check unless Rails.env.test?
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
# Add API event subscribers
|
|
23
|
+
config.after_initialize do
|
|
24
|
+
Spree.subscribers << Spree::WebhookEventSubscriber
|
|
25
|
+
end
|
|
26
|
+
|
|
21
27
|
def self.root
|
|
22
28
|
@root ||= Pathname.new(File.expand_path('../../..', __dir__))
|
|
23
29
|
end
|
|
@@ -1,67 +1 @@
|
|
|
1
|
-
#
|
|
2
|
-
# `Spree::Webhooks::Subscribers::QueueRequests.call` method
|
|
3
|
-
# call with the given `event` and `webhook_payload_body` arguments just once.
|
|
4
|
-
#
|
|
5
|
-
# @example
|
|
6
|
-
# expect { order.complete }.to emit_webhook_event('order.paid')
|
|
7
|
-
# expect do
|
|
8
|
-
# order.start_processing
|
|
9
|
-
# order.complete
|
|
10
|
-
# end.to emit_webhook_event('order.paid')
|
|
11
|
-
#
|
|
12
|
-
# It can also be negated, resulting in the expectation
|
|
13
|
-
# waiting to not receive a `call` method call with the
|
|
14
|
-
# given `event` and `webhook_payload_body` (`once` isn't taken into consideration).
|
|
15
|
-
#
|
|
16
|
-
# @example
|
|
17
|
-
# expect { order.complete }.not_to emit_webhook_event('order.paid')
|
|
18
|
-
# expect do
|
|
19
|
-
# order.start_processing
|
|
20
|
-
# order.complete
|
|
21
|
-
# end.not_to emit_webhook_event('order.paid')
|
|
22
|
-
#
|
|
23
|
-
# == Notes
|
|
24
|
-
#
|
|
25
|
-
# The matcher relies on a `webhook_payload_body` method previously defined which
|
|
26
|
-
# isn't added to the matcher definition, because it acts in a different
|
|
27
|
-
# way depending on what's the resource being tested.
|
|
28
|
-
#
|
|
29
|
-
RSpec::Matchers.define :emit_webhook_event do |event_to_emit, record = nil|
|
|
30
|
-
match do |block|
|
|
31
|
-
queue_requests = instance_double(Spree::Webhooks::Subscribers::QueueRequests)
|
|
32
|
-
|
|
33
|
-
allow(Spree::Webhooks::Subscribers::QueueRequests).to receive(:new).and_return(queue_requests)
|
|
34
|
-
allow(queue_requests).to receive(:call).with(any_args)
|
|
35
|
-
|
|
36
|
-
with_webhooks_enabled { Timecop.freeze { block.call } }
|
|
37
|
-
|
|
38
|
-
expect(queue_requests).to(
|
|
39
|
-
have_received(:call).with(event_name: event_to_emit, webhook_payload_body: webhook_payload_body.to_json, record: record).once
|
|
40
|
-
)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def block_definition(obj_method)
|
|
44
|
-
# positive look-behinds must have a fixed length, using a straightforward match instead
|
|
45
|
-
obj_method.source.squish[/(expect *({|do) *)(.*?)( *(}|end).(not_)*to)/, 3]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
failure_message do |obj_method|
|
|
49
|
-
block_def = block_definition(obj_method)
|
|
50
|
-
"Expected that executing `#{block_def}` emits the `#{event_to_emit}` Webhook event.\n" \
|
|
51
|
-
"Check that `#{block_def}` does implement `queue_webhooks_requests!` for " \
|
|
52
|
-
"`#{event_to_emit}` with the following webhook_payload_body: \n\n#{webhook_payload_body}."
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
failure_message_when_negated do |obj_method|
|
|
56
|
-
"Expected that executing `#{block_definition(obj_method)}` does not " \
|
|
57
|
-
"emit the `#{event_to_emit}` Webhook event with the following webhook_payload_body: #{webhook_payload_body}."
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
supports_block_expectations
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def with_webhooks_enabled
|
|
64
|
-
Spree::Webhooks.disabled = false
|
|
65
|
-
yield
|
|
66
|
-
Spree::Webhooks.disabled = true
|
|
67
|
-
end
|
|
1
|
+
# dummy file for compatibility with legacy webhooks
|
data/lib/spree/api.rb
CHANGED
data/lib/spree_api.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.3.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Bigg
|
|
@@ -95,20 +95,34 @@ dependencies:
|
|
|
95
95
|
- - "~>"
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
97
|
version: '2.1'
|
|
98
|
+
- !ruby/object:Gem::Dependency
|
|
99
|
+
name: pagy
|
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - "~>"
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '43.0'
|
|
105
|
+
type: :runtime
|
|
106
|
+
prerelease: false
|
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - "~>"
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
version: '43.0'
|
|
98
112
|
- !ruby/object:Gem::Dependency
|
|
99
113
|
name: spree_core
|
|
100
114
|
requirement: !ruby/object:Gem::Requirement
|
|
101
115
|
requirements:
|
|
102
116
|
- - '='
|
|
103
117
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: 5.
|
|
118
|
+
version: 5.3.0.rc1
|
|
105
119
|
type: :runtime
|
|
106
120
|
prerelease: false
|
|
107
121
|
version_requirements: !ruby/object:Gem::Requirement
|
|
108
122
|
requirements:
|
|
109
123
|
- - '='
|
|
110
124
|
- !ruby/object:Gem::Version
|
|
111
|
-
version: 5.
|
|
125
|
+
version: 5.3.0.rc1
|
|
112
126
|
description: Spree's API
|
|
113
127
|
email:
|
|
114
128
|
- hello@spreecommerce.org
|
|
@@ -165,8 +179,6 @@ files:
|
|
|
165
179
|
- app/controllers/spree/api/v2/platform/taxons_controller.rb
|
|
166
180
|
- app/controllers/spree/api/v2/platform/users_controller.rb
|
|
167
181
|
- app/controllers/spree/api/v2/platform/variants_controller.rb
|
|
168
|
-
- app/controllers/spree/api/v2/platform/webhooks/events_controller.rb
|
|
169
|
-
- app/controllers/spree/api/v2/platform/webhooks/subscribers_controller.rb
|
|
170
182
|
- app/controllers/spree/api/v2/platform/wished_items_controller.rb
|
|
171
183
|
- app/controllers/spree/api/v2/platform/wishlists_controller.rb
|
|
172
184
|
- app/controllers/spree/api/v2/platform/zones_controller.rb
|
|
@@ -192,24 +204,13 @@ files:
|
|
|
192
204
|
- app/helpers/spree/api/v2/display_money_helper.rb
|
|
193
205
|
- app/helpers/spree/api/v2/store_media_serializer_images_concern.rb
|
|
194
206
|
- app/jobs/spree/products/queue_status_changed_webhook_job.rb
|
|
195
|
-
- app/jobs/spree/
|
|
207
|
+
- app/jobs/spree/webhook_delivery_job.rb
|
|
196
208
|
- app/models/concerns/spree/user_api_authentication.rb
|
|
197
209
|
- app/models/concerns/spree/user_api_methods.rb
|
|
198
|
-
- app/models/concerns/spree/webhooks/has_webhooks.rb
|
|
199
210
|
- app/models/spree/oauth_access_grant.rb
|
|
200
211
|
- app/models/spree/oauth_access_token.rb
|
|
201
212
|
- app/models/spree/oauth_application.rb
|
|
202
|
-
- app/
|
|
203
|
-
- app/models/spree/payment/webhooks.rb
|
|
204
|
-
- app/models/spree/product/webhooks.rb
|
|
205
|
-
- app/models/spree/shipment/webhooks.rb
|
|
206
|
-
- app/models/spree/stock_item/webhooks.rb
|
|
207
|
-
- app/models/spree/stock_movement/webhooks.rb
|
|
208
|
-
- app/models/spree/variant/webhooks.rb
|
|
209
|
-
- app/models/spree/webhooks/base.rb
|
|
210
|
-
- app/models/spree/webhooks/event.rb
|
|
211
|
-
- app/models/spree/webhooks/event_signature.rb
|
|
212
|
-
- app/models/spree/webhooks/subscriber.rb
|
|
213
|
+
- app/paginators/spree/api/paginate.rb
|
|
213
214
|
- app/presenters/spree/api/products/filters_presenter.rb
|
|
214
215
|
- app/serializers/concerns/spree/api/v2/image_transformation_concern.rb
|
|
215
216
|
- app/serializers/concerns/spree/api/v2/public_metafields_concern.rb
|
|
@@ -284,8 +285,6 @@ files:
|
|
|
284
285
|
- app/serializers/spree/api/v2/platform/taxonomy_serializer.rb
|
|
285
286
|
- app/serializers/spree/api/v2/platform/user_serializer.rb
|
|
286
287
|
- app/serializers/spree/api/v2/platform/variant_serializer.rb
|
|
287
|
-
- app/serializers/spree/api/v2/platform/webhooks/event_serializer.rb
|
|
288
|
-
- app/serializers/spree/api/v2/platform/webhooks/subscriber_serializer.rb
|
|
289
288
|
- app/serializers/spree/api/v2/platform/wished_item_serializer.rb
|
|
290
289
|
- app/serializers/spree/api/v2/platform/wishlist_serializer.rb
|
|
291
290
|
- app/serializers/spree/api/v2/platform/zone_member_serializer.rb
|
|
@@ -332,9 +331,8 @@ files:
|
|
|
332
331
|
- app/serializers/spree/v2/storefront/wished_item_serializer.rb
|
|
333
332
|
- app/serializers/spree/v2/storefront/wishlist_serializer.rb
|
|
334
333
|
- app/services/spree/products/queue_status_changed_webhook.rb
|
|
335
|
-
- app/services/spree/webhooks/
|
|
336
|
-
- app/
|
|
337
|
-
- app/services/spree/webhooks/subscribers/queue_requests.rb
|
|
334
|
+
- app/services/spree/webhooks/deliver_webhook.rb
|
|
335
|
+
- app/subscribers/spree/webhook_event_subscriber.rb
|
|
338
336
|
- config/brakeman.ignore
|
|
339
337
|
- config/i18n-tasks.yml
|
|
340
338
|
- config/initializers/doorkeeper.rb
|
|
@@ -349,20 +347,14 @@ files:
|
|
|
349
347
|
- db/migrate/20131017162334_add_index_to_user_spree_api_key.rb
|
|
350
348
|
- db/migrate/20180320110726_create_doorkeeper_tables.rb
|
|
351
349
|
- db/migrate/20210727102516_change_integer_id_columns_type.rb
|
|
352
|
-
- db/migrate/20210902162826_create_spree_webhooks_tables.rb
|
|
353
350
|
- db/migrate/20210919183228_enable_polymorphic_resource_owner.rb
|
|
354
|
-
-
|
|
355
|
-
- db/migrate/20221221122100_add_secret_key_to_spree_webhooks_subscribers.rb
|
|
356
|
-
- db/migrate/20230116204600_backfill_secret_key_for_spree_webhooks_subscribers.rb
|
|
357
|
-
- db/migrate/20230116205000_change_secret_key_to_non_null_column.rb
|
|
351
|
+
- lib/generators/spree/api/install/install_generator.rb
|
|
358
352
|
- lib/spree/api.rb
|
|
359
353
|
- lib/spree/api/configuration.rb
|
|
360
354
|
- lib/spree/api/dependencies.rb
|
|
361
355
|
- lib/spree/api/engine.rb
|
|
362
356
|
- lib/spree/api/testing_support/factories.rb
|
|
363
357
|
- lib/spree/api/testing_support/factories/oauth_application_factory.rb
|
|
364
|
-
- lib/spree/api/testing_support/factories/webhook_event_factory.rb
|
|
365
|
-
- lib/spree/api/testing_support/factories/webhook_subscriber_factory.rb
|
|
366
358
|
- lib/spree/api/testing_support/matchers/webhooks.rb
|
|
367
359
|
- lib/spree/api/testing_support/serializers.rb
|
|
368
360
|
- lib/spree/api/testing_support/spree_webhooks.rb
|
|
@@ -377,9 +369,9 @@ licenses:
|
|
|
377
369
|
- BSD-3-Clause
|
|
378
370
|
metadata:
|
|
379
371
|
bug_tracker_uri: https://github.com/spree/spree/issues
|
|
380
|
-
changelog_uri: https://github.com/spree/spree/releases/tag/v5.
|
|
372
|
+
changelog_uri: https://github.com/spree/spree/releases/tag/v5.3.0.rc1
|
|
381
373
|
documentation_uri: https://docs.spreecommerce.org/
|
|
382
|
-
source_code_uri: https://github.com/spree/spree/tree/v5.
|
|
374
|
+
source_code_uri: https://github.com/spree/spree/tree/v5.3.0.rc1
|
|
383
375
|
rdoc_options: []
|
|
384
376
|
require_paths:
|
|
385
377
|
- lib
|
|
@@ -387,7 +379,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
387
379
|
requirements:
|
|
388
380
|
- - ">="
|
|
389
381
|
- !ruby/object:Gem::Version
|
|
390
|
-
version: '3.
|
|
382
|
+
version: '3.2'
|
|
391
383
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
392
384
|
requirements:
|
|
393
385
|
- - ">="
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Api
|
|
3
|
-
module V2
|
|
4
|
-
module Platform
|
|
5
|
-
module Webhooks
|
|
6
|
-
class EventsController < ResourceController
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
def model_class
|
|
10
|
-
Spree::Webhooks::Event
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def scope_includes
|
|
14
|
-
%i[subscriber]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def resource_serializer
|
|
18
|
-
Spree::Api::Dependencies.platform_webhooks_event_serializer.constantize
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Api
|
|
3
|
-
module V2
|
|
4
|
-
module Platform
|
|
5
|
-
module Webhooks
|
|
6
|
-
class SubscribersController < ResourceController
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
def model_class
|
|
10
|
-
Spree::Webhooks::Subscriber
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def spree_permitted_attributes
|
|
14
|
-
super + [{ subscriptions: [] }]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def resource_serializer
|
|
18
|
-
Spree::Api::Dependencies.platform_webhooks_subscriber_serializer.constantize
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Webhooks
|
|
3
|
-
module Subscribers
|
|
4
|
-
class MakeRequestJob < Spree::BaseJob
|
|
5
|
-
queue_as :spree_webhooks
|
|
6
|
-
|
|
7
|
-
def perform(webhook_payload_body, event_name, subscriber)
|
|
8
|
-
Spree::Webhooks::Subscribers::HandleRequest.new(
|
|
9
|
-
event_name: event_name,
|
|
10
|
-
subscriber: subscriber,
|
|
11
|
-
webhook_payload_body: webhook_payload_body
|
|
12
|
-
).call
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
module Webhooks
|
|
3
|
-
module HasWebhooks
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
|
|
6
|
-
included do
|
|
7
|
-
after_create_commit(proc { queue_webhooks_requests!(inferred_event_name(:create)) })
|
|
8
|
-
after_destroy_commit(proc { queue_webhooks_requests!(inferred_event_name(:delete)) })
|
|
9
|
-
after_update_commit(proc { queue_webhooks_requests!(inferred_event_name(:update)) })
|
|
10
|
-
|
|
11
|
-
def queue_webhooks_requests!(event_name)
|
|
12
|
-
return if disable_spree_webhooks?
|
|
13
|
-
return if no_webhooks_subscribers?(event_name)
|
|
14
|
-
return if update_event?(event_name) && updating_only_ignored_attributes?
|
|
15
|
-
return if webhook_payload_body.blank?
|
|
16
|
-
|
|
17
|
-
Spree::Webhooks::Subscribers::QueueRequests.call(
|
|
18
|
-
record: self,
|
|
19
|
-
event_name: event_name,
|
|
20
|
-
webhook_payload_body: webhook_payload_body,
|
|
21
|
-
**webhooks_request_options
|
|
22
|
-
)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def self.default_webhook_events
|
|
26
|
-
model_name = name.demodulize.tableize.singularize
|
|
27
|
-
%W[#{model_name}.create #{model_name}.delete #{model_name}.update]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def self.supported_webhook_events
|
|
31
|
-
events = default_webhook_events
|
|
32
|
-
events += custom_webhook_events if respond_to?(:custom_webhook_events)
|
|
33
|
-
events
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
private
|
|
38
|
-
|
|
39
|
-
def webhook_payload_body
|
|
40
|
-
resource_serializer.new(self, include: included_relationships).serializable_hash.to_json
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def inferred_event_name(operation)
|
|
44
|
-
"#{self.class.name.demodulize.tableize.singularize}.#{operation}"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def included_relationships
|
|
48
|
-
if self.class.respond_to?(:webhook_included_relationships)
|
|
49
|
-
self.class.webhook_included_relationships
|
|
50
|
-
elsif resource_serializer.relationships_to_serialize
|
|
51
|
-
resource_serializer.relationships_to_serialize.keys
|
|
52
|
-
else
|
|
53
|
-
[]
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def resource_serializer
|
|
58
|
-
@resource_serializer ||=
|
|
59
|
-
begin
|
|
60
|
-
demodulized_class_name = self.class.to_s.demodulize
|
|
61
|
-
"Spree::Api::V2::Platform::#{demodulized_class_name}Serializer".constantize
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def updating_only_ignored_attributes?
|
|
66
|
-
(saved_changes.keys - ignored_attributes).empty?
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def ignored_attributes
|
|
70
|
-
timestamps = %w[created_at updated_at deleted_at]
|
|
71
|
-
return timestamps unless self.class.respond_to?(:ignored_attributes_for_update_webhook_event)
|
|
72
|
-
|
|
73
|
-
timestamps + self.class.ignored_attributes_for_update_webhook_event
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def update_event?(event_name)
|
|
77
|
-
event_name.end_with?('.update')
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def disable_spree_webhooks?
|
|
81
|
-
Spree::Webhooks.disabled?
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def no_webhooks_subscribers?(event_name)
|
|
85
|
-
Spree::Current.webhooks_subscribers.none? do |subscriber|
|
|
86
|
-
subscriber.supports_event?(event_name)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def webhooks_request_options
|
|
91
|
-
{}
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class Order < Spree.base_class
|
|
3
|
-
module Webhooks
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
include Spree::Webhooks::HasWebhooks
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
after_update_commit :queue_webhooks_requests_for_order_resumed!
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
class_methods do
|
|
12
|
-
def custom_webhook_events
|
|
13
|
-
%w[order.canceled order.placed order.resumed order.shipped]
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def send_order_canceled_webhook
|
|
18
|
-
queue_webhooks_requests!('order.canceled')
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def send_order_placed_webhook
|
|
22
|
-
queue_webhooks_requests!('order.placed')
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def send_order_resumed_webhook
|
|
26
|
-
queue_webhooks_requests!('order.resumed')
|
|
27
|
-
self.state_machine_resumed = false # to not fire the same webhook twice
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def queue_webhooks_requests_for_order_resumed!
|
|
31
|
-
return if state_machine_resumed?
|
|
32
|
-
return unless state_previously_changed?
|
|
33
|
-
return unless state_previous_change&.last == 'resumed'
|
|
34
|
-
|
|
35
|
-
send_order_resumed_webhook
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class Payment < Spree.base_class
|
|
3
|
-
module Webhooks
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
include Spree::Webhooks::HasWebhooks
|
|
6
|
-
|
|
7
|
-
class_methods do
|
|
8
|
-
def custom_webhook_events
|
|
9
|
-
%w[payment.paid payment.voided]
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def send_payment_voided_webhook
|
|
14
|
-
queue_webhooks_requests!('payment.voided')
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def send_payment_completed_webhook
|
|
18
|
-
queue_webhooks_requests!('payment.paid')
|
|
19
|
-
order.queue_webhooks_requests!('order.paid') if order.paid?
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Spree
|
|
2
|
-
class Product < Spree.base_class
|
|
3
|
-
module Webhooks
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
include Spree::Webhooks::HasWebhooks
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
after_update_commit :queue_webhooks_requests_for_product_discontinued!
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
class_methods do
|
|
12
|
-
def custom_webhook_events
|
|
13
|
-
%w[product.back_in_stock product.backorderable product.discontinued
|
|
14
|
-
product.out_of_stock product.activated product.archived product.drafted]
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def ignored_attributes_for_update_webhook_event
|
|
18
|
-
%w[status]
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def send_product_activated_webhook
|
|
23
|
-
queue_webhooks_requests!('product.activated')
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def send_product_archived_webhook
|
|
27
|
-
queue_webhooks_requests!('product.archived')
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def send_product_drafted_webhook
|
|
31
|
-
queue_webhooks_requests!('product.drafted')
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def queue_webhooks_requests_for_product_discontinued!
|
|
35
|
-
return unless discontinue_on_previously_changed?
|
|
36
|
-
return if (change = discontinue_on_previous_change).blank? || change.last.blank?
|
|
37
|
-
|
|
38
|
-
queue_webhooks_requests!('product.discontinued')
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|