diff --git a/app/services/vine/voucher_validator_service.rb b/app/services/vine/voucher_validator_service.rb index 8311a5fc9f..57af49718d 100644 --- a/app/services/vine/voucher_validator_service.rb +++ b/app/services/vine/voucher_validator_service.rb @@ -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") diff --git a/config/locales/en.yml b/config/locales/en.yml index d3fe23123d..80094f4582 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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: diff --git a/spec/services/vine/voucher_validator_service_spec.rb b/spec/services/vine/voucher_validator_service_spec.rb index 2c263d3f97..68cd1f0a03 100644 --- a/spec/services/vine/voucher_validator_service_spec.rb +++ b/spec/services/vine/voucher_validator_service_spec.rb @@ -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