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
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ Naming/PredicatePrefix:

Metrics/ParameterLists:
Exclude:
- 'packages/forest_admin_datasource_zendesk/lib/forest_admin_datasource_zendesk/collections/base_collection.rb'
- 'packages/forest_admin_datasource_snowflake/lib/forest_admin_datasource_snowflake/datasource.rb'
- 'packages/forest_admin_agent/lib/forest_admin_agent/routes/query_handler.rb'
- 'packages/forest_admin_agent/lib/forest_admin_agent/services/smart_action_checker.rb'
Expand Down Expand Up @@ -347,6 +348,7 @@ Metrics/BlockLength:

Metrics/ClassLength:
Exclude:
- 'packages/forest_admin_datasource_zendesk/lib/forest_admin_datasource_zendesk/collections/base_collection.rb'
- 'packages/forest_admin_datasource_snowflake/lib/forest_admin_datasource_snowflake/collection.rb'
- 'packages/forest_admin_datasource_snowflake/lib/forest_admin_datasource_snowflake/datasource.rb'
- 'packages/forest_admin_datasource_snowflake/lib/forest_admin_datasource_snowflake/utils/query.rb'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@ class BaseCollection < ForestAdminDatasourceToolkit::Collection
DATE_OPS = [Operators::EQUAL, Operators::BEFORE, Operators::AFTER,
Operators::PRESENT, Operators::BLANK].freeze

attr_reader :custom_fields

# Template method: subclasses implement `define_schema` and
# `define_relations` as hooks; ordering between them, custom-field
# registration, and the search/count flags is owned here so collisions
# are always evaluated against the final native schema. A subclass can
# opt out of search/count by passing `searchable: false` / `countable:
# false` through `super`.
def initialize(datasource, name, custom_fields: [], searchable: true, countable: true, native_driver: nil)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Function with many parameters (count = 6): initialize [qlty:function-parameters]

super(datasource, name, native_driver)
define_schema
define_relations
@custom_fields = add_custom_fields(custom_fields)
enable_search if searchable
enable_count if countable
end

def aggregate(caller, filter, aggregation, _limit = nil)
unless aggregation.operation == 'Count' && aggregation.field.nil? && aggregation.groups.empty?
raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
Expand Down Expand Up @@ -97,7 +114,7 @@ def build_zendesk_query(caller, filter)

# Adds custom fields, skipping any whose column name collides with a
# field already declared on the collection (native column or relation).
# Returns the list of fields actually added so callers can keep their
# Returns the subset actually added so callers can keep their
# serializer in sync with the schema.
def add_custom_fields(custom_fields)
custom_fields.reject do |cf|
Expand All @@ -117,6 +134,9 @@ def add_custom_fields(custom_fields)

private

def define_schema = raise(NotImplementedError, "#{self.class} did not implement define_schema")
def define_relations = raise(NotImplementedError, "#{self.class} did not implement define_relations")

def sort_field_and_direction(entry)
return [entry.field, entry.ascending] if entry.respond_to?(:field)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ module Collections
class Organization < BaseCollection
include Searchable

attr_reader :custom_fields

OneToManySchema = ForestAdminDatasourceToolkit::Schema::Relations::OneToManySchema

ZENDESK_SORTABLE = {
Expand All @@ -14,12 +12,7 @@ class Organization < BaseCollection
}.freeze

def initialize(datasource, custom_fields: [])
super(datasource, 'ZendeskOrganization')
define_schema
define_relations
@custom_fields = add_custom_fields(custom_fields)
enable_search
enable_count
super(datasource, 'ZendeskOrganization', custom_fields: custom_fields)
end

def create(_caller, data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ class Ticket < BaseCollection
include CommentsEmbedder
include Serializer

attr_reader :custom_fields

ManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema

ZENDESK_SORTABLE = {
Expand All @@ -29,12 +27,7 @@ class Ticket < BaseCollection
}.freeze

def initialize(datasource, custom_fields: [])
super(datasource, 'ZendeskTicket')
define_schema
define_relations
@custom_fields = add_custom_fields(custom_fields)
enable_search
enable_count
super(datasource, 'ZendeskTicket', custom_fields: custom_fields)
end

def list(caller, filter, projection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ module Collections
class User < BaseCollection
include Searchable

attr_reader :custom_fields

ManyToOneSchema = ForestAdminDatasourceToolkit::Schema::Relations::ManyToOneSchema
OneToManySchema = ForestAdminDatasourceToolkit::Schema::Relations::OneToManySchema
ENUM_ROLE = %w[end-user agent admin].freeze
Expand All @@ -18,12 +16,7 @@ class User < BaseCollection
}.freeze

def initialize(datasource, custom_fields: [])
super(datasource, 'ZendeskUser')
define_schema
define_relations
@custom_fields = add_custom_fields(custom_fields)
enable_search
enable_count
super(datasource, 'ZendeskUser', custom_fields: custom_fields)
end

def create(_caller, data)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module ForestAdminDatasourceZendesk
RSpec.describe Collections::BaseCollection do
let(:datasource) do
instance_double(ForestAdminDatasourceZendesk::Datasource,
client: instance_double(ForestAdminDatasourceZendesk::Client),
custom_field_mapping: {})
end

describe 'subclass contract' do
it 'raises NotImplementedError naming define_schema when the hook is missing' do
subclass = Class.new(described_class)
expect { subclass.new(datasource, 'X') }
.to raise_error(NotImplementedError, /define_schema/)
end

it 'raises NotImplementedError naming define_relations when only define_schema is implemented' do
subclass = Class.new(described_class) { def define_schema; end }
expect { subclass.new(datasource, 'X') }
.to raise_error(NotImplementedError, /define_relations/)
end
end

describe 'search/count opt-out' do
let(:subclass) do
Class.new(described_class) do
def define_schema; end
def define_relations; end
end
end

it 'enables search and count by default' do
collection = subclass.new(datasource, 'X')
expect(collection.is_searchable?).to be(true)
expect(collection.is_countable?).to be(true)
end

it 'honours searchable: false / countable: false from super' do
collection = subclass.new(datasource, 'X', searchable: false, countable: false)
expect(collection.is_searchable?).to be(false)
expect(collection.is_countable?).to be(false)
end
end
end
end
Loading