diff --git a/Gemfile.lock b/Gemfile.lock index ef24419..ef9a574 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - graphql-hive (0.4.0) + graphql-hive (0.4.1) graphql (>= 2.3, < 3) GEM diff --git a/k6/graphql-api/Gemfile.lock b/k6/graphql-api/Gemfile.lock index c018f7e..e244fbe 100644 --- a/k6/graphql-api/Gemfile.lock +++ b/k6/graphql-api/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: ../.. specs: - graphql-hive (0.4.0) + graphql-hive (0.4.1) graphql (>= 2.3, < 3) GEM diff --git a/lib/graphql-hive/client.rb b/lib/graphql-hive/client.rb index 95d3c51..3068b48 100644 --- a/lib/graphql-hive/client.rb +++ b/lib/graphql-hive/client.rb @@ -20,22 +20,34 @@ def send(path, body, _log_type) path: path ) + http = setup_http(uri) + request = build_request(uri, body) + response = http.request(request) + + @options[:logger].debug(response.inspect) + @options[:logger].debug(response.body.inspect) + rescue StandardError => e + @options[:logger].fatal("Failed to send data: #{e}") + raise e + end + + def setup_http(uri) http = ::Net::HTTP.new(uri.host, uri.port) http.use_ssl = @options[:port].to_s == '443' http.read_timeout = 2 + http + end + + def build_request(uri, body) request = Net::HTTP::Post.new(uri.request_uri) + request['Authorization'] = @options[:token] + request['X-Usage-API-Version'] = '2' request['content-type'] = 'application/json' - request['x-api-token'] = @options[:token] request['User-Agent'] = "Hive@#{Graphql::Hive::VERSION}" request['graphql-client-name'] = 'Hive Ruby Client' request['graphql-client-version'] = Graphql::Hive::VERSION request.body = JSON.generate(body) - response = http.request(request) - - @options[:logger].debug(response.inspect) - @options[:logger].debug(response.body.inspect) - rescue StandardError => e - @options[:logger].fatal("Failed to send data: #{e}") + request end end end diff --git a/lib/graphql-hive/usage_reporter.rb b/lib/graphql-hive/usage_reporter.rb index cc6147a..d5beca1 100644 --- a/lib/graphql-hive/usage_reporter.rb +++ b/lib/graphql-hive/usage_reporter.rb @@ -128,8 +128,7 @@ def add_operation_to_report(report, operation) execution: { ok: errors[:errorsTotal].zero?, duration: duration, - errorsTotal: errors[:errorsTotal], - errors: errors[:errors] + errorsTotal: errors[:errorsTotal] } } @@ -148,12 +147,11 @@ def add_operation_to_report(report, operation) end def errors_from_results(results) - acc = { errorsTotal: 0, errors: [] } + acc = { errorsTotal: 0 } results.each do |result| errors = result.to_h.fetch('errors', []) - errors.each do |error| + errors.each do acc[:errorsTotal] += 1 - acc[:errors] << { message: error['message'], path: error['path']&.join('.') } end end acc diff --git a/lib/graphql-hive/version.rb b/lib/graphql-hive/version.rb index 49e8915..f847a4b 100644 --- a/lib/graphql-hive/version.rb +++ b/lib/graphql-hive/version.rb @@ -2,6 +2,6 @@ module Graphql module Hive - VERSION = '0.4.0' + VERSION = '0.4.1' end end diff --git a/spec/graphql/graphql-hive/client_spec.rb b/spec/graphql/graphql-hive/client_spec.rb new file mode 100644 index 0000000..4bfba80 --- /dev/null +++ b/spec/graphql/graphql-hive/client_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'graphql-hive' + +RSpec.describe GraphQL::Hive::Client do + let(:options) do + { + endpoint: 'app.graphql-hive.com', + port: 443, + token: 'Bearer test-token', + logger: Logger.new(nil) + } + end + + let(:client) { described_class.new(options) } + let(:body) { { size: 3, map: {}, operations: [] } } + + describe '#initialize' do + it 'sets the instance' do + expect(client.instance_variable_get(:@options)).to eq(options) + end + end + + describe '#send' do + let(:http) { instance_double(Net::HTTP) } + let(:request) { instance_double(Net::HTTP::Post) } + let(:response) { instance_double(Net::HTTPOK, body: '', code: '200') } + + before do + allow(Net::HTTP).to receive(:new).and_return(http) + allow(Net::HTTP::Post).to receive(:new).and_return(request) + + allow(http).to receive(:use_ssl=) + allow(http).to receive(:read_timeout=) + allow(http).to receive(:request).and_return(response) + + allow(request).to receive(:[]=) # request['header-name'] = 'header-value' + allow(request).to receive(:body=) + end + + it 'sets up the HTTP session' do + expect(Net::HTTP).to receive(:new).with('app.graphql-hive.com', 443).and_return(http) + expect(http).to receive(:use_ssl=).with(true) + expect(http).to receive(:read_timeout=).with(2) + + client.send('/usage', body, :usage) + end + + it 'creates the request with the correct headers and body' do + expect(Net::HTTP::Post).to receive(:new).with('/usage').and_return(request) + expect(request).to receive(:[]=).with('Authorization', 'Bearer test-token') + expect(request).to receive(:[]=).with('X-Usage-API-Version', '2') + expect(request).to receive(:[]=).with('content-type', 'application/json') + expect(request).to receive(:[]=).with('User-Agent', "Hive@#{Graphql::Hive::VERSION}") + expect(request).to receive(:[]=).with('graphql-client-name', 'Hive Ruby Client') + expect(request).to receive(:[]=).with('graphql-client-version', Graphql::Hive::VERSION) + expect(request).to receive(:body=).with(JSON.generate(body)) + + client.send('/usage', body, :usage) + end + + it 'executes the request' do + expect(http).to receive(:request).with(request).and_return(response) + client.send('/usage', body, :usage) + end + + it 'logs a fatal error and raises an exception when an exception is raised' do + allow(http).to receive(:request).and_raise(StandardError.new('Network error')) + expect(options[:logger]).to receive(:fatal).with('Failed to send data: Network error') + expect { client.send('/usage', body, :usage) }.to raise_error(StandardError, 'Network error') + end + end +end diff --git a/spec/graphql/graphql-hive/usage_reporter_spec.rb b/spec/graphql/graphql-hive/usage_reporter_spec.rb index 889e70d..b0f80cd 100644 --- a/spec/graphql/graphql-hive/usage_reporter_spec.rb +++ b/spec/graphql/graphql-hive/usage_reporter_spec.rb @@ -131,7 +131,7 @@ } }, operations: [ { - execution: { duration: 100_000, errors: [], errorsTotal: 0, ok: true }, + execution: { duration: 100_000, errorsTotal: 0, ok: true }, operationMapKey: '8b8412ce86f3ea7accb931b1a5de335d', timestamp: 1_720_705_946_333 }