Refactor Vine related services

Move them under Vine module to keep the code nicely organised
This commit is contained in:
Gaetan Craig-Riou
2024-10-29 10:45:05 +11:00
committed by Rachel Arnould
parent 9f3da1af4f
commit 0569b30e0d
24 changed files with 317 additions and 308 deletions

View File

@@ -44,9 +44,9 @@ module Admin
create_connected_app
jwt_service = VineJwtService.new(secret: connected_app_params[:vine_secret])
vine_api = VineApiService.new(api_key: connected_app_params[:vine_api_key],
jwt_generator: jwt_service)
jwt_service = Vine::JwtService.new(secret: connected_app_params[:vine_secret])
vine_api = Vine::ApiService.new(api_key: connected_app_params[:vine_api_key],
jwt_generator: jwt_service)
if !@app.connect(api_key: connected_app_params[:vine_api_key],
secret: connected_app_params[:vine_secret], vine_api:)

View File

@@ -79,8 +79,8 @@ class CheckoutController < BaseController
return true if redirect_to_payment_gateway
# Redeem VINE voucher
vine_voucher_redeemer = VineVoucherRedeemerService.new(order: @order)
if vine_voucher_redeemer.call == false
vine_voucher_redeemer = Vine::VoucherRedeemerService.new(order: @order)
if vine_voucher_redeemer.redeem == false
# rubocop:disable Rails/DeprecatedActiveModelErrorsMethods
flash[:error] = if vine_voucher_redeemer.errors.keys.include?(:redeeming_failed)
vine_voucher_redeemer.errors[:redeeming_failed]

View File

@@ -191,8 +191,8 @@ module Spree
end
def redeem_vine_voucher
vine_voucher_redeemer = VineVoucherRedeemerService.new(order: @order)
if vine_voucher_redeemer.call == false
vine_voucher_redeemer = Vine::VoucherRedeemerService.new(order: @order)
if vine_voucher_redeemer.redeem == false
# rubocop:disable Rails/DeprecatedActiveModelErrorsMethods
flash[:error] = if vine_voucher_redeemer.errors.keys.include?(:redeeming_failed)
vine_voucher_redeemer.errors[:redeeming_failed]

View File

