From 3013238f465df29874b811814e9e535cb4c98185 Mon Sep 17 00:00:00 2001 From: Andrew Burleson Date: Tue, 23 Nov 2021 12:18:52 -0600 Subject: [PATCH 1/6] Add #to_json on APIResources This PR adds a to_h and to_json method on API resources. It's helpful if you want to get back the raw data that an Emailable API Request returned, for example to serialize and cache that data for future use. --- lib/emailable/resources/api_resource.rb | 20 ++++++-- test/emailable/resources/api_resource_test.rb | 46 +++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 test/emailable/resources/api_resource_test.rb diff --git a/lib/emailable/resources/api_resource.rb b/lib/emailable/resources/api_resource.rb index 1cbc33d..c10f7c8 100644 --- a/lib/emailable/resources/api_resource.rb +++ b/lib/emailable/resources/api_resource.rb @@ -1,3 +1,5 @@ +require 'json' + module Emailable class APIResource @@ -7,14 +9,22 @@ def initialize(attributes = {}) end end - def inspect - ivars = instance_variables.map do |e| - [e.to_s.delete('@'), instance_variable_get(e)] + def to_h + instance_variables.map do |e| + [e.to_s.delete('@').to_sym, instance_variable_get(e)] end.to_h + end + + alias_method :to_hash, :to_h + + def to_json + JSON.generate(to_h) + end + + def inspect fmtted_email = @email ? " #{@email}" : '' "#<#{self.class}:0x#{(object_id << 1).to_s(16)}#{fmtted_email}> JSON: " + - JSON.pretty_generate(ivars) + JSON.pretty_generate(to_h) end - end end diff --git a/test/emailable/resources/api_resource_test.rb b/test/emailable/resources/api_resource_test.rb new file mode 100644 index 0000000..768b9bd --- /dev/null +++ b/test/emailable/resources/api_resource_test.rb @@ -0,0 +1,46 @@ +require 'test_helper' + +module Emailable + class BatchTest < Minitest::Test + class Example < APIResource + attr_accessor :foo, :bar, :baz + end + + def setup + @e = Example.new(foo: 'abc', bar: 123, baz: true) + end + + def test_init + assert_equal 'abc', @e.foo + assert_equal 123, @e.bar + assert_equal true, @e.baz + end + + def test_to_h + correct = { + foo: 'abc', + bar: 123, + baz: true, + } + assert_equal correct, @e.to_h + assert_equal correct, @e.to_hash + end + + def test_to_json + correct = %q|{"foo":"abc","bar":123,"baz":true}| + assert_equal correct, @e.to_json + end + + def test_inspect + correct = <<~STR.chomp + #<> JSON: { + "foo": "abc", + "bar": 123, + "baz": true + } + STR + output = @e.inspect.gsub(/<.*>/, '<>') + assert_equal correct, output + end + end +end From b92504c532da07af81b7671ec2b554d7dda6aa98 Mon Sep 17 00:00:00 2001 From: Jarrett Lusso Date: Tue, 23 Nov 2021 15:49:49 -0500 Subject: [PATCH 2/6] Fixed error handling to be more standard. Fixed bin/console that didn't work properly. Improved tests to not load active_record except where needed. Added requires for json and net/http that are needed in plain ruby environments. --- Gemfile.lock | 2 +- bin/console | 8 ++++---- lib/emailable.rb | 26 +++++--------------------- lib/emailable/client.rb | 27 +++++++++++---------------- lib/emailable/errors.rb | 12 ++++++++++++ test/email_validator_test.rb | 1 + test/test_helper.rb | 2 -- 7 files changed, 34 insertions(+), 44 deletions(-) create mode 100644 lib/emailable/errors.rb diff --git a/Gemfile.lock b/Gemfile.lock index 2b88f93..b248658 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - emailable (3.0.2) + emailable (3.1.0) GEM remote: https://rubygems.org/ diff --git a/bin/console b/bin/console index d0f264a..f305ece 100755 --- a/bin/console +++ b/bin/console @@ -1,14 +1,14 @@ #!/usr/bin/env ruby -require "bundler/setup" -require "emailable/ruby" +require 'bundler/setup' +require 'emailable' # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. # (If you use this, don't forget to add pry to your Gemfile!) -# require "pry" +# require 'pry' # Pry.start -require "irb" +require 'irb' IRB.start(__FILE__) diff --git a/lib/emailable.rb b/lib/emailable.rb index c3e698f..577531a 100644 --- a/lib/emailable.rb +++ b/lib/emailable.rb @@ -1,4 +1,8 @@ +require 'net/http' +require 'json' + require 'emailable/version' +require 'emailable/errors' require 'emailable/client' require 'emailable/response' require 'emailable/batch' @@ -33,9 +37,7 @@ def verify(email, smtp: nil, accept_all: nil, timeout: nil) response = client.request(:get, 'verify', opts) if response.status == 249 - raise Emailable::TimeoutError.new( - code: response.status, message: response.body - ) + raise Emailable::TimeoutError.new(response.body) else Verification.new(response.body) end @@ -47,22 +49,4 @@ def account Account.new(response.body) end - - class Error < StandardError - attr_accessor :code, :message - - def initialize(code: nil, message: nil) - @code = code - @message = message - end - end - class BadRequestError < Error; end - class UnauthorizedError < Error; end - class PaymentRequiredError < Error; end - class ForbiddenError < Error; end - class NotFoundError < Error; end - class TooManyRequestsError < Error; end - class InternalServerError < Error; end - class ServiceUnavailableError < Error; end - class TimeoutError < Error; end end diff --git a/lib/emailable/client.rb b/lib/emailable/client.rb index bf5e989..d8218c0 100644 --- a/lib/emailable/client.rb +++ b/lib/emailable/client.rb @@ -1,5 +1,15 @@ module Emailable class Client + ERRORS = { + 400 => BadRequestError, + 401 => UnauthorizedError, + 402 => PaymentRequiredError, + 403 => ForbiddenError, + 404 => NotFoundError, + 429 => TooManyRequestsError, + 500 => InternalServerError, + 503 => ServiceUnavailableError + }.freeze def initialize @base_url = 'https://api.emailable.com/v1' @@ -33,22 +43,7 @@ def request(method, endpoint, params = {}) status = response.status return response if status.between?(200, 299) - error_attributes = { - message: response.body['message'], - code: status - } - error_map = { - '400' => BadRequestError, - '401' => UnauthorizedError, - '402' => PaymentRequiredError, - '403' => ForbiddenError, - '404' => NotFoundError, - '429' => TooManyRequestsError, - '500' => InternalServerError, - '503' => ServiceUnavailableError - } - - raise error_map[status.to_s].new(error_attributes) + raise ERRORS[status].new(response.body['message']) end private diff --git a/lib/emailable/errors.rb b/lib/emailable/errors.rb new file mode 100644 index 0000000..ea76d10 --- /dev/null +++ b/lib/emailable/errors.rb @@ -0,0 +1,12 @@ +module Emailable + class Error < StandardError; end + class BadRequestError < Error; end + class UnauthorizedError < Error; end + class PaymentRequiredError < Error; end + class ForbiddenError < Error; end + class NotFoundError < Error; end + class TooManyRequestsError < Error; end + class InternalServerError < Error; end + class ServiceUnavailableError < Error; end + class TimeoutError < Error; end +end diff --git a/test/email_validator_test.rb b/test/email_validator_test.rb index c0147a7..3ec0422 100644 --- a/test/email_validator_test.rb +++ b/test/email_validator_test.rb @@ -1,3 +1,4 @@ +require 'active_model' require 'test_helper' class EmailValidatorTest < Minitest::Test diff --git a/test/test_helper.rb b/test/test_helper.rb index 1701fa5..1e1c196 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,5 +1,3 @@ -$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__) -require 'active_model' require 'emailable' require 'pry' From 870dbf14d6182c7e4ca595db1e4d5a6fb01d7ecd Mon Sep 17 00:00:00 2001 From: Jarrett Lusso Date: Tue, 23 Nov 2021 16:14:55 -0500 Subject: [PATCH 3/6] Moved inspect with email to verification resource since others won't have it. Also updated test. --- lib/emailable/resources/api_resource.rb | 6 +- lib/emailable/resources/verification.rb | 5 ++ test/emailable/resources/api_resource_test.rb | 73 ++++++++++--------- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/lib/emailable/resources/api_resource.rb b/lib/emailable/resources/api_resource.rb index c10f7c8..3e8167e 100644 --- a/lib/emailable/resources/api_resource.rb +++ b/lib/emailable/resources/api_resource.rb @@ -14,7 +14,7 @@ def to_h [e.to_s.delete('@').to_sym, instance_variable_get(e)] end.to_h end - + alias_method :to_hash, :to_h def to_json @@ -22,9 +22,9 @@ def to_json end def inspect - fmtted_email = @email ? " #{@email}" : '' - "#<#{self.class}:0x#{(object_id << 1).to_s(16)}#{fmtted_email}> JSON: " + + "#<#{self.class}:0x#{(object_id << 1).to_s(16)}> JSON: " + JSON.pretty_generate(to_h) end + end end diff --git a/lib/emailable/resources/verification.rb b/lib/emailable/resources/verification.rb index 30bd069..297b49f 100644 --- a/lib/emailable/resources/verification.rb +++ b/lib/emailable/resources/verification.rb @@ -11,5 +11,10 @@ class Verification < APIResource end end + def inspect + "#<#{self.class}:0x#{(object_id << 1).to_s(16)}#{@email}> JSON: " + + JSON.pretty_generate(to_h) + end + end end diff --git a/test/emailable/resources/api_resource_test.rb b/test/emailable/resources/api_resource_test.rb index 768b9bd..69d9054 100644 --- a/test/emailable/resources/api_resource_test.rb +++ b/test/emailable/resources/api_resource_test.rb @@ -1,46 +1,49 @@ require 'test_helper' module Emailable - class BatchTest < Minitest::Test - class Example < APIResource - attr_accessor :foo, :bar, :baz - end + module Resources + class APIResourceTest < Minitest::Test + class Example < APIResource + attr_accessor :foo, :bar, :baz + end - def setup - @e = Example.new(foo: 'abc', bar: 123, baz: true) - end + def setup + @e = Example.new(foo: 'abc', bar: 123, baz: true) + end - def test_init - assert_equal 'abc', @e.foo - assert_equal 123, @e.bar - assert_equal true, @e.baz - end + def test_init + assert_equal 'abc', @e.foo + assert_equal 123, @e.bar + assert_equal true, @e.baz + end - def test_to_h - correct = { - foo: 'abc', - bar: 123, - baz: true, - } - assert_equal correct, @e.to_h - assert_equal correct, @e.to_hash - end + def test_to_h + correct = { + foo: 'abc', + bar: 123, + baz: true, + } + assert_equal correct, @e.to_h + assert_equal correct, @e.to_hash + end - def test_to_json - correct = %q|{"foo":"abc","bar":123,"baz":true}| - assert_equal correct, @e.to_json - end + def test_to_json + correct = %q|{"foo":"abc","bar":123,"baz":true}| + assert_equal correct, @e.to_json + end - def test_inspect - correct = <<~STR.chomp - #<> JSON: { - "foo": "abc", - "bar": 123, - "baz": true - } - STR - output = @e.inspect.gsub(/<.*>/, '<>') - assert_equal correct, output + def test_inspect + correct = <<~STR.chomp + #<> JSON: { + "foo": "abc", + "bar": 123, + "baz": true + } + STR + output = @e.inspect.gsub(/<.*>/, '<>') + assert_equal correct, output + end end + end end From 33ee3fcc21ba9b26d6b80e638aafbb254257f7ec Mon Sep 17 00:00:00 2001 From: Jarrett Lusso Date: Tue, 23 Nov 2021 16:15:36 -0500 Subject: [PATCH 4/6] Updated travis url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6e73cc..77c9b09 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Emailable Ruby Library -[![Build Status](https://app.travis-ci.com/emailable/emailable-ruby.svg)](https://travis-ci.com/emailable/emailable-ruby) +[![Build Status](https://app.travis-ci.com/emailable/emailable-ruby.svg)](https://app.travis-ci.com/emailable/emailable-ruby) [![Maintainability](https://api.codeclimate.com/v1/badges/e7eef54e491adec95e6d/maintainability)](https://codeclimate.com/github/emailable/emailable-ruby/maintainability) This is the official ruby wrapper for the Emailable API. From d72adf113e9b9bca93d50530fefa8b7b019f799b Mon Sep 17 00:00:00 2001 From: Jarrett Lusso Date: Tue, 23 Nov 2021 16:17:32 -0500 Subject: [PATCH 5/6] Removed unecessary require --- lib/emailable/resources/api_resource.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/emailable/resources/api_resource.rb b/lib/emailable/resources/api_resource.rb index 3e8167e..6906575 100644 --- a/lib/emailable/resources/api_resource.rb +++ b/lib/emailable/resources/api_resource.rb @@ -1,5 +1,3 @@ -require 'json' - module Emailable class APIResource From a659398b33002f4cc0e70a5387c49454b7344358 Mon Sep 17 00:00:00 2001 From: Jarrett Lusso Date: Tue, 23 Nov 2021 16:21:06 -0500 Subject: [PATCH 6/6] 3.1.1 --- Gemfile.lock | 2 +- lib/emailable/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b248658..83d2a49 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - emailable (3.1.0) + emailable (3.1.1) GEM remote: https://rubygems.org/ diff --git a/lib/emailable/version.rb b/lib/emailable/version.rb index fd528c5..01388e1 100644 --- a/lib/emailable/version.rb +++ b/lib/emailable/version.rb @@ -1,3 +1,3 @@ module Emailable - VERSION = '3.1.0' + VERSION = '3.1.1' end