Skip to content

Commit

Permalink
Inline #query, #post, and #get into solr_service from AF
Browse files Browse the repository at this point in the history
refs #3800
  • Loading branch information
hackartisan committed Jun 20, 2019
1 parent 293a62b commit 2ad6778
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
29 changes: 29 additions & 0 deletions app/models/solr_hit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class SolrHit < Delegator
def self.for(hit)
return hit if hit.is_a? ActiveFedora::SolrHit

SolrHit.new(hit)
end

def __getobj__
@document # return object we are delegating to, required
end

alias static_config __getobj__

def __setobj__(obj)
@document = obj
end

attr_reader :document

def initialize(document)
document = document.with_indifferent_access
super
@document = document
end

def id
document[Hyrax.config.id_field]
end
end
41 changes: 40 additions & 1 deletion app/services/hyrax/solr_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Hyrax
class SolrService
extend Forwardable

def_delegators :@old_service, :add, :commit, :count, :delete, :get, :instance, :post, :query
def_delegators :@old_service, :add, :commit, :count, :delete, :instance
def_delegators :instance, :conn

def initialize
Expand All @@ -25,5 +25,44 @@ def select_path

delegate :add, :commit, :count, :delete, :get, :instance, :post, :query, to: :new
end

# Wraps rsolr get
# @return [Hash] the hash straight form rsolr
def get(query, args = {})
args = args.merge(q: query, qt: 'standard')
SolrService.instance.conn.get(Hyrax.config.solr_select_path, params: args)
end

# Wraps rsolr post
# @return [Hash] the hash straight form rsolr
def post(query, args = {})
args = args.merge(q: query, qt: 'standard')
SolrService.instance.conn.post(Hyrax.config.solr_select_path, data: args)
end

# Wraps get by default
# @return [Array<SolrHit>] the response docs wrapped in SolrHit objects
def query(query, args = {})
Rails.logger.warn rows_warning unless args.key?(:rows)
method = args.delete(:method) || :get

result = case method
when :get
get(query, args)
when :post
post(query, args)
else
raise "Unsupported HTTP method for querying SolrService (#{method.inspect})"
end
result['response']['docs'].map do |doc|
::SolrHit.new(doc)
end
end

private

def rows_warning
"Calling Hyrax::SolrService.get without passing an explicit value for ':rows' is not recommended. You will end up with Solr's default (usually set to 10)\nCalled by #{caller[0]}"
end
end
end
9 changes: 9 additions & 0 deletions spec/models/solr_hit_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
RSpec.describe SolrHit do
subject(:solr_hit) { described_class.new "id" => "my:_ID1_" }

describe "#id" do
it "extracts the id from the solr hit" do
expect(solr_hit.id).to eq "my:_ID1_"
end
end
end
60 changes: 60 additions & 0 deletions spec/services/hyrax/solr_service_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,67 @@
RSpec.describe Hyrax::SolrService do
let(:mock_conn) { instance_double(RSolr::Client) }

describe '.select_path' do
it 'raises NotImplementedError' do
expect { described_class.select_path }.to raise_error NotImplementedError
end
end

describe "#get" do
it "calls solr" do
stub_result = double("Result")
expect(mock_conn).to receive(:get).with('select', params: { q: 'querytext', qt: 'standard' }).and_return(stub_result)
allow(described_class).to receive(:instance).and_return(double("instance", conn: mock_conn))
expect(described_class.get('querytext')).to eq stub_result
end
end

describe "#post" do
it "calls solr" do
stub_result = double("Result")
expect(mock_conn).to receive(:post).with('select', data: { q: 'querytext', qt: 'standard' }).and_return(stub_result)
allow(described_class).to receive(:instance).and_return(double("instance", conn: mock_conn))
expect(described_class.post('querytext')).to eq stub_result
end
end

describe "#query" do
let(:doc) { { 'id' => 'x' } }
let(:docs) { [doc] }
let(:stub_result) { { 'response' => { 'docs' => docs } } }

before do
allow(described_class).to receive(:instance).and_return(double("instance", conn: mock_conn))
end

it "defaults to HTTP GET method" do
expect(mock_conn).to receive(:get).with('select', params: { rows: 2, q: 'querytext', qt: 'standard' }).and_return(stub_result)
described_class.query('querytext', rows: 2)
end

it "allows callers to specify HTTP POST method" do
expect(mock_conn).to receive(:post).with('select', data: { rows: 2, q: 'querytext', qt: 'standard' }).and_return(stub_result)
described_class.query('querytext', rows: 2, method: :post)
end

it "raises if method not GET or POST" do
expect(mock_conn).not_to receive(:head).with('select', data: { rows: 2, q: 'querytext', qt: 'standard' })
expect do
described_class.query('querytext', rows: 2, method: :head)
end.to raise_error(RuntimeError, "Unsupported HTTP method for querying SolrService (:head)")
end

it "wraps the solr response documents in Solr hits" do
expect(mock_conn).to receive(:get).with('select', params: { rows: 2, q: 'querytext', qt: 'standard' }).and_return(stub_result)
result = described_class.query('querytext', rows: 2)
expect(result.size).to eq 1
expect(result.first.id).to eq 'x'
end

it "warns about not passing rows" do
allow(mock_conn).to receive(:get).and_return(stub_result)
expect(Rails.logger).to receive(:warn).with(/^Calling Hyrax::SolrService\.get without passing an explicit value for ':rows' is not recommended/)
described_class.query('querytext')
end
end
end

0 comments on commit 2ad6778

Please # to comment.