Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci_steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
name: "Frederick API Gem CI"
on:
push:
branches: [master]
branches: [master]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
RUBY_VERSION: 2.4.3
RUBY_VERSION: 3.3.10
DOCKER: true
RAILS_ENV: test

Expand Down
89 changes: 66 additions & 23 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
# Enable rubocop todos to go through them one by one
# For how to get started with rubocop, see: https://buildtoship.com/integrate-rubocop-in-your-workflow/

require:
plugins:
- rubocop-rspec

AllCops:
TargetRubyVersion: 2.3
NewCops: disable
SuggestExtensions: false
TargetRubyVersion: 3.3.10
# Cop names are not displayed in offense messages by default. Change behavior
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
# option.
Expand Down Expand Up @@ -42,15 +44,17 @@ RSpec/NestedGroups:
Metrics/MethodLength:
Max: 20

Metrics/LineLength:
Layout/LineLength:
Max: 120
Exclude:
- 'spec/**/*'

Layout/MultilineMethodCallIndentation:
Exclude:
- 'spec/**/*'

# Checks the indentation of the first element in an array literal.
Layout/IndentArray:
Layout/FirstArrayElementIndentation:
Enabled: false

# Cop supports --auto-correct.
Expand All @@ -65,13 +69,7 @@ Layout/MultilineOperationIndentation:
EnforcedStyle: indented

Layout/IndentationConsistency:
# The difference between `rails` and `normal` is that the `rails` style
# prescribes that in classes and modules the `protected` and `private`
# modifier keywords shall be indented the same as public methods and that
# protected and private members shall be indented one step more than the
# modifiers. Other than that, both styles mean that entities on the same
# logical depth shall have the same indentation.
EnforcedStyle: rails
EnforcedStyle: indented_internal_methods

# Document classes and non-namespace modules.
Style/Documentation:
Expand All @@ -82,10 +80,6 @@ Style/Documentation:

# Cop supports --auto-correct.
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
Lint/UnusedMethodArgument:
Exclude:
- 'config/initializers/sidekiq.rb'

Layout/EmptyLinesAroundAccessModifier:
Enabled: false

Expand All @@ -102,17 +96,13 @@ Style/ClassAndModuleChildren:
RSpec/AnyInstance:
Enabled: false

# Configuration parameters: Max.
RSpec/ExampleLength:
Max: 10

Style/PredicateName:
Naming/PredicatePrefix:
Enabled: false


################################## EXCLUDED ##################################

Style/AccessorMethodName:
Naming/AccessorMethodName:
Exclude:
- 'app/controllers/api/v1/api_controller.rb'

Expand All @@ -129,40 +119,93 @@ RSpec/DescribeClass:
Exclude:
- 'spec/lib/tasks/**/*'
- 'spec/integration/*.rb'

RSpec/DescribedClass:
Exclude:
- '**/*'
Style/TrailingCommaInLiteral:

Style/TrailingCommaInArrayLiteral:
Exclude:
- 'spec/**/*'
- 'app/**/*'
- '**/*'

Style/TrailingCommaInHashLiteral:
Exclude:
- 'spec/**/*'
- 'app/**/*'
- '**/*'

Style/TrailingCommaInArguments:
Exclude:
- 'spec/**/*'
- 'app/**/*'
- '**/*'

Style/FrozenStringLiteralComment:
Exclude:
- 'app/views/*'

RSpec/MessageExpectation:
Exclude:
- 'spec/**/*'
RSpec/FilePath:

RSpec/SpecFilePathFormat:
Exclude:
- 'spec/**/*'

RSpec/SpecFilePathSuffix:
Exclude:
- 'spec/**/*'

RSpec/MultipleExpectations:
Exclude:
- 'spec/**/*'

RSpec/ExampleLength:
Exclude:
- 'spec/**/*'
- '**/*'

Metrics/ModuleLength:
Exclude:
- '**/*'

Metrics/BlockLength:
Exclude:
- 'spec/**/*'

