borrow_direct 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +183 -0
- data/Rakefile +11 -0
- data/bd_metrics/finditem_measure.rb +61 -0
- data/bd_metrics/isbn.txt +1088 -0
- data/bd_metrics/lccn.txt +1668 -0
- data/bd_metrics/oclc.txt +167 -0
- data/borrow_direct.gemspec +30 -0
- data/lib/borrow_direct/authentication.rb +55 -0
- data/lib/borrow_direct/defaults.rb +38 -0
- data/lib/borrow_direct/error.rb +17 -0
- data/lib/borrow_direct/find_item.rb +149 -0
- data/lib/borrow_direct/generate_query.rb +78 -0
- data/lib/borrow_direct/request.rb +185 -0
- data/lib/borrow_direct/request_item.rb +119 -0
- data/lib/borrow_direct/request_query.rb +124 -0
- data/lib/borrow_direct/util.rb +18 -0
- data/lib/borrow_direct/version.rb +3 -0
- data/lib/borrow_direct.rb +19 -0
- data/test/authentication_test.rb +79 -0
- data/test/find_item_test.rb +159 -0
- data/test/generate_query_test.rb +91 -0
- data/test/request_item_test.rb +109 -0
- data/test/request_query_test.rb +113 -0
- data/test/request_test.rb +141 -0
- data/test/support/assertions.rb +23 -0
- data/test/support/vcr_filter.rb +45 -0
- data/test/test_helper.rb +39 -0
- data/test/util_test.rb +32 -0
- data/test/vcr_cassettes/Authentication/Makes_a_request_succesfully.yml +52 -0
- data/test/vcr_cassettes/Authentication/Raises_for_bad_library_symbol.yml +52 -0
- data/test/vcr_cassettes/Authentication/Raises_for_bad_patron_barcode.yml +53 -0
- data/test/vcr_cassettes/Authentication/get_auth_id/raises_for_a_bad_library_symbol.yml +52 -0
- data/test/vcr_cassettes/Authentication/get_auth_id/raises_for_a_bad_patron_barcode.yml +53 -0
- data/test/vcr_cassettes/Authentication/get_auth_id/returns_an_auth_id_for_a_good_request.yml +52 -0
- data/test/vcr_cassettes/Authentication/raw_request_to_verify_HTTP_api/.yml +52 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/finds_a_locally_available_item.yml +49 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/finds_a_requestable_item.yml +49 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/finds_an_item_that_does_not_exist_in_BD.yml +50 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/with_expected_error_PUBFI002/returns_result.yml +40 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/works_with_multiple_values.yml +49 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/has_an_auth_id.yml +49 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/has_nil_auth_id_when_BD_doesn_t_want_to_give_us_one.yml +40 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/has_nil_pickup_locations_when_BD_doesn_t_want_to_give_us_them.yml +40 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/has_pickup_locations.yml +49 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_BD_returns_PUBFI002.yml +40 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_does_not_exist_in_BD.yml +50 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_no_libraries_will_lend.yml +50 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_locally_available_item.yml +49 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/requestable_for_requestable_item.yml +49 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/requestable_with_multiple_items_if_at_least_one_is_requestable.yml +49 -0
- data/test/vcr_cassettes/Request/authentication_id/automatically_fetches_one_when_needed.yml +52 -0
- data/test/vcr_cassettes/Request/authentication_id/can_refetch_when_instructed.yml +52 -0
- data/test/vcr_cassettes/Request/can_make_a_succesful_request.yml +49 -0
- data/test/vcr_cassettes/Request/gets_BD_error_info.yml +41 -0
- data/test/vcr_cassettes/Request/raises_on_bad_path.yml +53 -0
- data/test/vcr_cassettes/Request/raises_on_bad_request_hash.yml +63 -0
- data/test/vcr_cassettes/Request/with_expected_errors/still_returns_result.yml +41 -0
- data/test/vcr_cassettes/RequestItem/make_request/make_request_for_a_locally_available_item.yml +90 -0
- data/test/vcr_cassettes/RequestItem/make_request/make_request_for_a_requestable_item.yml +89 -0
- data/test/vcr_cassettes/RequestItem/make_request/make_request_for_an_unrequestable_item.yml +91 -0
- data/test/vcr_cassettes/RequestItem/make_request/raises_for_unrequestable.yml +91 -0
- data/test/vcr_cassettes/RequestItem/make_request/returns_number_for_succesful_request.yml +89 -0
- data/test/vcr_cassettes/RequestItem/make_request/says_no_for_item_that_BD_returns_PUBRI004.yml +89 -0
- data/test/vcr_cassettes/RequestItem/raw_requests_an_unrequestable_item.yml +91 -0
- data/test/vcr_cassettes/RequestItem/uses_manually_set_auth_id.yml +89 -0
- data/test/vcr_cassettes/RequestItem/with_pickup_location_and_requestable_item/still_works.yml +90 -0
- data/test/vcr_cassettes/RequestQuery/raw_request_query_request/returns_results.yml +381 -0
- data/test/vcr_cassettes/RequestQuery/raw_request_to_verify_the_BD_HTTP_API.yml +381 -0
- data/test/vcr_cassettes/RequestQuery/requests/fetches_default_records.yml +384 -0
- data/test/vcr_cassettes/RequestQuery/requests/fetches_full_records.yml +481 -0
- data/test/vcr_cassettes/top_level_describe/an_inner_describe/.yml +76 -0
- metadata +262 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'borrow_direct/find_item'
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
describe "FindItem", :vcr do
|
8
|
+
before do
|
9
|
+
@requestable_item_isbn = "9810743734" # item is in BD, and can be requested
|
10
|
+
@locally_avail_item_isbn = "0745649890" # item is in BD, but is avail locally so not BD-requestable
|
11
|
+
@not_requestable_item_isbn = "1441190090" # in BD, and we don't have it, but no libraries let us borrow (in this case, it's an ebook)
|
12
|
+
@returns_PUBFI002_ISBN = "0109836413" # BD returns an error PUBFI002 for this one, which we want to treat as simply not available.
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
describe "with defaults" do
|
18
|
+
before do
|
19
|
+
@original_symbol = BorrowDirect::Defaults.library_symbol
|
20
|
+
@original_bar = BorrowDirect::Defaults.find_item_patron_barcode
|
21
|
+
BorrowDirect::Defaults.library_symbol = "OUR_SYMBOL"
|
22
|
+
BorrowDirect::Defaults.find_item_patron_barcode = "OUR_BARCODE"
|
23
|
+
end
|
24
|
+
after do
|
25
|
+
BorrowDirect::Defaults.library_symbol = @original_symbol
|
26
|
+
BorrowDirect::Defaults.find_item_patron_barcode = @original_bar
|
27
|
+
end
|
28
|
+
|
29
|
+
it "uses defaults" do
|
30
|
+
finder = BorrowDirect::FindItem.new
|
31
|
+
|
32
|
+
assert_equal "OUR_SYMBOL", finder.patron_library_symbol
|
33
|
+
assert_equal "OUR_BARCODE", finder.patron_barcode
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "query production" do
|
38
|
+
it "exact search works" do
|
39
|
+
finder = BorrowDirect::FindItem.new("barcodeX", "libraryX")
|
40
|
+
hash = finder.send(:exact_search_request_hash, :isbn, "2")
|
41
|
+
|
42
|
+
assert_equal BorrowDirect::Defaults.partnership_id, hash["PartnershipId"]
|
43
|
+
assert_equal "barcodeX", hash["Credentials"]["Barcode"]
|
44
|
+
assert_equal "libraryX", hash["Credentials"]["LibrarySymbol"]
|
45
|
+
|
46
|
+
assert_equal "ISBN", hash["ExactSearch"].first["Type"]
|
47
|
+
assert_equal "2", hash["ExactSearch"].first["Value"]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "works with multiple values" do
|
51
|
+
finder = BorrowDirect::FindItem.new("barcodeX", "libraryX")
|
52
|
+
hash = finder.send(:exact_search_request_hash, :isbn, ["2", "3"])
|
53
|
+
|
54
|
+
exact_searches = hash["ExactSearch"]
|
55
|
+
|
56
|
+
assert_length 2, exact_searches
|
57
|
+
|
58
|
+
assert_include exact_searches, {"Type"=>"ISBN", "Value"=>"2"}
|
59
|
+
assert_include exact_searches, {"Type"=>"ISBN", "Value"=>"3"}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#find_item_request" do
|
64
|
+
|
65
|
+
it "raises on no search critera" do
|
66
|
+
assert_raises(ArgumentError) do
|
67
|
+
BorrowDirect::FindItem.new("whatever", "whatever").find_item_request
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises on multiple search critera" do
|
72
|
+
assert_raises(ArgumentError) do
|
73
|
+
BorrowDirect::FindItem.new("whatever", "whatever").find_item_request(:isbn => "1", :issn => "1")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "raises on unrecognized search criteria" do
|
78
|
+
assert_raises(ArgumentError) do
|
79
|
+
BorrowDirect::FindItem.new("whatever", "whatever").find_item_request(:whoknows => "1")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
it "finds a requestable item" do
|
85
|
+
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => @requestable_item_isbn)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "finds a locally available item" do
|
89
|
+
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => @locally_avail_item_isbn)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "finds an item that does not exist in BD" do
|
93
|
+
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => "NO_SUCH_THING")
|
94
|
+
end
|
95
|
+
|
96
|
+
it "works with multiple values" do
|
97
|
+
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => [@requestable_item_isbn, @locally_avail_item_isbn])
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "with expected error PUBFI002" do
|
101
|
+
it "returns result" do
|
102
|
+
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => @returns_PUBFI002_ISBN )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "find with Response" do
|
108
|
+
before do
|
109
|
+
@find_item = BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol])
|
110
|
+
end
|
111
|
+
|
112
|
+
it "requestable for requestable item" do
|
113
|
+
assert_equal true, @find_item.find(:isbn => @requestable_item_isbn).requestable?
|
114
|
+
end
|
115
|
+
|
116
|
+
it "requestable with multiple items if at least one is requestable" do
|
117
|
+
assert_equal true, @find_item.find(:isbn => [@requestable_item_isbn, "NO_SUCH_ISBN"]).requestable?
|
118
|
+
end
|
119
|
+
|
120
|
+
it "not requestable for locally available item" do
|
121
|
+
assert_equal false, @find_item.find(:isbn => @locally_avail_item_isbn).requestable?
|
122
|
+
end
|
123
|
+
|
124
|
+
it "not requestable for item that does not exist in BD" do
|
125
|
+
assert_equal false, @find_item.find(:isbn => "NO_SUCH_THING").requestable?
|
126
|
+
end
|
127
|
+
|
128
|
+
it "not requestable for item that no libraries will lend" do
|
129
|
+
assert_equal false, @find_item.find(:isbn => @not_requestable_item_isbn).requestable?
|
130
|
+
end
|
131
|
+
|
132
|
+
it "not requestable for item that BD returns PUBFI002" do
|
133
|
+
assert_equal false, @find_item.find(:isbn => @returns_PUBFI002_ISBN).requestable?
|
134
|
+
end
|
135
|
+
|
136
|
+
it "has an auth_id" do
|
137
|
+
assert_present @find_item.find(:isbn => @requestable_item_isbn).auth_id
|
138
|
+
end
|
139
|
+
|
140
|
+
it "has nil auth_id when BD doesn't want to give us one" do
|
141
|
+
assert_nil @find_item.find(:isbn => @returns_PUBFI002_ISBN).auth_id
|
142
|
+
end
|
143
|
+
|
144
|
+
it "has pickup locations" do
|
145
|
+
pickup_locations = @find_item.find(:isbn => @requestable_item_isbn).pickup_locations
|
146
|
+
|
147
|
+
assert_present pickup_locations
|
148
|
+
assert_kind_of Array, pickup_locations
|
149
|
+
end
|
150
|
+
|
151
|
+
it "has nil pickup locations when BD doesn't want to give us them" do
|
152
|
+
assert_nil @find_item.find(:isbn => @returns_PUBFI002_ISBN).pickup_locations
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
describe "GenerateQuery" do
|
5
|
+
before do
|
6
|
+
@test_base = "http://example.org"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "query_url_with" do
|
10
|
+
|
11
|
+
it "raises on unknown field" do
|
12
|
+
assert_raises(ArgumentError) do
|
13
|
+
BorrowDirect::GenerateQuery.new(@test_base).query_url_with(:invalid_thing => "foo")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "generates query" do
|
18
|
+
generate_query = BorrowDirect::GenerateQuery.new(@test_base)
|
19
|
+
|
20
|
+
url = generate_query.query_url_with(:title => "This is a title", :author => "This is an author")
|
21
|
+
|
22
|
+
assert url.start_with? @test_base
|
23
|
+
|
24
|
+
parsed_url = URI.parse(url)
|
25
|
+
url_query = CGI.parse( parsed_url.query )
|
26
|
+
|
27
|
+
assert_present url_query
|
28
|
+
|
29
|
+
assert_length 1, url_query["query"]
|
30
|
+
|
31
|
+
query_text = url_query["query"].first
|
32
|
+
|
33
|
+
parts = query_text.split(" and ")
|
34
|
+
|
35
|
+
assert_length 2, parts
|
36
|
+
|
37
|
+
assert_include parts, 'ti="This is a title"'
|
38
|
+
assert_include parts, 'au="This is an author"'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "best_known_item_query_url_with" do
|
43
|
+
it "uses only isbn when available" do
|
44
|
+
generate_query = BorrowDirect::GenerateQuery.new(@test_base)
|
45
|
+
|
46
|
+
url = generate_query.best_known_item_query_url_with(:isbn => "OUR_ISBN", :title => "This is a title", :author => "This is an author")
|
47
|
+
|
48
|
+
assert url.start_with? @test_base
|
49
|
+
|
50
|
+
parsed_url = URI.parse(url)
|
51
|
+
url_query = CGI.parse( parsed_url.query )
|
52
|
+
|
53
|
+
assert_present url_query
|
54
|
+
|
55
|
+
assert_length 1, url_query["query"]
|
56
|
+
|
57
|
+
query_text = url_query["query"].first
|
58
|
+
|
59
|
+
parts = query_text.split(" and ")
|
60
|
+
|
61
|
+
assert_length 1, parts
|
62
|
+
|
63
|
+
assert_include parts, 'isbn="OUR_ISBN"'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "uses author and title when it has to" do
|
67
|
+
generate_query = BorrowDirect::GenerateQuery.new(@test_base)
|
68
|
+
|
69
|
+
url = generate_query.best_known_item_query_url_with(:title => "This is a title", :author => "This is an author")
|
70
|
+
|
71
|
+
assert url.start_with? @test_base
|
72
|
+
|
73
|
+
parsed_url = URI.parse(url)
|
74
|
+
url_query = CGI.parse( parsed_url.query )
|
75
|
+
|
76
|
+
assert_present url_query
|
77
|
+
|
78
|
+
assert_length 1, url_query["query"]
|
79
|
+
|
80
|
+
query_text = url_query["query"].first
|
81
|
+
|
82
|
+
parts = query_text.split(" and ")
|
83
|
+
|
84
|
+
assert_length 2, parts
|
85
|
+
|
86
|
+
assert_include parts, 'ti="This is a title"'
|
87
|
+
assert_include parts, 'au="This is an author"'
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'vcr'
|
3
|
+
|
4
|
+
require 'borrow_direct/authentication'
|
5
|
+
require 'borrow_direct/request_item'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
describe "RequestItem", :vcr => {:tag => :bd_requestitem } do
|
12
|
+
before do
|
13
|
+
@requestable_item_isbn = "9797994864" # item is in BD, and can be requested
|
14
|
+
@locally_avail_item_isbn = "0745649890" # item is in BD, but is avail locally so not BD-requestable
|
15
|
+
@not_requestable_item_isbn = "1441190090" # in BD, and we don't have it, but no libraries let us borrow (in this case, it's an ebook)
|
16
|
+
@returns_PUBRI004_ISBN = "0109836413" # BD returns an error PUBRI004 for this one, which we want to treat as simply not available.
|
17
|
+
@pickup_location = "Some location" # BD seems to allow anything, which is disturbing
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
it "raises on no search critera" do
|
23
|
+
assert_raises(ArgumentError) do
|
24
|
+
BorrowDirect::RequestItem.new("whatever").request_item_request
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raises on multiple search critera" do
|
29
|
+
assert_raises(ArgumentError) do
|
30
|
+
BorrowDirect::RequestItem.new("whatever").request_item_request(nil, :isbn => "1", :issn => "1")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises on unrecognized search criteria" do
|
35
|
+
assert_raises(ArgumentError) do
|
36
|
+
BorrowDirect::RequestItem.new("whatever").request_item_request(nil, :whoknows => "1")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
it "raw requests an unrequestable item" do
|
42
|
+
|
43
|
+
resp = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).request_item_request(nil, :isbn => @not_requestable_item_isbn)
|
44
|
+
|
45
|
+
assert_present resp
|
46
|
+
assert_present resp["Request"]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "uses manually set auth_id" do
|
50
|
+
bd = BorrowDirect::RequestItem.new("bad_patron" , "bad_symbol")
|
51
|
+
bd.auth_id = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).get_auth_id
|
52
|
+
resp = bd.request_item_request(nil, :isbn => @requestable_item_isbn)
|
53
|
+
|
54
|
+
assert_present resp
|
55
|
+
assert_present resp["Request"]
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "make_request" do
|
59
|
+
it "make_request for a requestable item" do
|
60
|
+
request_id = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @requestable_item_isbn)
|
61
|
+
|
62
|
+
assert_present request_id
|
63
|
+
end
|
64
|
+
|
65
|
+
it "make_request for an unrequestable item" do
|
66
|
+
resp = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @not_requestable_item_isbn)
|
67
|
+
|
68
|
+
assert_nil resp
|
69
|
+
end
|
70
|
+
|
71
|
+
it "make_request for a locally available item" do
|
72
|
+
resp = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @locally_avail_item_isbn)
|
73
|
+
|
74
|
+
assert_nil resp
|
75
|
+
end
|
76
|
+
|
77
|
+
it "says no for item that BD returns PUBRI004" do
|
78
|
+
assert_nil BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @returns_PUBRI004_ISBN)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "with pickup location and requestable item" do
|
84
|
+
it "still works" do
|
85
|
+
request_id = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(@pickup_location, :isbn => @requestable_item_isbn)
|
86
|
+
|
87
|
+
assert_present request_id
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "make_request!" do
|
92
|
+
it "returns number for succesful request" do
|
93
|
+
request_id = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request!(nil, :isbn => @requestable_item_isbn)
|
94
|
+
|
95
|
+
assert_present request_id
|
96
|
+
end
|
97
|
+
|
98
|
+
it "raises for unrequestable" do
|
99
|
+
error = assert_raises(BorrowDirect::Error) do
|
100
|
+
request_id = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request!(nil, :isbn => @not_requestable_item_isbn)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'httpclient'
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
describe "RequestQuery", :vcr => {:tag => :bd_request_query} do
|
8
|
+
before do
|
9
|
+
@requestable_item_isbn = "9797994864" # item is in BD, and can be requested
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raw request to verify the BD HTTP API" do
|
13
|
+
|
14
|
+
# Get the auth code
|
15
|
+
|
16
|
+
auth_uri = BorrowDirect::Defaults.api_base.chomp("/") + "/portal-service/user/authentication/patron"
|
17
|
+
auth_hash = {
|
18
|
+
"AuthenticationInformation" => {
|
19
|
+
"LibrarySymbol" => VCRFilter[:bd_library_symbol],
|
20
|
+
"PatronId" => VCRFilter[:bd_patron]
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
headers = { "Content-Type" => "application/json",
|
25
|
+
"User-Agent" => "ruby borrow_direct gem #{BorrowDirect::VERSION} (HTTPClient #{HTTPClient::VERSION}) https://github.com/jrochkind/borrow_direct",
|
26
|
+
"Accept-Language" => "en"
|
27
|
+
}
|
28
|
+
http = HTTPClient.new
|
29
|
+
response = http.post auth_uri, JSON.generate(auth_hash), headers
|
30
|
+
response_hash = JSON.parse response.body
|
31
|
+
auth_id = response_hash["Authentication"]["AuthnUserInfo"]["AId"]
|
32
|
+
|
33
|
+
|
34
|
+
# Now use it to make a RequestQuery request. Note, BD API requires
|
35
|
+
# you to use the same User-Agent you used to receive the auth id.
|
36
|
+
|
37
|
+
|
38
|
+
query = {
|
39
|
+
"aid" => auth_id,
|
40
|
+
"type" => "open",
|
41
|
+
"fullRecord" => "0"
|
42
|
+
}
|
43
|
+
|
44
|
+
uri = BorrowDirect::Defaults.api_base.chomp("/") + "/portal-service/request/query/my"
|
45
|
+
|
46
|
+
http = HTTPClient.new
|
47
|
+
http_response = http.get uri, query, headers
|
48
|
+
|
49
|
+
assert_equal 200, http_response.code
|
50
|
+
assert_present http_response.body
|
51
|
+
|
52
|
+
response_hash = JSON.parse http_response.body
|
53
|
+
|
54
|
+
assert_present response_hash
|
55
|
+
assert_present response_hash["QueryResult"]
|
56
|
+
assert_kind_of Array, response_hash["QueryResult"]["MyRequestRecords"]
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "raw request_query_request" do
|
60
|
+
it "returns results" do
|
61
|
+
request_query = BorrowDirect::RequestQuery.new(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol])
|
62
|
+
response = request_query.request_query_request
|
63
|
+
|
64
|
+
assert_present response
|
65
|
+
assert_kind_of Hash, response
|
66
|
+
assert_present response["QueryResult"]["MyRequestRecords"]
|
67
|
+
assert_kind_of Array, response["QueryResult"]["MyRequestRecords"]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "requests" do
|
72
|
+
it "fetches default records" do
|
73
|
+
request_query = BorrowDirect::RequestQuery.new(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol])
|
74
|
+
results = request_query.requests
|
75
|
+
|
76
|
+
assert_kind_of Array, results
|
77
|
+
|
78
|
+
item = results.sample
|
79
|
+
|
80
|
+
[ :request_number, :title, :request_status].each do |key|
|
81
|
+
assert_present item.send key
|
82
|
+
end
|
83
|
+
|
84
|
+
[:allow_renew, :allow_cancel].each do |key|
|
85
|
+
assert_includes [true, false], item.send(key)
|
86
|
+
end
|
87
|
+
|
88
|
+
[:request_status_date, :date_submitted].each do |key|
|
89
|
+
assert_present item.send(key)
|
90
|
+
assert_kind_of DateTime, item.send(key)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it "fetches full records" do
|
95
|
+
request_query = BorrowDirect::RequestQuery.new(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol])
|
96
|
+
results = request_query.requests("all", true)
|
97
|
+
|
98
|
+
assert_kind_of Array, results
|
99
|
+
# too hard to test presence of each attributes, as not every item has every
|
100
|
+
# attribute and too hard to find examples to test.
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'borrow_direct/request'
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
describe "Request", :vcr => {:tag => :bd_request} do
|
8
|
+
before do
|
9
|
+
@successful_item_isbn = "9810743734"
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
it "raises on bad path" do
|
14
|
+
assert_raises(BorrowDirect::HttpError) do
|
15
|
+
response = BorrowDirect::Request.new("/no/such/path").request( "foo" => "bar" )
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises on bad request hash" do
|
20
|
+
assert_raises(BorrowDirect::HttpError) do
|
21
|
+
response = BorrowDirect::Request.new("/dws/item/available").request( "foo" => "bar" )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "gets BD error info" do
|
26
|
+
request = {
|
27
|
+
"PartnershipId" => "BAD_ID",
|
28
|
+
"Credentials" => {
|
29
|
+
"LibrarySymbol" => "librarySymbol",
|
30
|
+
"Barcode" => "barcode/patronId"
|
31
|
+
},
|
32
|
+
"ExactSearch" => [
|
33
|
+
{
|
34
|
+
"Type" => "type",
|
35
|
+
"Value" => "value"
|
36
|
+
}
|
37
|
+
]
|
38
|
+
}
|
39
|
+
|
40
|
+
e = assert_raises(BorrowDirect::Error) do
|
41
|
+
response = BorrowDirect::Request.new("/dws/item/available").request( request )
|
42
|
+
end
|
43
|
+
|
44
|
+
refute_nil e
|
45
|
+
refute_nil e.message
|
46
|
+
refute_nil e.bd_code
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can make a succesful request" do
|
50
|
+
request = {
|
51
|
+
"PartnershipId" => "BD",
|
52
|
+
"Credentials" => {
|
53
|
+
"LibrarySymbol" => VCRFilter[:bd_library_symbol],
|
54
|
+
"Barcode" => VCRFilter[:bd_patron]
|
55
|
+
},
|
56
|
+
"ExactSearch" => [
|
57
|
+
{
|
58
|
+
"Type" => "ISBN",
|
59
|
+
"Value" => @successful_item_isbn
|
60
|
+
}
|
61
|
+
]
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
response = BorrowDirect::Request.new("/dws/item/available").request( request )
|
66
|
+
end
|
67
|
+
|
68
|
+
it "uses timeout for HttpClient" do
|
69
|
+
request = BorrowDirect::Request.new("/some/path")
|
70
|
+
request.timeout = 5
|
71
|
+
|
72
|
+
http_client = request.http_client
|
73
|
+
|
74
|
+
assert_equal 5, http_client.send_timeout
|
75
|
+
assert_equal 5, http_client.receive_timeout
|
76
|
+
assert_equal 5, http_client.connect_timeout
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "with expected errors" do
|
80
|
+
it "still returns result" do
|
81
|
+
request = {
|
82
|
+
"PartnershipId" => "BAD_ID",
|
83
|
+
"Credentials" => {
|
84
|
+
"LibrarySymbol" => "librarySymbol",
|
85
|
+
"Barcode" => "barcode/patronId"
|
86
|
+
},
|
87
|
+
"ExactSearch" => [
|
88
|
+
{
|
89
|
+
"Type" => "type",
|
90
|
+
"Value" => "value"
|
91
|
+
}
|
92
|
+
]
|
93
|
+
}
|
94
|
+
|
95
|
+
bd = BorrowDirect::Request.new("/dws/item/available")
|
96
|
+
bd.expected_error_codes << "PUBFI003"
|
97
|
+
response = bd.request( request )
|
98
|
+
|
99
|
+
assert_present response
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "authentication id" do
|
105
|
+
it "starts out nil" do
|
106
|
+
assert_nil BorrowDirect::Request.new("/").auth_id
|
107
|
+
end
|
108
|
+
|
109
|
+
it "manually set one will be used without fetch" do
|
110
|
+
r = BorrowDirect::Request.new("/")
|
111
|
+
r.auth_id = "OUR_AUTH_ID"
|
112
|
+
|
113
|
+
assert_equal "OUR_AUTH_ID", r.need_auth_id("wont_use_this", "or_this")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "automatically fetches one when needed" do
|
117
|
+
r = BorrowDirect::Request.new("/")
|
118
|
+
auth_id = r.need_auth_id(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol])
|
119
|
+
|
120
|
+
assert_present auth_id
|
121
|
+
assert_equal auth_id, r.auth_id
|
122
|
+
end
|
123
|
+
|
124
|
+
it "can refetch when instructed" do
|
125
|
+
r = BorrowDirect::Request.new("/")
|
126
|
+
|
127
|
+
r.auth_id = "OLD_BAD_AUTH_ID"
|
128
|
+
fetched = r.fetch_auth_id!(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol])
|
129
|
+
|
130
|
+
assert_present r.auth_id
|
131
|
+
assert_equal fetched, r.auth_id
|
132
|
+
refute_equal "OLD_BAD_AUTH_ID", r.auth_id
|
133
|
+
end
|
134
|
+
|
135
|
+
it "takes with_auth_id" do
|
136
|
+
r = BorrowDirect::Request.new("/").with_auth_id("OUR_AUTH_ID")
|
137
|
+
assert_equal "OUR_AUTH_ID", r.auth_id
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Useful assertions not provided by minitest-spec
|
2
|
+
|
3
|
+
def assert_present(arg, msg = nil)
|
4
|
+
msg ||= "#{arg.inspect} is empty or not present"
|
5
|
+
|
6
|
+
is_present = arg.respond_to?(:empty?) ? !arg.empty? : !!arg
|
7
|
+
|
8
|
+
assert is_present, msg
|
9
|
+
end
|
10
|
+
|
11
|
+
def assert_length(length, array, msg = nil)
|
12
|
+
msg ||= "Expected #{array.inspect} to be length #{length}"
|
13
|
+
|
14
|
+
assert (array.respond_to?(:length) && array.length == length), msg
|
15
|
+
end
|
16
|
+
|
17
|
+
def assert_include(collection, item, msg = nil)
|
18
|
+
assert_respond_to(collection, :include?, "The collection must respond to :include?.")
|
19
|
+
|
20
|
+
msg ||= "#{collection.inspect.slice(0,10)} expected to include\#{item}"
|
21
|
+
|
22
|
+
assert collection.include?(item), msg
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'vcr'
|
2
|
+
|
3
|
+
# Convenience for using VCR's filter_sensitive_data according to our common
|
4
|
+
# pattern.
|
5
|
+
#
|
6
|
+
# For a sensitive piece of information, set in your shell environment variable eg:
|
7
|
+
#
|
8
|
+
# BD_FINDITEM_PATRON="patron_barcode"
|
9
|
+
#
|
10
|
+
# Then call in a test:
|
11
|
+
# VCRFilter.sensitive_data! :bd_finditem_patron
|
12
|
+
#
|
13
|
+
# In the tests, when you need to use the piece of data somewhere, use
|
14
|
+
# VCRFilter[:bd_library_symbol]
|
15
|
+
#
|
16
|
+
# eg
|
17
|
+
# BorrowDirect::FindItem.new(VCRFilter[:bd_finditem_patron])
|
18
|
+
#
|
19
|
+
# Optional but recommended, use VCR cassette tags...
|
20
|
+
# VCRFilter.sensitive_data!, :bd_finditem_patron, :bd_finditem_tests
|
21
|
+
# #...
|
22
|
+
# describe "BD finditem items", :vcr => {:tag => :bd_finditem_tests}
|
23
|
+
#
|
24
|
+
# When recording a new cassette, the value from ENV will be used in interactions
|
25
|
+
# with remote service, but won't be saved in your on disk cassettes -- it will
|
26
|
+
# be saved as eg DUMMY_BD_FINDITEM_PATRON instead.
|
27
|
+
#
|
28
|
+
# When running from recorded cassettes, you don't need to have the ENV defined, but
|
29
|
+
# when (re-)recording a cassette, you of course do.
|
30
|
+
module VCRFilter
|
31
|
+
@@data = {}
|
32
|
+
def self.[](key) ; @@data[key.to_s.downcase] ; end
|
33
|
+
def self.[]=(key, value) ; @@data[key.to_s.downcase] = value ; end
|
34
|
+
|
35
|
+
def self.sensitive_data!(key, vcr_tag = nil)
|
36
|
+
env_key = key.to_s.upcase
|
37
|
+
dummy_value = "DUMMY_#{env_key}"
|
38
|
+
|
39
|
+
self[key] = (ENV[env_key] || dummy_value)
|
40
|
+
|
41
|
+
VCR.configure do |c|
|
42
|
+
c.filter_sensitive_data( dummy_value, vcr_tag ) { self[key] }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|