From 4d20139b815f92768ee98072d1c0b60653cda6f4 Mon Sep 17 00:00:00 2001 From: Ivan Naumov Date: Tue, 27 Feb 2024 23:00:43 +0300 Subject: [PATCH] Add mutant and simplify errors --- .mutant.yml | 21 +++++++++++++++++++++ Gemfile | 3 +++ Gemfile.lock | 22 +++++++++++++++++++++- lib/shikimori/api/errors.rb | 13 +------------ lib/shikimori/api/rest.rb | 16 ++++++++++++---- lib/shikimori/oauth2/config.rb | 2 ++ sig/shikimori/api.rbs | 3 --- sig/shikimori/api/rest.rbs | 7 ++++--- spec/shikimori/api/v1/achievements_spec.rb | 2 +- 9 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 .mutant.yml diff --git a/.mutant.yml b/.mutant.yml new file mode 100644 index 0000000..157c2bb --- /dev/null +++ b/.mutant.yml @@ -0,0 +1,21 @@ +includes: +- lib +requires: +- shikimori-api +- shikimori-oauth2 +- omniauth-shikimori-oauth2 + +matcher: + subjects: + - Shikimori::API* + - Shikimori::OAuth2* + - Omniauth::Strategies::Shikimori + - Omniauth::Shikimori* +integration: + name: rspec + arguments: + - --fail-fast + - --seed + - '0' + - spec +fail_fast: true diff --git a/Gemfile b/Gemfile index 08b100c..6815fe1 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,9 @@ group :development, :test do gem 'steep', require: false gem 'typeprof', require: false + + gem 'mutant-license', source: 'https://oss:gOVCrJ1XYGYW9WKqeEAXZojdLPBu4oNM@gem.mutant.dev' + gem 'mutant-rspec' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 131aee2..5f90c0b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,11 @@ PATH shikimori-oauth2 (1.0.1) oauth2 (~> 2.0.0) +GEM + remote: https://oss:gOVCrJ1XYGYW9WKqeEAXZojdLPBu4oNM@gem.mutant.dev/ + specs: + mutant-license (0.1.1.2.1808796712161246693429340807553770173020.0) + GEM remote: https://rubygems.org/ specs: @@ -58,6 +63,15 @@ GEM logger (1.6.0) minitest (5.22.2) multi_xml (0.6.0) + mutant (0.11.28) + diff-lcs (~> 1.3) + parser (~> 3.3.0) + regexp_parser (~> 2.8.2) + sorbet-runtime (~> 0.5.0) + unparser (~> 0.6.9) + mutant-rspec (0.11.28) + mutant (= 0.11.28) + rspec-core (>= 3.8.0, < 4.0.0) mutex_m (0.2.0) net-http (0.4.1) uri @@ -94,7 +108,7 @@ GEM ffi (~> 1.0) rbs (3.4.4) abbrev - regexp_parser (2.9.0) + regexp_parser (2.8.3) rexml (3.2.6) rspec (3.13.0) rspec-core (~> 3.13.0) @@ -150,6 +164,7 @@ GEM snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) + sorbet-runtime (0.5.11274) steep (1.6.0) activesupport (>= 5.1) concurrent-ruby (>= 1.1.10) @@ -173,6 +188,9 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) + unparser (0.6.13) + diff-lcs (~> 1.3) + parser (>= 3.3.0) uri (0.13.0) vcr (6.2.0) version_gem (1.1.3) @@ -187,6 +205,8 @@ PLATFORMS DEPENDENCIES dotenv + mutant-license! + mutant-rspec omniauth-shikimori-oauth2! rack-test rake diff --git a/lib/shikimori/api/errors.rb b/lib/shikimori/api/errors.rb index cd6297f..87bd3dd 100644 --- a/lib/shikimori/api/errors.rb +++ b/lib/shikimori/api/errors.rb @@ -3,19 +3,8 @@ module Shikimori module API class RequestError < StandardError; end - class NotFoundError < RequestError; end class ForbiddenError < RequestError; end - - # Error, when request is bad - class BadRequestError < RequestError - attr_reader :errors - - def initialize(errors) - @errors = errors.is_a?(Hash) ? errors['errors'] : errors - - super("Bad request. Errors:\n\t#{@errors.join("\n\t")}") - end - end + class BadRequestError < RequestError; end end end diff --git a/lib/shikimori/api/rest.rb b/lib/shikimori/api/rest.rb index 2bd5d78..14a9b04 100644 --- a/lib/shikimori/api/rest.rb +++ b/lib/shikimori/api/rest.rb @@ -80,8 +80,6 @@ def start_request(uri, request, body = nil, **options) def parse_response(response) case response - when Net::HTTPNoContent - {} when Net::HTTPSuccess, Net::HTTPCreated json_parse_response_body(response.body) when Net::HTTPForbidden @@ -89,12 +87,22 @@ def parse_response(response) when Net::HTTPNotFound raise NotFoundError when Net::HTTPUnprocessableEntity, Net::HTTPBadRequest - raise BadRequestError, json_parse_response_body(response.body) + raise BadRequestError, json_parse_response_errors(response.body) + end + end + + def json_parse_response_errors(body) + error = json_parse_response_body(body) + + if error.is_a?(Array) + error.join(', ') + elsif error.is_a?(Hash) && error.key?('errors') + error['errors'] end end def json_parse_response_body(body) - JSON.parse(body&.empty? ? '{}' : body) + JSON.parse(body.nil? || body.empty? ? '{}' : body) rescue JSON::ParserError {} end diff --git a/lib/shikimori/oauth2/config.rb b/lib/shikimori/oauth2/config.rb index 6807984..41ba335 100644 --- a/lib/shikimori/oauth2/config.rb +++ b/lib/shikimori/oauth2/config.rb @@ -4,7 +4,9 @@ module Shikimori module OAuth2 # Configuration for Shikimori OAuth2 client class Config + # @return [String] Default site url DEFAULT_SITE_URL = 'https://shikimori.one/' + # @return [String] Default APP name DEFAULT_APP_NAME = 'Api Test' attr_accessor :options, :site, :app_name diff --git a/sig/shikimori/api.rbs b/sig/shikimori/api.rbs index 85d5626..fa707c7 100644 --- a/sig/shikimori/api.rbs +++ b/sig/shikimori/api.rbs @@ -10,9 +10,6 @@ module Shikimori end class BadRequestError < RequestError - attr_reader errors: Array[String] - - def initialize: (Array[String] | { "errors" => Array[String] }) -> void end end end diff --git a/sig/shikimori/api/rest.rbs b/sig/shikimori/api/rest.rbs index ef1a73b..056d788 100644 --- a/sig/shikimori/api/rest.rbs +++ b/sig/shikimori/api/rest.rbs @@ -22,11 +22,12 @@ module Shikimori private - def request: (request_method, ::URI::Generic, ?body, **untyped) -> [Net::HTTPResponse, (::Hash[_ToS, Object] | nil)] + def request: (request_method, ::URI::Generic, ?body, **untyped) -> [Net::HTTPResponse, (::Hash[_ToS, Object] | nil | Array[untyped])] def build_request: (request_method, ::URI::Generic, **untyped) -> request def start_request: (::URI::Generic, request, ?body, **untyped) -> Net::HTTPResponse - def parse_response: (Net::HTTPResponse response) -> (::Hash[_ToS, untyped] | nil) - def json_parse_response_body: (String) -> (::Hash[_ToS, untyped] | nil) + def parse_response: (Net::HTTPResponse response) -> (::Hash[_ToS, untyped] | Array[untyped] | nil) + def json_parse_response_errors: (String) -> (String | nil) + def json_parse_response_body: (String) -> (::Hash[_ToS, untyped] | Array[untyped] | nil) def headers_from: (Hash[untyped, untyped]) -> Hash[String, String] def query_params_from: (::URI::Generic, Hash[untyped, untyped]) -> untyped end diff --git a/spec/shikimori/api/v1/achievements_spec.rb b/spec/shikimori/api/v1/achievements_spec.rb index a1d40ef..59675c7 100644 --- a/spec/shikimori/api/v1/achievements_spec.rb +++ b/spec/shikimori/api/v1/achievements_spec.rb @@ -22,7 +22,7 @@ it { expect { request }.to raise_error( Shikimori::API::BadRequestError, - /Bad request. Errors:/ + "Invalid parameter 'user_id' value \"$bad_format\": Must be a number." ) } end