RSpec/MessageSpies:
Enabled: false

RSpec/MultipleMemoizedHelpers:
Enabled: false

RSpec/ContextWording:
Enabled: false

RSpec/ExpectInHook:
Enabled: false

RSpec/StubbedMock:
Enabled: false

RSpec/RepeatedExampleGroupBody:
Enabled: false

RSpec/RepeatedExampleGroupDescription:
Enabled: false

Lint/ConstantDefinitionInBlock:
Exclude:
- 'spec/**/*'

RSpec/IndexedLet:
Enabled: false

RSpec/IdenticalEqualityAssertion:
Enabled: false

Naming/VariableNumber:
Exclude:
- 'spec/**/*'
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-2.4.3
ruby-3.3.10
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:2.7.0
FROM ruby:3.3.10

WORKDIR /frederick_api_gem
ADD Gemfile /frederick_api_gem
Expand Down
6 changes: 3 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ gemspec

group :development, :test do
gem 'bundler'
gem 'byebug'
gem 'debug'
gem 'rake'
gem 'rspec'
gem 'rubocop', '0.49.1', require: false
gem 'rubocop-rspec', '1.15.1', require: false
gem 'rubocop', require: false
gem 'rubocop-rspec', require: false
gem 'webmock'
gem 'yard'
end
6 changes: 3 additions & 3 deletions frederick_api.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# coding: utf-8
# frozen_string_literal: true

lib = File.expand_path('../lib', __FILE__)
lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'frederick_api/version'

Expand All @@ -10,12 +9,13 @@ Gem::Specification.new do |spec|
spec.version = FrederickAPI::VERSION
spec.authors = ['Frederick Engineering']
spec.email = ['tech@hirefrederick.com']
spec.required_ruby_version = '>= 3.3.10'

spec.summary = 'Frederick API Client'
spec.description = 'Ruby client for the Frederick API'
spec.homepage = 'https://github.com/HireFrederick/frederick_api_gem'
spec.licenses = ['MIT']
spec.files = Dir['{lib}/**/*', 'README.md', 'MIT-LICENSE']
spec.require_paths = ['lib']
spec.add_runtime_dependency 'json_api_client', '~> 1.17.1'
spec.add_runtime_dependency 'json_api_client', '~> 1.23.0'
end
3 changes: 2 additions & 1 deletion lib/frederick_api/v2/errors/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ class Error < JsonApiClient::Errors::ClientError
attr_reader :errors

# Initialize with a JsonApiClient::ResultSet or a Resource
def initialize(result)
def initialize(result) # rubocop:disable Lint/MissingSuper
# @env is used in base class JsonApiClient::Errors::Error
@env = result
@errors = result.errors || []
end

def to_s
return "Client Error: #{self.errors.first['detail']}" if self.errors.any?

super
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/frederick_api/v2/helpers/backgroundable_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class BackgroundableParser < ::JsonApiClient::Parsers::Parser
def self.parse(klass, response)
result_set = super(klass, response)
return result_set unless result_set&.first&.type == 'background_jobs'

result_set = super(::FrederickAPI::V2::BackgroundJob, response)
result_set&.first&.response = { headers: response.headers, status: response.status }
result_set
Expand Down
9 changes: 5 additions & 4 deletions lib/frederick_api/v2/helpers/paginator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,18 @@ def is_campaign_source?
end

def eligible_page_count
return (total_pages - current_page) unless FrederickAPI.config.emails_per_day_limit_enabled
return total_pages - current_page unless FrederickAPI.config.emails_per_day_limit_enabled

url = first_link
location_id = url.match(%r{locations/([a-f0-9\-]+)/contacts})[1]
location_id = url.match(%r{locations/([a-f0-9-]+)/contacts})[1]
cache_key = "emails_sent_today_#{location_id}"
emails_sent_today = Rails.cache.read(cache_key) || 0
emails_per_day_limit = FrederickAPI.config.emails_per_day_limit
batch_size = FrederickAPI.config.frolodex_batch_fetch_size || 1000
(emails_per_day_limit - emails_sent_today) / batch_size
rescue => e
rescue StandardError => e
NewRelic::Agent.notice_error(e, first_link: first_link)
Comment thread
dhruvasagar-mb marked this conversation as resolved.
0
end