@@ -87,7 +87,7 @@ class VoucherAdjustmentsController < BaseController
end
def vine_voucher
vine_voucher_validator = VineVoucherValidatorService.new(
vine_voucher_validator = Vine::VoucherValidatorService.new(
voucher_code: voucher_params[:voucher_code], enterprise: @order.distributor
)
voucher = vine_voucher_validator.validate

View File

@@ -0,0 +1,77 @@
# frozen_string_literal: true
require "faraday"
module Vine
class ApiService
attr_reader :api_key, :jwt_generator
def initialize(api_key:, jwt_generator:)
@vine_api_url = ENV.fetch("VINE_API_URL")
@api_key = api_key
@jwt_generator = jwt_generator
end
def my_team
my_team_url = "#{@vine_api_url}/my-team"
response = connection.get(my_team_url)
log_error("Vine::ApiService#my_team", response)
response
end
def voucher_validation(voucher_short_code)
voucher_validation_url = "#{@vine_api_url}/voucher-validation"
response = connection.post(
voucher_validation_url,
{ type: "voucher_code", value: voucher_short_code },
'Content-Type': "application/json"
)
log_error("Vine::ApiService#voucher_validation", response)
response
end
def voucher_redemptions(voucher_id, voucher_set_id, amount)
voucher_redemptions_url = "#{@vine_api_url}/voucher-redemptions"
response = connection.post(
voucher_redemptions_url,
{ voucher_id:, voucher_set_id:, amount: amount.to_i },
'Content-Type': "application/json"
)
log_error("Vine::ApiService#voucher_redemptions", response)
response
end
private
def connection
jwt = jwt_generator.generate_token
Faraday.new(
request: { timeout: 30 },
headers: {
'X-Authorization': "JWT #{jwt}",
Accept: "application/json"
}
) do |f|
f.request :json
f.response :json
f.request :authorization, 'Bearer', api_key
end
end
def log_error(prefix, response)
return if response.success?
Rails.logger.error "#{prefix} -- response_status: #{response.status}"
Rails.logger.error "#{prefix} -- response: #{response.body}"
end
end
end

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
module Vine
class JwtService
ALGORITHM = "HS256"
ISSUER = "openfoodnetwork"
def initialize(secret: )
@secret = secret
end
def generate_token
generation_time = Time.zone.now
payload = {
iss: ISSUER,
iat: generation_time.to_i,
exp: (generation_time + 1.minute).to_i,
}
JWT.encode(payload, @secret, ALGORITHM)
end
end
end

View File

@@ -0,0 +1,66 @@
# frozen_string_literal: true
module Vine
class VoucherRedeemerService
attr_reader :order, :errors
def initialize(order: )
@order = order
@errors = {}
end
def redeem
# Do nothing if we don't have a vine voucher added to the order
voucher_adjustment = order.voucher_adjustments.first
@voucher = voucher_adjustment&.originator
return true if voucher_adjustment.nil? || !@voucher.vine?
if vine_settings.nil?
errors[:vine_settings] = I18n.t("vine_voucher_redeemer_service.errors.vine_settings")
return false
end
response = call_vine_api
if !response.success?
handle_errors(response)
return false
end
voucher_adjustment.close
true
rescue Faraday::Error => e
Rails.logger.error e.inspect
Bugsnag.notify(e)
errors[:vine_api] = I18n.t("vine_voucher_validator_service.errors.vine_api")
false
end
private
def vine_settings
ConnectedApps::Vine.find_by(enterprise: order.distributor)&.data
end
def call_vine_api
jwt_service = Vine::JwtService.new(secret: vine_settings["secret"])
vine_api = Vine::ApiService.new(api_key: vine_settings["api_key"], jwt_generator: jwt_service)
# Voucher amount is stored in dollars, VINE expect cents
vine_api.voucher_redemptions(
@voucher.external_voucher_id, @voucher.external_voucher_set_id, (@voucher.amount * 100)
)
end
def handle_errors(response)
if response.status == 400
errors[:redeeming_failed] = I18n.t("vine_voucher_redeemer_service.errors.redeeming_failed")
else
errors[:vine_api] = I18n.t("vine_voucher_redeemer_service.errors.vine_api")
end
end
end
end

View File

@@ -0,0 +1,84 @@
# frozen_string_literal: true
module Vine
class VoucherValidatorService
attr_reader :voucher_code, :errors
def initialize(voucher_code:, enterprise:)
@voucher_code = voucher_code
@enterprise = enterprise
@errors = {}
end
def validate
if vine_settings.nil?
errors[:vine_settings] = I18n.t("vine_voucher_validator_service.errors.vine_settings")
return nil
end
response = call_vine_api
if !response.success?
handle_errors(response)
return nil
end
save_voucher(response)
rescue Faraday::Error => e
Rails.logger.error e.inspect
Bugsnag.notify(e)
# TODO do we need a more specific error ?
errors[:vine_api] = I18n.t("vine_voucher_validator_service.errors.vine_api")
nil
end
private
def vine_settings
ConnectedApps::Vine.find_by(enterprise: @enterprise)&.data
end
def call_vine_api
# Check voucher is valid
jwt_service = Vine::JwtService.new(secret: vine_settings["secret"])
vine_api = Vine::ApiService.new(api_key: vine_settings["api_key"], jwt_generator: jwt_service)
vine_api.voucher_validation(voucher_code)
end
def handle_errors(response)
if response.status == 400
errors[:invalid_voucher] = I18n.t("vine_voucher_validator_service.errors.invalid_voucher")
elsif response.status == 404
errors[:not_found_voucher] =
I18n.t("vine_voucher_validator_service.errors.not_found_voucher")
else
errors[:vine_api] = I18n.t("vine_voucher_validator_service.errors.vine_api")
end
end
def save_voucher(response)
voucher_data = response.body["data"]
# Check if voucher already exist
voucher = Voucher.vine.find_by(code: voucher_code, enterprise: @enterprise)
amount = voucher_data["voucher_value_remaining"].to_f / 100
if voucher.present?
voucher.update(amount: )
else
voucher = Vouchers::FlatRate.create(
enterprise: @enterprise,
code: voucher_data["voucher_short_code"],
amount:,
external_voucher_id: voucher_data["id"],
external_voucher_set_id: voucher_data["voucher_set_id"],
voucher_type: "VINE"
)
end
voucher
end
end
end

View File

@@ -1,75 +0,0 @@
# frozen_string_literal: true
require "faraday"
class VineApiService
attr_reader :api_key, :jwt_generator
def initialize(api_key:, jwt_generator:)
@vine_api_url = ENV.fetch("VINE_API_URL")
@api_key = api_key
@jwt_generator = jwt_generator
end
def my_team
my_team_url = "#{@vine_api_url}/my-team"
response = connection.get(my_team_url)
log_error("VineApiService#my_team", response)
response
end
def voucher_validation(voucher_short_code)
voucher_validation_url = "#{@vine_api_url}/voucher-validation"
response = connection.post(
voucher_validation_url,
{ type: "voucher_code", value: voucher_short_code },
'Content-Type': "application/json"
)
log_error("VineApiService#voucher_validation", response)
response
end
def voucher_redemptions(voucher_id, voucher_set_id, amount)
voucher_redemptions_url = "#{@vine_api_url}/voucher-redemptions"
response = connection.post(
voucher_redemptions_url,
{ voucher_id:, voucher_set_id:, amount: amount.to_i },
'Content-Type': "application/json"
)
log_error("VineApiService#voucher_redemptions", response)
response
end
private
def connection
jwt = jwt_generator.generate_token
Faraday.new(
request: { timeout: 30 },
headers: {
'X-Authorization': "JWT #{jwt}",
Accept: "application/json"
}
) do |f|
f.request :json
f.response :json
f.request :authorization, 'Bearer', api_key
end
end
def log_error(prefix, response)
return if response.success?
Rails.logger.error "#{prefix} -- response_status: #{response.status}"
Rails.logger.error "#{prefix} -- response: #{response.body}"
end
end

View File

@@ -1,21 +0,0 @@
# frozen_string_literal: true
class VineJwtService
ALGORITHM = "HS256"
ISSUER = "openfoodnetwork"
def initialize(secret: )
@secret = secret
end
def generate_token
generation_time = Time.zone.now
payload = {
iss: ISSUER,
iat: generation_time.to_i,
exp: (generation_time + 1.minute).to_i,
}
JWT.encode(payload, @secret, ALGORITHM)
end
end

View File

@@ -1,64 +0,0 @@
# frozen_string_literal: true
class VineVoucherRedeemerService
attr_reader :order, :errors
def initialize(order: )
@order = order
@errors = {}
end
def call
# Do nothing if we don't have a vine voucher added to the order
voucher_adjustment = order.voucher_adjustments.first
@voucher = voucher_adjustment&.originator
return true if voucher_adjustment.nil? || !@voucher.vine?
if vine_settings.nil?
errors[:vine_settings] = I18n.t("vine_voucher_redeemer_service.errors.vine_settings")
return false
end
response = call_vine_api
if !response.success?
handle_errors(response)
return false
end
voucher_adjustment.close
true
rescue Faraday::Error => e
Rails.logger.error e.inspect
Bugsnag.notify(e)
errors[:vine_api] = I18n.t("vine_voucher_validator_service.errors.vine_api")
false
end
private
def vine_settings
ConnectedApps::Vine.find_by(enterprise: order.distributor)&.data
end
def call_vine_api
jwt_service = VineJwtService.new(secret: vine_settings["secret"])
vine_api = VineApiService.new(api_key: vine_settings["api_key"], jwt_generator: jwt_service)
# Voucher amount is stored in dollars, VINE expect cents
vine_api.voucher_redemptions(
@voucher.external_voucher_id, @voucher.external_voucher_set_id, (@voucher.amount * 100)
)
end
def handle_errors(response)
if response.status == 400
errors[:redeeming_failed] = I18n.t("vine_voucher_redeemer_service.errors.redeeming_failed")
else
errors[:vine_api] = I18n.t("vine_voucher_redeemer_service.errors.vine_api")
end
end
end

View File

@@ -1,81 +0,0 @@
# frozen_string_literal: true
class VineVoucherValidatorService
attr_reader :voucher_code, :errors
def initialize(voucher_code:, enterprise:)
@voucher_code = voucher_code
@enterprise = enterprise
@errors = {}
end
def validate
if vine_settings.nil?
errors[:vine_settings] = I18n.t("vine_voucher_validator_service.errors.vine_settings")
return nil
end
response = call_vine_api
if !response.success?
handle_errors(response)
return nil
end
save_voucher(response)
rescue Faraday::Error => e
Rails.logger.error e.inspect
Bugsnag.notify(e)
# TODO do we need a more specific error ?
errors[:vine_api] = I18n.t("vine_voucher_validator_service.errors.vine_api")
nil
end
private
def vine_settings
ConnectedApps::Vine.find_by(enterprise: @enterprise)&.data
end
def call_vine_api
# Check voucher is valid
jwt_service = VineJwtService.new(secret: vine_settings["secret"])
vine_api = VineApiService.new(api_key: vine_settings["api_key"], jwt_generator: jwt_service)
vine_api.voucher_validation(voucher_code)
end
def handle_errors(response)
if response.status == 400
errors[:invalid_voucher] = I18n.t("vine_voucher_validator_service.errors.invalid_voucher")
elsif response.status == 404
errors[:not_found_voucher] = I18n.t("vine_voucher_validator_service.errors.not_found_voucher")
else
errors[:vine_api] = I18n.t("vine_voucher_validator_service.errors.vine_api")
end
end
def save_voucher(response)
voucher_data = response.body["data"]
# Check if voucher already exist
voucher = Voucher.vine.find_by(code: voucher_code, enterprise: @enterprise)
amount = voucher_data["voucher_value_remaining"].to_f / 100
if voucher.present?
voucher.update(amount: )
else
voucher = Vouchers::FlatRate.create(
enterprise: @enterprise,
code: voucher_data["voucher_short_code"],
amount:,
external_voucher_id: voucher_data["id"],
external_voucher_set_id: voucher_data["voucher_set_id"],
voucher_type: "VINE"
)
end
voucher
end
end

View File

@@ -502,7 +502,7 @@ RSpec.describe CheckoutController, type: :controller do
create(:voucher_flat_rate, voucher_type: "VINE", code: 'some_code',
enterprise: distributor, amount: 6)
}
let(:vine_voucher_redeemer) { instance_double(VineVoucherRedeemerService) }
let(:vine_voucher_redeemer) { instance_double(Vine::VoucherRedeemerService) }
before do
# Adding voucher to the order
@@ -510,11 +510,11 @@ RSpec.describe CheckoutController, type: :controller do
VoucherAdjustmentsService.new(order).update
order.update_totals_and_states
allow(VineVoucherRedeemerService).to receive(:new).and_return(vine_voucher_redeemer)
allow(Vine::VoucherRedeemerService).to receive(:new).and_return(vine_voucher_redeemer)
end
it "completes the order and redirects to order confirmation" do
expect(vine_voucher_redeemer).to receive(:call).and_return(true)
expect(vine_voucher_redeemer).to receive(:redeem).and_return(true)
put(:update, params:)
@@ -524,7 +524,7 @@ RSpec.describe CheckoutController, type: :controller do
context "when redeeming the voucher fails" do
it "returns 422 and some error" do
allow(vine_voucher_redeemer).to receive(:call).and_return(false)
allow(vine_voucher_redeemer).to receive(:redeem).and_return(false)
allow(vine_voucher_redeemer).to receive(:errors).and_return(
{ redeeming_failed: "Redeeming the voucher failed" }
)
@@ -538,7 +538,7 @@ RSpec.describe CheckoutController, type: :controller do
context "when an other error happens" do
it "returns 422 and some error" do
allow(vine_voucher_redeemer).to receive(:call).and_return(false)
allow(vine_voucher_redeemer).to receive(:redeem).and_return(false)
allow(vine_voucher_redeemer).to receive(:errors).and_return(
{ vine_api: "There was an error communicating with the API" }
)

