Recognise certain voucher errors

I considered using the vine error message as the translation key (ie I18n.t(vine_voucher_validator_service.errors.#{message.parameterize.underscore}), but thought it might be more predictable to have keys explicitly defined and whitelisted like this.

These error message are still squashed by the controller, we'll deal with that next.
This commit is contained in:
David Cook
2025-09-09 15:55:23 +10:00
parent 06bfd07fec
commit 419f4490d6
3 changed files with 48 additions and 3 deletions

View File

@@ -2,6 +2,11 @@
module Vine
class VoucherValidatorService
VINE_ERRORS = {
# https://github.com/openfoodfoundation/vine/blob/main/app/Enums/ApiResponse.php
"This voucher has expired." => :expired,
}.freeze
attr_reader :voucher_code, :errors
def initialize(voucher_code:, enterprise:)
@@ -43,7 +48,9 @@ module Vine
def handle_errors(response)
if response[:status] == 400
errors[:invalid_voucher] = I18n.t("vine_voucher_validator_service.errors.invalid_voucher")
message = response[:body] && JSON.parse(response[:body]).dig("meta", "message")
key = VINE_ERRORS.fetch(message, :invalid_voucher)
errors[:invalid_voucher] = I18n.t("vine_voucher_validator_service.errors.#{key}")
elsif response[:status] == 404
errors[:not_found_voucher] =
I18n.t("vine_voucher_validator_service.errors.not_found_voucher")

View File

@@ -587,6 +587,7 @@ en:
errors:
vine_api: "There was an error communicating with the API, please try again later."
invalid_voucher: "The voucher is not valid"
expired: "The voucher has expired"
not_found_voucher: "Sorry, we couldn't find that voucher, please check the code."
vine_voucher_redeemer_service:
errors:

View File

@@ -270,11 +270,12 @@ RSpec.describe Vine::VoucherValidatorService, feature: :connected_apps do
enterprise: distributor, data: { api_key: "1234568", secret: "my_secret" }
)
}
# Faraday returns un-parsed json
let(:data) {
{
meta: { responseCode: 400, limit: 50, offset: 0, message: "Invalid merchant team." },
data: []
}.deep_stringify_keys
}.to_json
}
before do
@@ -285,7 +286,7 @@ RSpec.describe Vine::VoucherValidatorService, feature: :connected_apps do
expect_validate_to_be_nil
end
it "adds an error message" do
it "adds a general error message" do
validate_voucher_service.validate
expect(validate_voucher_service.errors).to include(
@@ -293,6 +294,23 @@ RSpec.describe Vine::VoucherValidatorService, feature: :connected_apps do
)
end
context "it is expired" do
let(:data) {
{
meta: { responseCode: 400, limit: 50, offset: 0, message: "This voucher has expired." },
data: []
}.to_json
}
it "adds a specific error message" do
validate_voucher_service.validate
expect(validate_voucher_service.errors).to include(
{ invalid_voucher: "The voucher has expired" }
)
end
end
it "doesn't creates a new VINE voucher" do
expect_voucher_count_not_to_change
end
@@ -420,6 +438,25 @@ RSpec.describe Vine::VoucherValidatorService, feature: :connected_apps do
}.not_to change { voucher.reload.amount }
end
end
context "it is expired" do
let(:data) {
{
meta: { responseCode: 400, limit: 50, offset: 0, message: "This voucher has expired." },
data: []
}.to_json
}
it "adds a specific error message" do
mock_api_exception(type: Faraday::BadRequestError, status: 400, body: data)
validate_voucher_service.validate
expect(validate_voucher_service.errors).to include(
{ invalid_voucher: "The voucher has expired" }
)
end
end
end
end