Skip to content

Commit

Permalink
Ensure completed status
Browse files Browse the repository at this point in the history
Other status shouldn't be processed.
Added more test cases.
  • Loading branch information
thibaudgg committed Sep 17, 2024
1 parent a03790f commit e38a209
Show file tree
Hide file tree
Showing 8 changed files with 887 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ GEM
rexml
drb (2.2.1)
hashdiff (1.1.1)
i18n (1.14.5)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
json (2.7.2)
logger (1.6.1)
Expand Down
3 changes: 0 additions & 3 deletions app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ def verify_signature!

computed_hmac = Base64.strict_encode64(
OpenSSL::HMAC.digest('sha256', secret, @request_body))
# TODO: Remove debug logging
logger.info "Header HMAC: #{signature}"
logger.info "Computed HMAC: #{computed_hmac}"

unless signature && Rack::Utils.secure_compare(computed_hmac, signature)
halt 403, 'Forbidden'
Expand Down
25 changes: 19 additions & 6 deletions lib/webhook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ def initialize(payload)

def handle!
ensure_mapping!
ensure_status_completed!

# submit_member!(member_params)
submit_member!(member_params) if test_env?
member_params
end

Expand All @@ -27,13 +28,20 @@ def ensure_mapping!
return if mapping

store_name = @payload.dig("store", "name")
raise "No mapping found for store: #{store_id} (#{store_name})"
raise "Skipped, no mapping found for store: #{store_id} (#{store_name})"
end

def ensure_status_completed!
status = @payload["status"]
unless status == "completed"
raise "Skipped, order status is not completed: #{status}"
end
end

def submit_member!(params)
http = Net::HTTP.new(api_uri.host, api_uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if ENV["RACK_ENV"] == "test"
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if test_env?

headers = {
"Content-Type" => "application/json",
Expand All @@ -57,6 +65,7 @@ def member_params
city: billing["city"],
zip: billing["postcode"],
country_code: billing["country"],
note: "Commande locali-ge.ch ##{@payload["id"]}",
waiting_basket_size_id: mapping_id_for("basket_sizes"),
waiting_depot_id: mapping_id_for("depots"),
members_basket_complements_attributes: basket_complements
Expand All @@ -79,7 +88,7 @@ def api_token

def api_uri
url = mapping.last["api_endpoint"]
url.gsub!(/\.ch/, ".test") if ENV["RACK_ENV"] == "test"
url.gsub!(/\.ch/, ".test") if test_env?
URI.parse(url)
end

Expand All @@ -90,15 +99,15 @@ def basket_complements
end

def mapping_id_for(type)
mapping.last[type].each { |product_id, id|
mapping.last[type]&.each { |product_id, id|
return id if product_id.in?(product_ids)
}
nil
end

def mapping_ids_for(type)
ids = []
mapping.last[type].each { |product_id, id|
mapping.last[type]&.each { |product_id, id|
ids << id if product_id.in?(product_ids)
}
ids
Expand Down Expand Up @@ -126,4 +135,8 @@ def billing
def store_id
@payload.dig("store", "id")
end

def test_env?
ENV["RACK_ENV"] == "test"
end
end
124 changes: 102 additions & 22 deletions test/app_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ def request(payload, secret: nil)
post "/webhook", payload
end

def test_valid_webhook_request
def test_valid_webhook_request_cocagne
ENV["COCAGNE_API_TOKEN"] = "api-token-cocagne"
payload = File.read('test/fixtures/order_created.json')
payload = File.read('test/fixtures/order_completed_cocagne.json')
stub_request(:any, "https://admin.cocagne.test/api/v1/members")
.to_return(status: 201)

Expand All @@ -39,26 +39,106 @@ def test_valid_webhook_request
assert_equal 204, last_response.status
assert_empty last_response.body

# assert_requested :post, "https://admin.cocagne.test/api/v1/members",
# times: 1,
# headers: {
# "Content-Type" => "application/json",
# "Authorization" => "Token token=api-token-cocagne"
# },
# body: {
# name: "Doe John",
# emails: "[email protected]",
# phones: "079 123 45 67",
# address: "Chemin de la Mairie, 1",
# city: "Troinex",
# zip: "1256",
# country_code: "CH",
# waiting_basket_size_id: 1,
# waiting_depot_id: 22,
# members_basket_complements_attributes: [
# { basket_complement_id:10, quantity:1 }
# ]
# }.to_json
assert_requested :post, "https://admin.cocagne.test/api/v1/members",
times: 1,
headers: {
"Content-Type" => "application/json",
"Authorization" => "Token token=api-token-cocagne"
},
body: {
name: "Doe John",
emails: "[email protected]",
phones: "079 123 45 67",
address: "Chemin de la Mairie, 1",
city: "Troinex",
zip: "1256",
country_code: "CH",
note: "Commande locali-ge.ch #35255",
waiting_basket_size_id: 1,
waiting_depot_id: 7,
members_basket_complements_attributes: [
{ basket_complement_id:10, quantity:1 }
]
}.to_json
end

def test_valid_webhook_request_locali
ENV["LOCALI_API_TOKEN"] = "api-token-locali"
payload = File.read('test/fixtures/order_completed_locali.json')
stub_request(:any, "https://admin.panier-locali.test/api/v1/members")
.to_return(status: 201)

request(payload)

assert_equal 204, last_response.status
assert_empty last_response.body

assert_requested :post, "https://admin.panier-locali.test/api/v1/members",
times: 1,
headers: {
"Content-Type" => "application/json",
"Authorization" => "Token token=api-token-locali"
},
body: {
name: "Doe John",
emails: "[email protected]",
phones: "0791234567",
address: "Chemin de la Mairie 1",
city: "Genève",
zip: "1205",
country_code: "CH",
note: "Commande locali-ge.ch #35717",
waiting_basket_size_id: 1,
waiting_depot_id: 3,
members_basket_complements_attributes: []
}.to_json
end

def test_valid_webhook_request_touviere
ENV["TOUVIERE_API_TOKEN"] = "api-token-touviere"
payload = File.read('test/fixtures/order_completed_touviere.json')
stub_request(:any, "https://admin.touviere.test/api/v1/members")
.to_return(status: 201)

request(payload)

assert_equal 204, last_response.status
assert_empty last_response.body

assert_requested :post, "https://admin.touviere.test/api/v1/members",
times: 1,
headers: {
"Content-Type" => "application/json",
"Authorization" => "Token token=api-token-touviere"
},
body: {
name: "Doe John",
emails: "[email protected]",
phones: "0791234567",
address: "Chemin de la Mairie 1",
city: "Genève",
zip: "1205",
country_code: "CH",
note: "Commande locali-ge.ch #35715",
waiting_basket_size_id: 1,
waiting_depot_id: 3,
members_basket_complements_attributes: [
{ basket_complement_id: 2, quantity: 1 },
{ basket_complement_id: 1, quantity: 1 }
]
}.to_json
end

def test_valid_webhook_request_but_not_completed
ENV["COCAGNE_API_TOKEN"] = "api-token-cocagne"
payload = File.read('test/fixtures/order_processing_cocagne.json')

request(payload)

assert_equal 204, last_response.status
assert_empty last_response.body

assert_not_requested :post, "https://admin.cocagne.test/api/v1/members"
end

def test_unknown_store
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": 35255,
"parent_id": 0,
"status": "postfi-redirected",
"status": "completed",
"currency": "CHF",
"version": "8.7.0",
"prices_include_tax": true,
Expand Down
Loading

0 comments on commit e38a209

Please sign in to comment.