def pages_to_be_fetched
Expand All @@ -95,7 +96,7 @@ def pages_to_be_fetched
# log pages fetched for further analysis.
def nr_log_page_count(page_count)
NewRelic::Agent.record_metric('FrolodexPageFetchCount', page_count)
rescue
rescue StandardError
nil
end

Expand Down
14 changes: 7 additions & 7 deletions lib/frederick_api/v2/helpers/query_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ def _fetch

def _new_scope(opts = {})
self.class.new(@klass,
requestor: requestor,
primary_key: opts.fetch(:primary_key, @primary_key),
requestor: requestor,
primary_key: opts.fetch(:primary_key, @primary_key),
pagination_params: @pagination_params.merge(opts.fetch(:pagination_params, {})),
path_params: @path_params.merge(opts.fetch(:path_params, {})),
path_params: @path_params.merge(opts.fetch(:path_params, {})),
additional_params: @additional_params.merge(opts.fetch(:additional_params, {})),
filters: @filters.merge(opts.fetch(:filters, {})),
includes: @includes + opts.fetch(:includes, []),
orders: @orders + opts.fetch(:orders, []),
fields: @fields + opts.fetch(:fields, []))
filters: @filters.merge(opts.fetch(:filters, {})),
includes: @includes + opts.fetch(:includes, []),
orders: @orders + opts.fetch(:orders, []),
fields: @fields + opts.fetch(:fields, []))
end
end
end
Expand Down
15 changes: 10 additions & 5 deletions lib/frederick_api/v2/helpers/requestor.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'cgi'

module FrederickAPI
module V2
module Helpers
Expand All @@ -21,12 +23,12 @@ class Requestor < JsonApiClient::Query::Requestor
# Paths that may have an unbounded query param length so we should always use a POST
# instead of a GET to get around AWS Cloudfront limitations
GET_VIA_POST_PATHS = [
%r{^.*locations\/[^\/]+\/contacts$},
%r{^.*locations\/[^\/]+\/interactions$}
%r{^.*locations/[^/]+/contacts$},
%r{^.*locations/[^/]+/interactions$}
].map(&:freeze).freeze

def initialize(klass, path = nil)
@klass = klass
super(klass)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you help me understand this change?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, I don't see a need to call the parent class for assigning a variable. I think it would be safer to revert.

@path = path
end

Expand Down Expand Up @@ -68,8 +70,9 @@ def request(type, path, params: nil, body: nil, additional_headers: {})

begin
make_request.call
rescue JsonApiClient::Errors::ConnectionError, JsonApiClient::Errors::ServerError => ex
raise ex if ex.is_a?(JsonApiClient::Errors::NotFound) || ex.is_a?(JsonApiClient::Errors::Conflict)
rescue JsonApiClient::Errors::ConnectionError, JsonApiClient::Errors::ServerError => e
raise e if e.is_a?(JsonApiClient::Errors::NotFound) || e.is_a?(JsonApiClient::Errors::Conflict)

make_request.call
end
end
Expand All @@ -79,12 +82,14 @@ def handle_background(response)
return response unless
(job = response&.first).is_a?(::FrederickAPI::V2::BackgroundJob) && job.status != 'complete'
raise FrederickAPI::V2::Errors::BackgroundJobFailure, job if job.has_errors?

sleep job.retry_after
linked(job.links.attributes['self'])
end

def handle_errors(result)
return result unless result.has_errors?

error_klass = FrederickAPI::V2::Errors::ERROR_CODES[result.errors.first[:status]] ||
FrederickAPI::V2::Errors::Error
raise error_klass, result
Expand Down
Loading