diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98113990..d18e31b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rubyversion: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3'] + rubyversion: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4'] steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 @@ -35,7 +35,7 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: '3.4' rubygems: '3.3.0' bundler-cache: true - name: Install Dependencies @@ -51,7 +51,7 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: '3.4' rubygems: '3.3.0' bundler-cache: true - name: Install Dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e96e1a4c..0a27f705 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: '3.4' rubygems: '3.3.0' bundler-cache: true - name: Build Package diff --git a/CHANGELOG.md b/CHANGELOG.md index 105020f2..7bbf4b5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ # CHANGELOG -## Next Release +## Next Release (minor) +- Adds Ruby 3.4 support +- Corrects the HTTP verb for updating a brand from `GET` to `PATCH` - Removes the deprecated `create_list` tracker endpoint function as it is no longer available via API ## v6.4.1 (2024-08-09) diff --git a/easypost.gemspec b/easypost.gemspec index 55593c25..8397a057 100644 --- a/easypost.gemspec +++ b/easypost.gemspec @@ -21,8 +21,13 @@ Gem::Specification.new do |spec| spec.require_paths = ['lib'] spec.required_ruby_version = '>= 2.6' + spec.add_development_dependency 'abbrev', '~> 0.1' + spec.add_development_dependency 'benchmark', '~> 0.4' + spec.add_development_dependency 'bigdecimal', '~> 3' spec.add_development_dependency 'brakeman', '~> 5.4' spec.add_development_dependency 'faraday', '~> 2.7.5' # used for integration tests + spec.add_development_dependency 'logger', '~> 1' + spec.add_development_dependency 'ostruct', '~> 0.6' spec.add_development_dependency 'pry', '~> 0.14' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rdoc', '~> 6.9' diff --git a/examples b/examples index 0492e408..7669825f 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 0492e408e1b37b2ec18bcb4a4d228ab0f458f59d +Subproject commit 7669825fb53be074d7f585c78c4f38ad4fefe0d0 diff --git a/lib/easypost/services/user.rb b/lib/easypost/services/user.rb index 1703ec94..063643cc 100644 --- a/lib/easypost/services/user.rb +++ b/lib/easypost/services/user.rb @@ -74,7 +74,7 @@ def api_keys(id) # Update the Brand of a User. def update_brand(id, params = {}) wrapped_params = { brand: params } - response = @client.make_request(:get, "users/#{id}/brand", wrapped_params) + response = @client.make_request(:patch, "users/#{id}/brand", wrapped_params) EasyPost::InternalUtilities::Json.convert_json_to_object(response, EasyPost::Models::Brand) end diff --git a/spec/cassettes/user/EasyPost_Services_User_update_brand_updates_the_authenticated_user_s_brand.yml b/spec/cassettes/user/EasyPost_Services_User_update_brand_updates_the_authenticated_user_s_brand.yml index bac5e30e..15fcc4a4 100644 --- a/spec/cassettes/user/EasyPost_Services_User_update_brand_updates_the_authenticated_user_s_brand.yml +++ b/spec/cassettes/user/EasyPost_Services_User_update_brand_updates_the_authenticated_user_s_brand.yml @@ -35,7 +35,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7b66a7db36e799e564005a6356 + - 16a5647b67af85a2e787377a0053832a Cache-Control: - private, no-cache, no-store Pragma: @@ -45,18 +45,18 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.140684' + - '0.229489' Transfer-Encoding: - chunked X-Node: - - bigweb39nuq + - bigweb33nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502132348-e5a3dc472b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb3nuq c0f5e722d1 + - extlb2nuq 99aac35317 + - intlb3nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: @@ -71,14 +71,20 @@ http_interactions: User","phone_number":"8005550100","verified":true,"created_at":"2024-07-26T19:08:21Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_acfa6f7268d14e449edd1fe6f4ab64cc","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T17:41:32Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_4b066506d76940aeb28943506eb76941","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T17:46:31Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_48b7c8e5981647a8aee52aa1cb910280","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test - User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T18:07:19Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]}]}' - recorded_at: Mon, 29 Jul 2024 18:11:02 GMT + User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T18:07:19Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_dc18fb938f184bfd8f345d7fb1469130","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test + User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T21:45:16Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_06004d67f8294a73b2a21b62d5a2e3d6","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test + User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T21:50:35Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_b760795a35e24bfc803b51b29cca0d7e","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test + User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T21:59:34Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_a2e569dd62f14b75b2f8c84aa62ded62","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test + User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T22:03:04Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_85480046d6514ea3863eb950fbea392e","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test + User","phone_number":"8005550100","verified":true,"created_at":"2024-07-29T22:04:22Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]},{"id":"user_89583592d7914082b3b61fdf9230db38","object":"User","parent_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d","name":"Test + User","phone_number":"8005550100","verified":true,"created_at":"2024-08-01T17:06:15Z","default_carbon_offset":false,"has_elevate_access":false,"children":[]}]}' + recorded_at: Fri, 14 Feb 2025 18:04:18 GMT - request: - method: get - uri: https://api.easypost.com/v2/users/user_0f6b83e3530b401cb1e8aeaa6a250d4d/brand?brand=%7B:color=%3E%22%23123456%22%7D + method: patch + uri: https://api.easypost.com/v2/users/user_0f6b83e3530b401cb1e8aeaa6a250d4d/brand body: - encoding: US-ASCII - string: '' + encoding: UTF-8 + string: '{"brand":{"color":"#123456"}}' headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -108,7 +114,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7466a7db37e799e566005a63f6 + - 16a5647e67af85a2e787377d005383ac Cache-Control: - private, no-cache, no-store Pragma: @@ -118,22 +124,22 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.090249' + - '0.101178' Transfer-Encoding: - chunked X-Node: - - bigweb33nuq + - bigweb54nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502132348-e5a3dc472b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb4nuq c0f5e722d1 + - extlb2nuq 99aac35317 + - intlb4nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: encoding: UTF-8 string: '{"ad":null,"ad_href":null,"background_color":null,"color":"#123456","id":"brd_136abcc3c9de49fcb1a0e963f26fdcac","logo":"https://assets.easypost.com/assets/images/branding/easypost-primary-logo.7324aa54b64b34d6cd70ca5ba4d1842d.svg","logo_href":"https://www.easypost.com","name":"EasyPost","object":"Brand","theme":"theme1","user_id":"user_0f6b83e3530b401cb1e8aeaa6a250d4d"}' - recorded_at: Mon, 29 Jul 2024 18:11:03 GMT -recorded_with: VCR 6.1.0 + recorded_at: Fri, 14 Feb 2025 18:04:18 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/cassettes/webhook/EasyPost_Services_Webhook_create_creates_a_webhook.yml b/spec/cassettes/webhook/EasyPost_Services_Webhook_create_creates_a_webhook.yml index 93eb70ac..75e0e41b 100644 --- a/spec/cassettes/webhook/EasyPost_Services_Webhook_create_creates_a_webhook.yml +++ b/spec/cassettes/webhook/EasyPost_Services_Webhook_create_creates_a_webhook.yml @@ -5,7 +5,7 @@ http_interactions: uri: https://api.easypost.com/v2/webhooks body: encoding: UTF-8 - string: '{"webhook":{"url":"http://example.com"}}' + string: '{"webhook":{"url":"http://example.com","webhook_secret":"sécret","custom_headers":[{"name":"test","value":"header"}]}}' headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -35,7 +35,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7866a7db38e799e581005a65cd + - 4b64bb4d67b62818e2b8ff700009ab69 Cache-Control: - private, no-cache, no-store Pragma: @@ -45,27 +45,27 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.195541' + - '0.426072' Transfer-Encoding: - chunked X-Node: - - bigweb38nuq + - bigweb36nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502191732-9cdc8ea15b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb4nuq c0f5e722d1 + - extlb1nuq 99aac35317 + - intlb3nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: encoding: UTF-8 - string: '{"id":"hook_eba4eaf24dd511efa52d5d09a9f2573c","object":"Webhook","mode":"test","url":"http://example.com","created_at":"2024-07-29T18:11:05Z","disabled_at":null}' - recorded_at: Mon, 29 Jul 2024 18:11:04 GMT + string: '{"id":"hook_78e7a450eef211ef927d05e2cbdc7978","object":"Webhook","mode":"test","url":"http://example.com","created_at":"2025-02-19T18:51:05Z","disabled_at":null,"custom_headers":[{"name":"test","value":"header"}]}' + recorded_at: Wed, 19 Feb 2025 18:51:05 GMT - request: method: delete - uri: https://api.easypost.com/v2/webhooks/hook_eba4eaf24dd511efa52d5d09a9f2573c + uri: https://api.easypost.com/v2/webhooks/hook_78e7a450eef211ef927d05e2cbdc7978 body: encoding: US-ASCII string: '' @@ -98,7 +98,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7966a7db39e799e582005a6689 + - 3c3ed33267b62819e2b8ff720008eb31 Cache-Control: - private, no-cache, no-store Pragma: @@ -108,22 +108,22 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.370557' + - '0.241701' Transfer-Encoding: - chunked X-Node: - - bigweb35nuq + - bigweb33nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502191732-9cdc8ea15b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb4nuq c0f5e722d1 + - extlb2nuq 99aac35317 + - intlb3nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: encoding: UTF-8 string: "{}" - recorded_at: Mon, 29 Jul 2024 18:11:05 GMT -recorded_with: VCR 6.1.0 + recorded_at: Wed, 19 Feb 2025 18:51:05 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/cassettes/webhook/EasyPost_Services_Webhook_update_updates_a_webhook.yml b/spec/cassettes/webhook/EasyPost_Services_Webhook_update_updates_a_webhook.yml index 1cb8ce6a..7c1b2df7 100644 --- a/spec/cassettes/webhook/EasyPost_Services_Webhook_update_updates_a_webhook.yml +++ b/spec/cassettes/webhook/EasyPost_Services_Webhook_update_updates_a_webhook.yml @@ -35,7 +35,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7666a7db3ce799e587005a69a5 + - 4b64bb5067b6283ae2b8ffd60009d020 Cache-Control: - private, no-cache, no-store Pragma: @@ -45,30 +45,30 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.180870' + - '0.109819' Transfer-Encoding: - chunked X-Node: - - bigweb36nuq + - bigweb35nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502191732-9cdc8ea15b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb3nuq c0f5e722d1 + - extlb1nuq 99aac35317 + - intlb3nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: encoding: UTF-8 - string: '{"id":"hook_edd8938c4dd511ef8af45962431e1651","object":"Webhook","mode":"test","url":"http://example.com","created_at":"2024-07-29T18:11:09Z","disabled_at":null}' - recorded_at: Mon, 29 Jul 2024 18:11:08 GMT + string: '{"id":"hook_8cbab03aeef211efabe53931f5ecc7b8","object":"Webhook","mode":"test","url":"http://example.com","created_at":"2025-02-19T18:51:38Z","disabled_at":null,"custom_headers":[]}' + recorded_at: Wed, 19 Feb 2025 18:51:38 GMT - request: method: patch - uri: https://api.easypost.com/v2/webhooks/hook_edd8938c4dd511ef8af45962431e1651 + uri: https://api.easypost.com/v2/webhooks/hook_8cbab03aeef211efabe53931f5ecc7b8 body: encoding: UTF-8 - string: "{}" + string: '{"webhook_secret":"sécret","custom_headers":[{"name":"test","value":"header"}]}' headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 @@ -98,7 +98,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7666a7db3de799e59f005a6a43 + - 4b64bb5067b6283ae2b8ffd90009d056 Cache-Control: - private, no-cache, no-store Pragma: @@ -108,27 +108,27 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.489107' + - '0.609185' Transfer-Encoding: - chunked X-Node: - - bigweb53nuq + - bigweb58nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502191732-9cdc8ea15b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb3nuq c0f5e722d1 + - extlb1nuq 99aac35317 + - intlb4nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: encoding: UTF-8 - string: '{"id":"hook_edd8938c4dd511ef8af45962431e1651","object":"Webhook","mode":"test","url":"http://example.com","created_at":"2024-07-29T18:11:09Z","disabled_at":null}' - recorded_at: Mon, 29 Jul 2024 18:11:09 GMT + string: '{"id":"hook_8cbab03aeef211efabe53931f5ecc7b8","object":"Webhook","mode":"test","url":"http://example.com","created_at":"2025-02-19T18:51:38Z","disabled_at":null,"custom_headers":[{"name":"test","value":"header"}]}' + recorded_at: Wed, 19 Feb 2025 18:51:38 GMT - request: method: delete - uri: https://api.easypost.com/v2/webhooks/hook_edd8938c4dd511ef8af45962431e1651 + uri: https://api.easypost.com/v2/webhooks/hook_8cbab03aeef211efabe53931f5ecc7b8 body: encoding: US-ASCII string: '' @@ -161,7 +161,7 @@ http_interactions: Referrer-Policy: - strict-origin-when-cross-origin X-Ep-Request-Uuid: - - d044fa7966a7db3de799e5a1005a6b23 + - 4b64bb4e67b6283be2b8ffdc0009d11a Cache-Control: - private, no-cache, no-store Pragma: @@ -171,22 +171,22 @@ http_interactions: Content-Type: - application/json; charset=utf-8 X-Runtime: - - '0.338752' + - '0.304757' Transfer-Encoding: - chunked X-Node: - - bigweb38nuq + - bigweb33nuq X-Version-Label: - - easypost-202407291746-57ea285141-master + - easypost-202502191732-9cdc8ea15b-master X-Backend: - easypost X-Proxied: - - extlb1nuq fa152d4755 - - intlb4nuq c0f5e722d1 + - extlb1nuq 99aac35317 + - intlb3nuq 51d74985a2 Strict-Transport-Security: - max-age=31536000; includeSubDomains; preload body: encoding: UTF-8 string: "{}" - recorded_at: Mon, 29 Jul 2024 18:11:10 GMT -recorded_with: VCR 6.1.0 + recorded_at: Wed, 19 Feb 2025 18:51:39 GMT +recorded_with: VCR 6.2.0 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9101fdb8..04f27e0c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -61,7 +61,7 @@ def create_and_insure_shipment(client, amount) def check_expired_cassette(cassette_path) full_cassette_path = "#{"spec/cassettes/#{cassette_path}".gsub('::', '_').gsub(' ', '_').gsub('.', '_')}.yml" seconds_in_day = 86_400 - expiration_days = 180 + expiration_days = 365 expiration_seconds = seconds_in_day * expiration_days return unless File.exist?(full_cassette_path) diff --git a/spec/support/fixture.rb b/spec/support/fixture.rb index e081ce06..7edbe4ff 100644 --- a/spec/support/fixture.rb +++ b/spec/support/fixture.rb @@ -129,15 +129,19 @@ def self.event_bytes end def self.webhook_hmac_signature - read_fixture_data['webhook_hmac_signature'] + read_fixture_data['webhooks']['hmac_signature'] end def self.webhook_secret - read_fixture_data['webhook_secret'] + read_fixture_data['webhooks']['secret'] end def self.webhook_url - read_fixture_data['webhook_url'] + read_fixture_data['webhooks']['url'] + end + + def self.webhook_custom_headers + read_fixture_data['webhooks']['custom_headers'] end # The credit card details below are for a valid proxy card usable diff --git a/spec/user_spec.rb b/spec/user_spec.rb index 999f4bb3..193073b5 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -71,7 +71,7 @@ brand = client.user.update_brand( user.id, - color: color, + { color: color }, ) expect(brand).to be_an_instance_of(EasyPost::Models::Brand) diff --git a/spec/webhook_spec.rb b/spec/webhook_spec.rb index b77c2c81..3cfef98e 100644 --- a/spec/webhook_spec.rb +++ b/spec/webhook_spec.rb @@ -9,11 +9,15 @@ it 'creates a webhook' do webhook = client.webhook.create( url: Fixture.webhook_url, + webhook_secret: Fixture.webhook_secret, + custom_headers: Fixture.webhook_custom_headers, ) expect(webhook).to be_an_instance_of(EasyPost::Models::Webhook) expect(webhook.id).to match('hook_') expect(webhook.url).to eq(Fixture.webhook_url) + expect(webhook.custom_headers[0].name).to eq('test') + expect(webhook.custom_headers[0].value).to eq('header') # Remove the webhook once we have tested it so we don't pollute the account with test webhooks client.webhook.delete(webhook.id) @@ -55,9 +59,16 @@ url: Fixture.webhook_url, ) - updated_webhook = client.webhook.update(webhook.id) + updated_webhook = client.webhook.update( + webhook.id, { + webhook_secret: Fixture.webhook_secret, + custom_headers: Fixture.webhook_custom_headers, + }, + ) expect(updated_webhook).to be_an_instance_of(EasyPost::Models::Webhook) + expect(updated_webhook.custom_headers[0].name).to eq('test') + expect(updated_webhook.custom_headers[0].value).to eq('header') client.webhook.delete(webhook.id) # Remove the webhook once we have tested it so we don't pollute the account with test webhooks end