diff --git a/app/services/vine_api_service.rb b/app/services/vine_api_service.rb index 8fa34ce48a..131e83b239 100644 --- a/app/services/vine_api_service.rb +++ b/app/services/vine_api_service.rb @@ -14,8 +14,32 @@ class VineApiService 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 + + private + + def connection jwt = jwt_generator.generate_token - connection = Faraday.new( + Faraday.new( request: { timeout: 30 }, headers: { 'X-Authorization': "JWT #{jwt}", @@ -26,14 +50,12 @@ class VineApiService f.response :json f.request :authorization, 'Bearer', api_key end + end - response = connection.get(my_team_url) + def log_error(prefix, response) + return if response.success? - if !response.success? - Rails.logger.error "VineApiService#my_team -- response_status: #{response.status}" - Rails.logger.error "VineApiService#my_team -- response: #{response.body}" - end - - response + Rails.logger.error "#{prefix} -- response_status: #{response.status}" + Rails.logger.error "#{prefix} -- response: #{response.body}" end end diff --git a/spec/fixtures/vcr_cassettes/VineApiService/_voucher_validation/when_a_request_succeed/returns_the_response.yml b/spec/fixtures/vcr_cassettes/VineApiService/_voucher_validation/when_a_request_succeed/returns_the_response.yml new file mode 100644 index 0000000000..847f63ece3 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/VineApiService/_voucher_validation/when_a_request_succeed/returns_the_response.yml @@ -0,0 +1,57 @@ +--- +http_interactions: +- request: + method: post + uri: https://vine-staging.openfoodnetwork.org.au/api/v1/voucher-validation + body: + encoding: UTF-8 + string: '{"type":"voucher_code","value":"CI3922"}' + headers: + X-Authorization: + - "" + Accept: + - application/json + User-Agent: + - Faraday v2.9.0 + Content-Type: + - application/json + Authorization: + - "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Content-Type: + - application/json + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Vary: + - Accept-Encoding + Cache-Control: + - no-cache, private + Date: + - Mon, 07 Oct 2024 23:48:46 GMT + X-Ratelimit-Limit: + - '60' + X-Ratelimit-Remaining: + - '59' + Access-Control-Allow-Origin: + - "*" + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + body: + encoding: ASCII-8BIT + string: '{"meta":{"responseCode":200,"limit":50,"offset":0,"message":""},"data":{"id":"9d2437c8-4559-4dda-802e-8d9c642a0c1d","voucher_short_code":"CI3922","voucher_set_id":"9d24349c-1fe8-4090-988b-d7355ed32559","is_test":1,"voucher_value_original":500,"voucher_value_remaining":500,"num_voucher_redemptions":0,"last_redemption_at":null,"created_at":"2024-10-01T13:20:02.000000Z","updated_at":"2024-10-01T13:20:02.000000Z","deleted_at":null}}' + recorded_at: Mon, 07 Oct 2024 23:48:46 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/services/vine_api_service_spec.rb b/spec/services/vine_api_service_spec.rb index 0614931719..e9321fbb84 100644 --- a/spec/services/vine_api_service_spec.rb +++ b/spec/services/vine_api_service_spec.rb @@ -9,6 +9,7 @@ RSpec.describe VineApiService do let(:vine_api_key) { "12345" } let(:jwt_service) { VineJwtService.new(secret:) } let(:secret) { "my_secret" } + let(:token) { "some.jwt.token" } before do allow(ENV).to receive(:fetch).and_call_original @@ -33,22 +34,16 @@ RSpec.describe VineApiService do vine_api.my_team - expect(a_request(:get, "https://vine-staging.openfoodnetwork.org.au/api/v1/my-team").with( - headers: { Authorization: "Bearer #{vine_api_key}" } - )).to have_been_made + expect_request_with_api_key(:get, "https://vine-staging.openfoodnetwork.org.au/api/v1/my-team") end it "sends JWT token via a header" do - token = "some.jwt.token" stub_request(:get, my_team_url).to_return(status: 200) - - allow(jwt_service).to receive(:generate_token).and_return(token) + mock_jwt_service vine_api.my_team - expect(a_request(:get, "https://vine-staging.openfoodnetwork.org.au/api/v1/my-team").with( - headers: { 'X-Authorization': "JWT #{token}" } - )).to have_been_made + expect_request_with_jwt_token(:get, "https://vine-staging.openfoodnetwork.org.au/api/v1/my-team") end context "when a request succeed", :vcr do @@ -64,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).twice + expect(Rails.logger).to receive(:error).with(match("VineApiService#my_team")).twice response = vine_api.my_team @@ -80,4 +75,85 @@ RSpec.describe VineApiService do end end end + + describe "#voucher_validation" do + let(:voucher_validation_url) { "#{vine_api_url}/voucher-validation" } + let(:voucher_short_code) { "123456" } + # let(:voucher_short_code) { "CI3922" } + + it "send a POST request to the team VINE api endpoint" do + stub_request(:post, voucher_validation_url).to_return(status: 200) + vine_api.voucher_validation(voucher_short_code) + + expect(a_request( + :post, "https://vine-staging.openfoodnetwork.org.au/api/v1/voucher-validation" + ).with(body: { type: "voucher_code", value: voucher_short_code } )).to have_been_made + end + + it "sends the VINE api key via a header" do + stub_request(:post, voucher_validation_url).to_return(status: 200) + + vine_api.voucher_validation(voucher_short_code) + + expect_request_with_api_key( + :post, "https://vine-staging.openfoodnetwork.org.au/api/v1/voucher-validation" + ) + end + + it "sends JWT token via a header" do + stub_request(:post, voucher_validation_url).to_return(status: 200) + mock_jwt_service + + vine_api.voucher_validation(voucher_short_code) + + expect_request_with_jwt_token( + :post, "https://vine-staging.openfoodnetwork.org.au/api/v1/voucher-validation" + ) + end + + context "when a request succeed", :vcr do + it "returns the response" do + response = vine_api.voucher_validation(voucher_short_code) + + expect(response.success?).to be(true) + expect(response.body).not_to be_empty + end + end + + context "when a request fails" do + it "logs the error" do + stub_request(:post, voucher_validation_url).to_return(body: "error", status: 401) + + expect(Rails.logger).to receive(:error).with( + match("VineApiService#voucher_validation") + ).twice + + response = vine_api.voucher_validation(voucher_short_code) + + expect(response.success?).to be(false) + end + + it "return the response" do + stub_request(:post, voucher_validation_url).to_return(body: "error", status: 401) + response = vine_api.voucher_validation(voucher_short_code) + + expect(response.success?).to be(false) + expect(response.body).not_to be_empty + end + end + end + + def expect_request_with_api_key(method, url) + expect(a_request(method, url).with( headers: { Authorization: "Bearer #{vine_api_key}" })) + .to have_been_made + end + + def expect_request_with_jwt_token(method, url) + expect(a_request(method, url).with( headers: { 'X-Authorization': "JWT #{token}" })) + .to have_been_made + end + + def mock_jwt_service + allow(jwt_service).to receive(:generate_token).and_return(token) + end end