Skip to content

Commit

Permalink
[refactor] Extract IlliadParameterBuilder class
Browse files Browse the repository at this point in the history
Extract logic for building messages to send to ILLiad to a seprate class. Fufilling the request via ILLiad is a fundamentally different concept from the user making a request to sul-requests, so it makes sense for these to be separate classes.
  • Loading branch information
jcoyne committed Oct 13, 2023
1 parent 0c98e8e commit d35211e
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 191 deletions.
36 changes: 1 addition & 35 deletions app/models/concerns/illiadable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,6 @@ def illiad_error?
end

def illiad_request_params
default_illiad_request_params.merge(special_illiad_request_params).compact
IlliadRequestParameters.build(self)
end

# Override to customize params sent for a specific request type
def special_illiad_request_params
{}
end

private

# These are always sent to ILLiad, regardless of request type
# For more details, see the parameter mapping spreadsheet:
# https://docs.google.com/spreadsheets/d/1bvMuOL4xDjAlXl-QjpsTWHf8Lc3icB7O3ED3FDmKvTQ/edit?usp=sharing
# And ILLiad docs for the API:
# https://support.atlas-sys.com/hc/en-us/articles/360011809394-The-ILLiad-Web-Platform-API#h_01FCP7ZPFFT22TX87CGYP70V0J
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def default_illiad_request_params
{
ProcessType: 'Borrowing',
AcceptAlternateEdition: false,
Username: user.sunetid,
UserInfo1: user.patron.blocked? ? 'Blocked' : nil,
ISSN: bib_data.isbn,
LoanPublisher: bib_data.publisher,
LoanPlace: bib_data.pub_place,
LoanDate: bib_data.pub_date,
LoanEdition: bib_data.edition,
ESPNumber: bib_data.oclcn,
CitedIn: bib_data.view_url,
CallNumber: holdings.first.try(:callnumber),
ILLNumber: holdings.first.try(:barcode),
ItemNumber: holdings.first.try(:barcode),
PhotoJournalVolume: holdings.first.try(:enumeration)
}
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
end
99 changes: 99 additions & 0 deletions app/services/illiad_request_parameters.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# frozen_string_literal: true

# Builds the parameters to send to ILLiad
class IlliadRequestParameters
def self.build(request)
new(request).build
end

def initialize(request)
@request = request
end

def build
default_illiad_request_params.merge(special_illiad_request_params).compact
end

private

attr_reader :request

delegate :user, :bib_data, :holdings, :origin, :origin_location, :section_title,
:page_range, :needed_date, :destination_library_code, to: :request

# These are always sent to ILLiad, regardless of request type
# For more details, see the parameter mapping spreadsheet:
# https://docs.google.com/spreadsheets/d/1bvMuOL4xDjAlXl-QjpsTWHf8Lc3icB7O3ED3FDmKvTQ/edit?usp=sharing
# And ILLiad docs for the API:
# https://support.atlas-sys.com/hc/en-us/articles/360011809394-The-ILLiad-Web-Platform-API#h_01FCP7ZPFFT22TX87CGYP70V0J
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def default_illiad_request_params
{
RequestType: request_type,
SpecIns: spec_ins,
ProcessType: 'Borrowing',
AcceptAlternateEdition: false,
Username: user.sunetid,
UserInfo1: user.patron.blocked? ? 'Blocked' : nil,
ISSN: bib_data.isbn,
LoanPublisher: bib_data.publisher,
LoanPlace: bib_data.pub_place,
LoanDate: bib_data.pub_date,
LoanEdition: bib_data.edition,
ESPNumber: bib_data.oclcn,
CitedIn: bib_data.view_url,
CallNumber: holdings.first.try(:callnumber),
ILLNumber: holdings.first.try(:barcode),
ItemNumber: holdings.first.try(:barcode),
PhotoJournalVolume: holdings.first.try(:enumeration)
}
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize

def special_illiad_request_params
case request
when HoldRecall
hold_recall_request_params
when Scan
scan_request_parameters
end
end

def request_type
case request
when HoldRecall
'Loan'
when Scan
'Article'
end
end

def spec_ins
case request
when HoldRecall
'Hold/Recall Request'
when Scan
'Scan and Deliver Request'
end
end

def scan_request_parameters
{
PhotoJournalTitle: bib_data.title,
PhotoArticleAuthor: bib_data.author,
Location: origin,
ReferenceNumber: origin_location,
PhotoArticleTitle: section_title,
PhotoJournalInclusivePages: page_range
}
end

def hold_recall_request_params
{
LoanTitle: bib_data.title,
LoanAuthor: bib_data.author,
NotWantedAfter: needed_date.strftime('%Y-%m-%d'),
ItemInfo4: destination_library_code
}
end
end
7 changes: 1 addition & 6 deletions spec/jobs/submit_illiad_request_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@

require 'rails_helper'

# A fake Request type that can be sent to ILLiad
class ExampleRequest < Request
include Illiadable
end

RSpec.describe SubmitIlliadRequestJob do
subject { described_class.new(request_id) }

let(:request_id) { 1 }
let(:request) { instance_double(ExampleRequest) }
let(:request) { instance_double(Scan) }
let(:illiad_request) { instance_double(IlliadRequest, request!: illiad_response) }
let(:illiad_response) { instance_double(Faraday::Response, body: '{"Foo": "Bar"}', success?: true) }