View File

@@ -7,7 +7,7 @@ RSpec.describe ConnectedApps::Vine do
let(:vine_api_key) { "12345" }
let(:secret) { "my_secret" }
let(:vine_api) { instance_double(VineApiService) }
let(:vine_api) { instance_double(Vine::ApiService) }
describe "#connect" do
it "send a request to VINE api" do

View File

@@ -13,11 +13,11 @@ RSpec.describe "Admin ConnectedApp" do
describe "POST /admin/enterprises/:enterprise_id/connected_apps" do
context "with type ConnectedApps::Vine" do
let(:vine_api) { instance_double(VineApiService) }
let(:vine_api) { instance_double(Vine::ApiService) }
before do
allow(VineJwtService).to receive(:new).and_return(instance_double(VineJwtService))
allow(VineApiService).to receive(:new).and_return(vine_api)
allow(Vine::JwtService).to receive(:new).and_return(instance_double(Vine::JwtService))
allow(Vine::ApiService).to receive(:new).and_return(vine_api)
end
it "creates a new connected app" do
@@ -115,7 +115,7 @@ RSpec.describe "Admin ConnectedApp" do
before do
allow(ENV).to receive(:fetch).and_call_original
allow(ENV).to receive(:fetch).with("VINE_API_URL").and_raise(KeyError)
allow(VineApiService).to receive(:new).and_call_original
allow(Vine::ApiService).to receive(:new).and_call_original
end
it "redirects to enterprise edit page, with an error" do

