diff --git a/app/services/vine_api_service.rb b/app/services/vine_api_service.rb new file mode 100644 index 0000000000..8fa34ce48a --- /dev/null +++ b/app/services/vine_api_service.rb @@ -0,0 +1,39 @@ +# 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" + + jwt = jwt_generator.generate_token + connection = 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 + + response = connection.get(my_team_url) + + if !response.success? + Rails.logger.error "VineApiService#my_team -- response_status: #{response.status}" + Rails.logger.error "VineApiService#my_team -- response: #{response.body}" + end + + response + end +end diff --git a/spec/fixtures/vcr_cassettes/VineApiService/_my_team/when_a_request_succeed/returns_the_response_do.yml b/spec/fixtures/vcr_cassettes/VineApiService/_my_team/when_a_request_succeed/returns_the_response_do.yml new file mode 100644 index 0000000000..136540eb6a --- /dev/null +++ b/spec/fixtures/vcr_cassettes/VineApiService/_my_team/when_a_request_succeed/returns_the_response_do.yml @@ -0,0 +1,53 @@ +--- +http_interactions: +- request: + method: get + uri: https://vine-staging.openfoodnetwork.org.au/api/v1/my-team + body: + encoding: US-ASCII + string: '' + headers: + X-Authorization: + - "" + User-Agent: + - Faraday v2.9.0 + Authorization: + - "" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + 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: + - Wed, 02 Oct 2024 00:27:30 GMT + 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":"","cached":true,"cached_at":"2024-10-02 + 00:27:30","availableRelations":["teamUsers.user","country"]},"data":{"id":1,"name":"OK200 + Team","country_id":14,"created_at":"2024-09-12T06:39:07.000000Z","updated_at":"2024-09-12T06:39:07.000000Z","deleted_at":null}}' + recorded_at: Wed, 02 Oct 2024 00:27:30 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 new file mode 100644 index 0000000000..c0cb2953a4 --- /dev/null +++ b/spec/services/vine_api_service_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe VineApiService 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(:secret) { "my_secret" } + + before do + allow(ENV).to receive(:fetch).and_call_original + allow(ENV).to receive(:fetch).with("VINE_API_URL").and_return(vine_api_url) + end + + describe "#my_team" do + let(:my_team_url) { "#{vine_api_url}/my-team" } + + it "send a request to the team VINE api endpoint" do + stub_request(:get, my_team_url).to_return(status: 200) + + vine_api.my_team + + expect(a_request( + :get, "https://vine-staging.openfoodnetwork.org.au/api/v1/my-team" + )).to have_been_made + end + + it "sends the VINE api key via a header" do + stub_request(:get, my_team_url).to_return(status: 200) + + 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 + 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) + + 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 + end + + context "when a request succeed", :vcr do + it "returns the response do" do + response = vine_api.my_team + + 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(:get, my_team_url).to_return(body: "error", status: 401) + + expect(Rails.logger).to receive(:error).twice + + response = vine_api.my_team + + expect(response.success?).to be(false) + end + + it "return the response" do + stub_request(:get, my_team_url).to_return(body: "error", status: 401) + response = vine_api.my_team + + expect(response.success?).to be(false) + expect(response.body).not_to be_empty + end + end + end +end