Expand Down
42 changes: 2 additions & 40 deletions spec/models/concerns/illiadable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,8 @@

require 'rails_helper'

# A fake Request type that can be sent to ILLiad
class ExampleRequest < Request
include Illiadable
clear_validators!
end

RSpec.describe Illiadable do
subject(:request) { ExampleRequest.new(id: 1, item_id: '1234', user:, bib_data:) }

let(:user) { create(:sso_user) }
let(:patron) { instance_double(Folio::Patron, blocked?: false) }
let(:bib_data) do
instance_double(
Folio::Instance,
hrid: 'a1234',
title: 'The title',
isbn: '978-3-16-148410-0',
oclcn: '(OCoLC-M)1294477572',
pub_date: '2018',
pub_place: 'Berlin',
publisher: 'Walter de Gruyter GmbH',
edition: '1st ed.',
view_url: 'https://searchworks.stanford.edu/view/1234',
request_holdings: holdings
)
end
let(:holdings) do
[
instance_double(
Folio::Item,
barcode: '12345678',
callnumber: 'ABC 321',
enumeration: 'T.1 2023'
)
]
end

before do
allow(user).to receive(:patron).and_return(patron)
end
subject(:request) { build_stubbed(:scan, :with_holdings) }

describe '#notify_ilb!' do
it 'sends an email' do
Expand All @@ -56,7 +18,7 @@ class ExampleRequest < Request

context 'when illiad responded with a message' do
before do
request.update(illiad_response_data: { 'Message' => 'Something went wrong' })
request.illiad_response_data = { 'Message' => 'Something went wrong' }
end

it 'is true' do
Expand Down
111 changes: 1 addition & 110 deletions spec/models/illiad_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,12 @@

require 'rails_helper'

# A fake Request type that can be sent to ILLiad
class ExampleRequest < Request
include Illiadable
end

RSpec.describe IlliadRequest do
subject { described_class.new(request) }

let(:user) { create(:sso_user) }
let(:patron) { instance_double(Folio::Patron, blocked?: false) }
let(:request) { ExampleRequest.new(item_id: '1234', bib_data:) }
let(:bib_data) do
instance_double(
Folio::Instance,
hrid: 'a1234',
isbn: '978-3-16-148410-0',
oclcn: '(OCoLC-M)1294477572',
pub_date: '2018',
pub_place: 'Berlin',
publisher: 'Walter de Gruyter GmbH',
edition: '1st ed.',
view_url: 'https://searchworks.stanford.edu/view/1234',
request_holdings: holdings
)
end
let(:holdings) do
[
instance_double(
Folio::Item,
barcode: '12345678',
callnumber: 'ABC 321',
enumeration: 'T.1 2023'
)
]
end
let(:request) { create(:scan, :with_holdings_barcodes, user:) }

before do
allow(request).to receive(:user).and_return(user)
Expand All @@ -47,10 +18,6 @@ class ExampleRequest < Request
subject.request!
end

it 'POSTs to the illiad api url' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')).to have_been_made
end

describe 'request headers' do
it 'declares that it is sending JSON' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
Expand All @@ -68,82 +35,6 @@ class ExampleRequest < Request
end
end

describe 'request body' do
it 'includes the user sunetid' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"Username":"some-sso-user"/)).to have_been_made
end

it 'includes the process type' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"ProcessType":"Borrowing"/)).to have_been_made
end

it 'specifies that alternate editions are not acceptable by default' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"AcceptAlternateEdition":false/)).to have_been_made
end

it 'includes the call number' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"CallNumber":"ABC 321"/)).to have_been_made
end

it 'includes the barcode as the item number' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"ItemNumber":"12345678"/)).to have_been_made
end

it 'includes the enumeration' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"PhotoJournalVolume":"T.1 2023"/)).to have_been_made
end

it 'includes the publisher' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"LoanPublisher":"Walter de Gruyter GmbH"/)).to have_been_made
end

it 'includes the place of publication' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"LoanPlace":"Berlin"/)).to have_been_made
end

it 'includes the date of publication' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"LoanDate":"2018"/)).to have_been_made
end

it 'includes the edition' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"LoanEdition":"1st ed."/)).to have_been_made
end

it 'includes the OCLC number' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"ESPNumber":"\(OCoLC-M\)1294477572"/)).to have_been_made
end

it 'includes the catalog view link' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: %r{"CitedIn":"https://searchworks.stanford.edu/view/1234"})).to have_been_made
end

it 'includes the ISBN' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"ISSN":"978-3-16-148410-0"/)).to have_been_made
end

context 'when the user is blocked' do
let(:patron) { instance_double(Folio::Patron, blocked?: true) }

it 'includes the blocked status' do
expect(a_request(:post, 'https://illiad.stanford.edu/ILLiadWebPlatform/Transaction/')
.with(body: /"UserInfo1":"Blocked"/)).to have_been_made
end
end
end

context 'with a scan' do
let(:request) { create(:scan, :with_holdings_barcodes, user:) }

Expand Down

0 comments on commit d35211e

Please sign in to comment.