View File

@@ -76,16 +76,16 @@ RSpec.describe Spree::Admin::PaymentsController, type: :request do
create(:voucher_flat_rate, voucher_type: "VINE", code: 'some_code',
enterprise: order.distributor, amount: 6)
}
let(:vine_voucher_redeemer) { instance_double(VineVoucherRedeemerService) }
let(:vine_voucher_redeemer) { instance_double(Vine::VoucherRedeemerService) }
before do
add_voucher_to_order(vine_voucher, order)
allow(VineVoucherRedeemerService).to receive(:new).and_return(vine_voucher_redeemer)
allow(Vine::VoucherRedeemerService).to receive(:new).and_return(vine_voucher_redeemer)
end
it "completes the order and redirects to payment page" do
expect(vine_voucher_redeemer).to receive(:call).and_return(true)
expect(vine_voucher_redeemer).to receive(:redeem).and_return(true)
post("/admin/orders/#{order.number}/payments.json", params:)
@@ -97,7 +97,7 @@ RSpec.describe Spree::Admin::PaymentsController, type: :request do
context "when redeeming the voucher fails" do
it "redirect to payments page" do
allow(vine_voucher_redeemer).to receive(:call).and_return(false)
allow(vine_voucher_redeemer).to receive(:redeem).and_return(false)
allow(vine_voucher_redeemer).to receive(:errors).and_return(
{ redeeming_failed: "Redeeming the voucher failed" }
)
@@ -111,7 +111,7 @@ RSpec.describe Spree::Admin::PaymentsController, type: :request do
context "when an other error happens" do
it "redirect to payments page" do
allow(vine_voucher_redeemer).to receive(:call).and_return(false)
allow(vine_voucher_redeemer).to receive(:redeem).and_return(false)
allow(vine_voucher_redeemer).to receive(:errors).and_return(
{ vine_api: "There was an error communicating with the API" }
)
@@ -267,16 +267,16 @@ RSpec.describe Spree::Admin::PaymentsController, type: :request do
create(:voucher_flat_rate, voucher_type: "VINE", code: 'some_code',
enterprise: order.distributor, amount: 6)
}
let(:vine_voucher_redeemer) { instance_double(VineVoucherRedeemerService) }
let(:vine_voucher_redeemer) { instance_double(Vine::VoucherRedeemerService) }
before do
add_voucher_to_order(vine_voucher, order)
allow(VineVoucherRedeemerService).to receive(:new).and_return(vine_voucher_redeemer)
allow(Vine::VoucherRedeemerService).to receive(:new).and_return(vine_voucher_redeemer)
end
it "completes the order and redirects to payment page" do
expect(vine_voucher_redeemer).to receive(:call).and_return(true)
expect(vine_voucher_redeemer).to receive(:redeem).and_return(true)
put(
"/admin/orders/#{order.number}/payments/#{order.payments.first.id}/" \
@@ -293,7 +293,7 @@ RSpec.describe Spree::Admin::PaymentsController, type: :request do
context "when redeeming the voucher fails" do
it "redirect to payments page" do
allow(vine_voucher_redeemer).to receive(:call).and_return(false)
allow(vine_voucher_redeemer).to receive(:redeem).and_return(false)
allow(vine_voucher_redeemer).to receive(:errors).and_return(
{ redeeming_failed: "Redeeming the voucher failed" }
)
@@ -312,7 +312,7 @@ RSpec.describe Spree::Admin::PaymentsController, type: :request do
context "when an other error happens" do
it "redirect to payments page" do
allow(vine_voucher_redeemer).to receive(:call).and_return(false)
allow(vine_voucher_redeemer).to receive(:redeem).and_return(false)
allow(vine_voucher_redeemer).to receive(:errors).and_return(
{ vine_api: "There was an error communicating with the API" }
)

View File

@@ -87,10 +87,10 @@ RSpec.describe VoucherAdjustmentsController, type: :request do
end
context "with a VINE voucher", feature: :connected_apps do
let(:vine_voucher_validator) { instance_double(VineVoucherValidatorService) }
let(:vine_voucher_validator) { instance_double(Vine::VoucherValidatorService) }
before do
allow(VineVoucherValidatorService).to receive(:new).and_return(vine_voucher_validator)
allow(Vine::VoucherValidatorService).to receive(:new).and_return(vine_voucher_validator)
end
context "with a new voucher" do

View File

@@ -2,12 +2,12 @@
require "spec_helper"
RSpec.describe VineApiService do
RSpec.describe Vine::ApiService do
subject(:vine_api) { described_class.new(api_key: vine_api_key, jwt_generator: jwt_service) }
let(:vine_api_url) { "https://vine-staging.openfoodnetwork.org.au/api/v1" }
let(:vine_api_key) { "12345" }
let(:jwt_service) { VineJwtService.new(secret:) }
let(:jwt_service) { Vine::JwtService.new(secret:) }
let(:secret) { "my_secret" }
let(:token) { "some.jwt.token" }
@@ -59,7 +59,7 @@ RSpec.describe VineApiService do
it "logs the error" do
stub_request(:get, my_team_url).to_return(body: "error", status: 401)
expect(Rails.logger).to receive(:error).with(match("VineApiService#my_team")).twice
expect(Rails.logger).to receive(:error).with(match("Vine::ApiService#my_team")).twice
response = vine_api.my_team
@@ -124,7 +124,7 @@ RSpec.describe VineApiService do
stub_request(:post, voucher_validation_url).to_return(body: "error", status: 401)
expect(Rails.logger).to receive(:error).with(
match("VineApiService#voucher_validation")
match("Vine::ApiService#voucher_validation")
).twice
response = vine_api.voucher_validation(voucher_short_code)
@@ -192,7 +192,7 @@ RSpec.describe VineApiService do
stub_request(:post, voucher_redemptions_url).to_return(body: "error", status: 401)
expect(Rails.logger).to receive(:error).with(
match("VineApiService#voucher_redemptions")
match("Vine::ApiService#voucher_redemptions")
).twice
response = vine_api.voucher_redemptions(voucher_id, voucher_set_id, amount)

View File

@@ -2,7 +2,7 @@
require "spec_helper"
RSpec.describe VineJwtService do
RSpec.describe Vine::JwtService do
describe "#generate_token" do
subject { described_class.new(secret: vine_secret) }
let(:vine_secret) { "some_secret" }

View File

@@ -2,7 +2,7 @@
require "spec_helper"
RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
RSpec.describe Vine::VoucherRedeemerService, feature: :connected_apps do
subject(:voucher_redeemer_service) { described_class.new(order: ) }
let(:user) { order.user }
@@ -17,13 +17,13 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
}
let(:voucher_id) { "9d316d27-0dad-411a-8953-316a1aaf7742" }
let(:voucher_set_id) { "9d314daa-0878-4b73-922d-698047640cf4" }
let(:vine_api_service) { instance_double(VineApiService) }
let(:vine_api_service) { instance_double(Vine::ApiService) }
before do
allow(VineApiService).to receive(:new).and_return(vine_api_service)
allow(Vine::ApiService).to receive(:new).and_return(vine_api_service)
end
describe "#call" do
describe "#redeem" do
context "with a valid voucher" do
let!(:vine_connected_app) {
ConnectedApps::Vine.create(
@@ -60,7 +60,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
.with(voucher_id, voucher_set_id, 600)
.and_return(mock_api_response(success: true, data:))
voucher_redeemer_service.call
voucher_redeemer_service.redeem
end
it "closes the linked assement" do
@@ -68,7 +68,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
.and_return(mock_api_response(success: true, data:))
expect {
voucher_redeemer_service.call
voucher_redeemer_service.redeem
}.to change { order.voucher_adjustments.first.state }.to("closed")
end
@@ -76,7 +76,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
allow(vine_api_service).to receive(:voucher_redemptions)
.and_return(mock_api_response(success: true, data:))
expect(voucher_redeemer_service.call).to be(true)
expect(voucher_redeemer_service.redeem).to be(true)
end
context "when redeeming fails" do
@@ -93,16 +93,16 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
it "doesn't close the linked assement" do
expect {
voucher_redeemer_service.call
voucher_redeemer_service.redeem
}.not_to change { order.voucher_adjustments.first.state }
end
it "returns false" do
expect(voucher_redeemer_service.call).to be(false)
expect(voucher_redeemer_service.redeem).to be(false)
end
it "adds an error message" do
voucher_redeemer_service.call
voucher_redeemer_service.redeem
expect(voucher_redeemer_service.errors).to include(
{ redeeming_failed: "Redeeming the voucher failed" }
@@ -115,17 +115,17 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
before { add_voucher(vine_voucher) }
it "returns false" do
expect(voucher_redeemer_service.call).to be(false)
expect(voucher_redeemer_service.redeem).to be(false)
end
it "doesn't call the VINE API" do
it "doesn't redeem the VINE API" do
expect(vine_api_service).not_to receive(:voucher_redemptions)
voucher_redeemer_service.call
voucher_redeemer_service.redeem
end
it "adds an error message" do
voucher_redeemer_service.call
voucher_redeemer_service.redeem
expect(voucher_redeemer_service.errors).to include(
{ vine_settings: "No Vine api settings for the given enterprise" }
@@ -134,7 +134,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
it "doesn't close the linked assement" do
expect {
voucher_redeemer_service.call
voucher_redeemer_service.redeem
}.not_to change { order.voucher_adjustments.first.state }
end
end
@@ -148,13 +148,13 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
}
it "returns true" do
expect(voucher_redeemer_service.call).to be(true)
expect(voucher_redeemer_service.redeem).to be(true)
end
it "doesn't call the VINE API" do
it "doesn't redeem the VINE API" do
expect(vine_api_service).not_to receive(:voucher_redemptions)
voucher_redeemer_service.call
voucher_redeemer_service.redeem
end
end
@@ -169,13 +169,13 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
before { add_voucher(voucher) }
it "returns true" do
expect(voucher_redeemer_service.call).to be(true)
expect(voucher_redeemer_service.redeem).to be(true)
end
it "doesn't call the VINE API" do
it "doesn't redeem the VINE API" do
expect(vine_api_service).not_to receive(:voucher_redemptions)
voucher_redeemer_service.call
voucher_redeemer_service.redeem
end
end
@@ -192,11 +192,11 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
end
it "returns false" do
expect(voucher_redeemer_service.call).to be(false)
expect(voucher_redeemer_service.redeem).to be(false)
end
it "adds an error message" do
voucher_redeemer_service.call
voucher_redeemer_service.redeem
expect(voucher_redeemer_service.errors).to include(
{ vine_api: "There was an error communicating with the API" }
@@ -205,7 +205,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
it "doesn't close the linked assement" do
expect {
voucher_redeemer_service.call
voucher_redeemer_service.redeem
}.not_to change { order.voucher_adjustments.first.state }
end
@@ -213,7 +213,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
expect(Rails.logger).to receive(:error)
expect(Bugsnag).to receive(:notify)
voucher_redeemer_service.call
voucher_redeemer_service.redeem
end
end
@@ -240,11 +240,11 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
end
it "returns false" do
expect(voucher_redeemer_service.call).to be(false)
expect(voucher_redeemer_service.redeem).to be(false)
end
it "adds an error message" do
voucher_redeemer_service.call
voucher_redeemer_service.redeem
expect(voucher_redeemer_service.errors).to include(
{ vine_api: "There was an error communicating with the API" }
@@ -253,7 +253,7 @@ RSpec.describe VineVoucherRedeemerService, feature: :connected_apps do
it "doesn't close the linked assement" do
expect {
voucher_redeemer_service.call
voucher_redeemer_service.redeem
}.not_to change { order.voucher_adjustments.first.state }
end
end

View File

@@ -2,15 +2,15 @@
require "spec_helper"
RSpec.describe VineVoucherValidatorService, feature: :connected_apps do
RSpec.describe Vine::VoucherValidatorService, feature: :connected_apps do
subject(:validate_voucher_service) { described_class.new(voucher_code:, enterprise: distributor) }
let(:voucher_code) { "good_code" }
let(:distributor) { create(:distributor_enterprise) }
let(:vine_api_service) { instance_double(VineApiService) }
let(:vine_api_service) { instance_double(Vine::ApiService) }
before do
allow(VineApiService).to receive(:new).and_return(vine_api_service)
allow(Vine::ApiService).to receive(:new).and_return(vine_api_service)
end
describe "#validate" do