borrow_direct 1.1.0 → 1.2.0.pre1
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 +5 -13
- data/.travis.yml +6 -0
- data/Gemfile +2 -0
- data/README.md +19 -6
- data/bd_metrics/finditem_measure.rb +8 -1
- data/borrow_direct.gemspec +1 -1
- data/lib/borrow_direct/authentication.rb +16 -8
- data/lib/borrow_direct/defaults.rb +4 -1
- data/lib/borrow_direct/encryption.rb +34 -0
- data/lib/borrow_direct/error.rb +17 -0
- data/lib/borrow_direct/find_item.rb +32 -18
- data/lib/borrow_direct/pickup_location.rb +32 -0
- data/lib/borrow_direct/request.rb +30 -8
- data/lib/borrow_direct/request_item.rb +15 -7
- data/lib/borrow_direct/request_query.rb +18 -4
- data/lib/borrow_direct/version.rb +1 -1
- data/test/authentication_test.rb +40 -12
- data/test/encryption_test.rb +58 -0
- data/test/find_item_test.rb +66 -11
- data/test/request_item_test.rb +65 -8
- data/test/request_query_test.rb +23 -27
- data/test/request_test.rb +40 -27
- data/test/test_helper.rb +10 -1
- data/test/vcr_cassettes/Authentication/Makes_a_request_succesfully.yml +11 -23
- data/test/vcr_cassettes/Authentication/Raises_for_bad_library_symbol.yml +12 -23
- data/test/vcr_cassettes/Authentication/Raises_for_bad_patron_barcode.yml +12 -24
- data/test/vcr_cassettes/Authentication/get_auth_id/Raises_for_bad_api_key.yml +41 -0
- data/test/vcr_cassettes/Authentication/get_auth_id/raises_for_a_bad_library_symbol.yml +12 -23
- data/test/vcr_cassettes/Authentication/get_auth_id/raises_for_a_bad_patron_barcode.yml +12 -24
- data/test/vcr_cassettes/Authentication/get_auth_id/returns_an_auth_id_for_a_good_request.yml +11 -23
- data/test/vcr_cassettes/Authentication/get_auth_id/returns_auth_id_with_API_key_from_defaults.yml +40 -0
- data/test/vcr_cassettes/Authentication/raw_request_to_verify_HTTP_api/works.yml +11 -23
- data/test/vcr_cassettes/FindItem/_find_item_request/Raises_with_bad_api_key.yml +41 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/finds_a_locally_available_item.yml +47 -18
- data/test/vcr_cassettes/FindItem/_find_item_request/finds_a_requestable_item.yml +66 -18
- data/test/vcr_cassettes/FindItem/_find_item_request/finds_an_item_that_does_not_exist_in_BD.yml +66 -19
- data/test/vcr_cassettes/FindItem/_find_item_request/raises_proper_error_on_bad_AID.yml +40 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/uses_manually_set_auth_id.yml +97 -0
- data/test/vcr_cassettes/FindItem/_find_item_request/with_expected_error_PUBFI002/returns_result.yml +46 -9
- data/test/vcr_cassettes/FindItem/_find_item_request/works_with_multiple_values.yml +66 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/_pickup_location_data/returns_array_of_PickupLocations.yml +97 -0
- data/test/vcr_cassettes/FindItem/find_with_Response/has_an_auth_id.yml +66 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/has_nil_pickup_locations_when_BD_doesn_t_want_to_give_us_them.yml +46 -9
- data/test/vcr_cassettes/FindItem/find_with_Response/has_pickup_locations.yml +66 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/knows_locally_available_.yml +47 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_BD_returns_PUBFI002.yml +46 -9
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_does_not_exist_in_BD.yml +46 -19
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_no_libraries_will_lend.yml +275 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_locally_available_item.yml +47 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/requestable_for_requestable_item.yml +66 -18
- data/test/vcr_cassettes/FindItem/find_with_Response/requestable_with_multiple_items_if_at_least_one_is_requestable.yml +66 -18
- data/test/vcr_cassettes/Request/authentication_id/automatically_fetches_one_when_needed.yml +47 -22
- data/test/vcr_cassettes/Request/authentication_id/can_refetch_when_instructed.yml +47 -22
- data/test/vcr_cassettes/Request/authentication_id/manually_set_one_will_be_used_without_fetch.yml +40 -0
- data/test/vcr_cassettes/Request/authentication_id/starts_out_nil.yml +40 -0
- data/test/vcr_cassettes/Request/authentication_id/takes_with_auth_id.yml +40 -0
- data/test/vcr_cassettes/Request/can_make_a_succesful_request_with_AID.yml +97 -0
- data/test/vcr_cassettes/Request/gets_BD_error_info.yml +49 -12
- data/test/vcr_cassettes/Request/gets_BD_error_info_from_a_bad_AID.yml +77 -0
- data/test/vcr_cassettes/Request/raises_exception_on_timeout_live.yml +40 -0
- data/test/vcr_cassettes/Request/raises_on_bad_path.yml +61 -24
- data/test/vcr_cassettes/Request/raises_on_bad_request_hash.yml +50 -35
- data/test/vcr_cassettes/Request/uses_timeout_for_HttpClient.yml +40 -0
- data/test/vcr_cassettes/Request/with_expected_errors/still_returns_result.yml +47 -10
- data/test/vcr_cassettes/RequestItem/make_request/make_request_for_a_locally_available_item.yml +21 -33
- data/test/vcr_cassettes/RequestItem/make_request/make_request_for_a_requestable_item.yml +20 -32
- data/test/vcr_cassettes/RequestItem/make_request/make_request_for_an_unrequestable_item.yml +21 -33
- data/test/vcr_cassettes/RequestItem/make_request/says_no_for_item_that_BD_returns_PUBRI003.yml +77 -0
- data/test/vcr_cassettes/RequestItem/make_request/sets_an_auth_id.yml +77 -0
- data/test/vcr_cassettes/RequestItem/make_request_/raises_for_unrequestable.yml +21 -33
- data/test/vcr_cassettes/RequestItem/make_request_/returns_number_for_succesful_request.yml +20 -32
- data/test/vcr_cassettes/RequestItem/raises_proper_error_on_bad_AID.yml +40 -0
- data/test/vcr_cassettes/RequestItem/raw_RequestItem_sanity_check.yml +134 -0
- data/test/vcr_cassettes/RequestItem/raw_requests_an_unrequestable_item.yml +21 -33
- data/test/vcr_cassettes/RequestItem/uses_manually_set_auth_id.yml +20 -32
- data/test/vcr_cassettes/RequestItem/with_pickup_location_and_requestable_item/works_with_String_pickup_location.yml +78 -0
- data/test/vcr_cassettes/RequestItem/with_pickup_location_and_requestable_item/works_with_structured_PickupLocation.yml +77 -0
- data/test/vcr_cassettes/RequestQuery/raises_proper_error_on_bad_AID.yml +40 -0
- data/test/vcr_cassettes/RequestQuery/raw_request_query_request/returns_results.yml +117 -325
- data/test/vcr_cassettes/RequestQuery/raw_request_to_verify_the_BD_HTTP_API.yml +30 -325
- data/test/vcr_cassettes/RequestQuery/requests/fetches_default_records.yml +117 -328
- data/test/vcr_cassettes/RequestQuery/requests/fetches_full_records.yml +148 -425
- metadata +67 -38
- data/test/vcr_cassettes/Authentication/raw_request_to_verify_HTTP_api/.yml +0 -52
- data/test/vcr_cassettes/FindItem/find_with_Response/has_nil_auth_id_when_BD_doesn_t_want_to_give_us_one.yml +0 -40
- data/test/vcr_cassettes/Request/can_make_a_succesful_request.yml +0 -49
- data/test/vcr_cassettes/RequestItem/make_request/raises_for_unrequestable.yml +0 -91
- data/test/vcr_cassettes/RequestItem/make_request/returns_number_for_succesful_request.yml +0 -89
- data/test/vcr_cassettes/RequestItem/make_request/says_no_for_item_that_BD_returns_PUBRI004.yml +0 -89
- data/test/vcr_cassettes/RequestItem/with_pickup_location_and_requestable_item/still_works.yml +0 -90
- data/test/vcr_cassettes/top_level_describe/an_inner_describe/.yml +0 -76
data/test/authentication_test.rb
CHANGED
@@ -6,14 +6,15 @@ require 'httpclient'
|
|
6
6
|
describe "Authentication", :vcr => {:tag => :bd_auth} do
|
7
7
|
describe "raw request to verify HTTP api" do
|
8
8
|
it "works" do
|
9
|
-
uri = BorrowDirect::Defaults.api_base.chomp("/") + "/portal-service/user/authentication
|
9
|
+
uri = BorrowDirect::Defaults.api_base.chomp("/") + "/portal-service/user/authentication"
|
10
10
|
|
11
11
|
|
12
12
|
request_hash = {
|
13
|
-
"
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
"ApiKey" => VCRFilter[:bd_api_key],
|
14
|
+
"PartnershipId" => BorrowDirect::Defaults.partnership_id,
|
15
|
+
"UserGroup" => "patron",
|
16
|
+
"LibrarySymbol" => VCRFilter[:bd_library_symbol],
|
17
|
+
"PatronId" => VCRFilter[:bd_patron]
|
17
18
|
}
|
18
19
|
|
19
20
|
http = HTTPClient.new
|
@@ -26,47 +27,74 @@ describe "Authentication", :vcr => {:tag => :bd_auth} do
|
|
26
27
|
|
27
28
|
assert_present response_hash
|
28
29
|
|
29
|
-
assert_present response_hash["
|
30
|
+
assert_present response_hash["AuthorizationId"]
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
34
|
it "Makes a request succesfully" do
|
34
|
-
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol])
|
35
|
+
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol], VCRFilter[:bd_api_key])
|
35
36
|
response = bd.authentication_request
|
36
37
|
|
37
38
|
assert_present response
|
38
|
-
assert_present response["
|
39
|
+
assert_present response["AuthorizationId"]
|
39
40
|
end
|
40
41
|
|
42
|
+
|
43
|
+
|
41
44
|
it "Raises for bad library symbol" do
|
42
|
-
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , "BAD_SYMBOL")
|
45
|
+
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , "BAD_SYMBOL", VCRFilter[:bd_api_key])
|
43
46
|
assert_raises(BorrowDirect::Error) do
|
44
47
|
bd.authentication_request
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
51
|
it "Raises for bad patron barcode" do
|
49
|
-
bd = BorrowDirect::Authentication.new("BAD_BARCODE", VCRFilter[:bd_library_symbol])
|
52
|
+
bd = BorrowDirect::Authentication.new("BAD_BARCODE", VCRFilter[:bd_library_symbol], VCRFilter[:bd_api_key])
|
50
53
|
assert_raises(BorrowDirect::Error) do
|
51
54
|
bd.authentication_request
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
58
|
+
it "Raises with no api_key" do
|
59
|
+
begin
|
60
|
+
orig_api_key = BorrowDirect::Defaults.api_key
|
61
|
+
BorrowDirect::Defaults.api_key = nil
|
62
|
+
|
63
|
+
assert_raises(ArgumentError) do
|
64
|
+
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol])
|
65
|
+
end
|
66
|
+
ensure
|
67
|
+
BorrowDirect::Defaults.api_key = orig_api_key
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
55
72
|
describe "get_auth_id" do
|
56
73
|
it "returns an auth_id for a good request" do
|
74
|
+
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol], VCRFilter[:bd_api_key])
|
75
|
+
assert_present bd.get_auth_id
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns auth_id with API key from defaults" do
|
57
79
|
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol])
|
58
80
|
assert_present bd.get_auth_id
|
59
81
|
end
|
60
82
|
|
83
|
+
it "Raises for bad api_key" do
|
84
|
+
assert_raises(BorrowDirect::Error) do
|
85
|
+
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol], "BAD_API_KEY").get_auth_id
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
61
89
|
it "raises for a bad library symbol" do
|
62
|
-
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , "BAD_SYMBOL")
|
90
|
+
bd = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , "BAD_SYMBOL", VCRFilter[:bd_api_key])
|
63
91
|
assert_raises(BorrowDirect::Error) do
|
64
92
|
bd.get_auth_id
|
65
93
|
end
|
66
94
|
end
|
67
95
|
|
68
96
|
it "raises for a bad patron barcode" do
|
69
|
-
bd = BorrowDirect::Authentication.new("BAD_BARCODE", VCRFilter[:bd_library_symbol])
|
97
|
+
bd = BorrowDirect::Authentication.new("BAD_BARCODE", VCRFilter[:bd_library_symbol], VCRFilter[:bd_api_key])
|
70
98
|
assert_raises(BorrowDirect::Error) do
|
71
99
|
bd.get_auth_id
|
72
100
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'borrow_direct/encryption'
|
3
|
+
|
4
|
+
describe "Relais Encryption" do
|
5
|
+
before do
|
6
|
+
@sample_private_key = <<-EOS
|
7
|
+
-----BEGIN RSA PRIVATE KEY-----
|
8
|
+
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
9
|
+
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
10
|
+
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
11
|
+
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
12
|
+
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
13
|
+
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
14
|
+
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
15
|
+
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
16
|
+
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
17
|
+
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
18
|
+
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
19
|
+
-----END RSA PRIVATE KEY-----
|
20
|
+
EOS
|
21
|
+
|
22
|
+
@sample_public_key = <<-EOS
|
23
|
+
-----BEGIN PUBLIC KEY-----
|
24
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
|
25
|
+
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
|
26
|
+
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
|
27
|
+
-----END PUBLIC KEY-----
|
28
|
+
EOS
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "timestamp" do
|
32
|
+
it "creates in GMT" do
|
33
|
+
timestamp = BorrowDirect::Encryption.new(@sample_public_key).now_timestamp
|
34
|
+
|
35
|
+
utc_date = Time.now.utc.to_date
|
36
|
+
|
37
|
+
assert timestamp =~ /(\d{4})(\d{2})(\d{2}) \d{6}/
|
38
|
+
|
39
|
+
assert_equal utc_date.year.to_s, $1
|
40
|
+
assert_equal "%02d" % utc_date.month, $2
|
41
|
+
assert_equal "%02d" % utc_date.day, $3
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "encrypted value" do
|
46
|
+
it "is encrypted with datestamp properly" do
|
47
|
+
original_value = "$$VALUE$$"
|
48
|
+
encrypted = BorrowDirect::Encryption.new(@sample_public_key).encode_with_ts(original_value)
|
49
|
+
encrypted = Base64.decode64(encrypted)
|
50
|
+
|
51
|
+
# Let's decrypt it and see
|
52
|
+
private_key = OpenSSL::PKey::RSA.new(@sample_private_key)
|
53
|
+
payload = private_key.private_decrypt(encrypted)
|
54
|
+
|
55
|
+
assert payload =~ /#{original_value}|\d{8} \d{6}/
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/test/find_item_test.rb
CHANGED
@@ -4,12 +4,13 @@ require 'borrow_direct/find_item'
|
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
-
describe "FindItem", :vcr do
|
7
|
+
describe "FindItem", :vcr => {:tag => :bd_finditem }do
|
8
8
|
before do
|
9
9
|
@requestable_item_isbn = "9810743734" # item is in BD, and can be requested
|
10
10
|
@locally_avail_item_isbn = "0745649890" # item is in BD, but is avail locally so not BD-requestable
|
11
|
-
@not_requestable_item_isbn = "
|
11
|
+
@not_requestable_item_isbn = "1444367072" # in BD, and we don't have it, but no libraries let us borrow (in this case, it's an ebook)
|
12
12
|
@returns_PUBFI002_ISBN = "0109836413" # BD returns an error PUBFI002 for this one, which we want to treat as simply not available.
|
13
|
+
@not_in_BD_at_all_isbn = "1898989898" # Not in BD at all, made up ISBN, invalid.
|
13
14
|
end
|
14
15
|
|
15
16
|
|
@@ -39,9 +40,12 @@ describe "FindItem", :vcr do
|
|
39
40
|
finder = BorrowDirect::FindItem.new("barcodeX", "libraryX")
|
40
41
|
hash = finder.send(:exact_search_request_hash, :isbn, "2")
|
41
42
|
|
43
|
+
|
42
44
|
assert_equal BorrowDirect::Defaults.partnership_id, hash["PartnershipId"]
|
43
|
-
|
44
|
-
|
45
|
+
|
46
|
+
# These aren't there anymore.
|
47
|
+
#assert_equal "barcodeX", hash["Credentials"]["Barcode"]
|
48
|
+
#assert_equal "libraryX", hash["Credentials"]["LibrarySymbol"]
|
45
49
|
|
46
50
|
assert_equal "ISBN", hash["ExactSearch"].first["Type"]
|
47
51
|
assert_equal "2", hash["ExactSearch"].first["Value"]
|
@@ -80,11 +84,42 @@ describe "FindItem", :vcr do
|
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
87
|
+
it "raises proper error on bad AID" do
|
88
|
+
e = assert_raises(BorrowDirect::InvalidAidError) do
|
89
|
+
BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).with_auth_id("bad_expired_aid").find_item_request(:isbn => @requestable_item_isbn)
|
90
|
+
end
|
91
|
+
assert_present e.message
|
92
|
+
assert_present e.bd_code
|
93
|
+
assert_present e.aid
|
94
|
+
end
|
95
|
+
|
96
|
+
it "Raises with bad api_key" do
|
97
|
+
begin
|
98
|
+
orig_api_key = BorrowDirect::Defaults.api_key
|
99
|
+
BorrowDirect::Defaults.api_key = "BADAPIKEY"
|
100
|
+
|
101
|
+
assert_raises(BorrowDirect::Error) do
|
102
|
+
BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => @requestable_item_isbn)
|
103
|
+
end
|
104
|
+
ensure
|
105
|
+
BorrowDirect::Defaults.api_key = orig_api_key
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
83
109
|
|
84
110
|
it "finds a requestable item" do
|
85
111
|
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => @requestable_item_isbn)
|
86
112
|
end
|
87
113
|
|
114
|
+
it "uses manually set auth_id" do
|
115
|
+
auth_id = BorrowDirect::Authentication.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).get_auth_id
|
116
|
+
bd = BorrowDirect::FindItem.new("bad_patron" , "bad_symbol").with_auth_id(auth_id)
|
117
|
+
resp = bd.find_item_request(:isbn => @requestable_item_isbn)
|
118
|
+
|
119
|
+
assert_present resp
|
120
|
+
assert_equal true, resp["Available"]
|
121
|
+
end
|
122
|
+
|
88
123
|
it "finds a locally available item" do
|
89
124
|
assert_present BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find_item_request(:isbn => @locally_avail_item_isbn)
|
90
125
|
end
|
@@ -113,8 +148,10 @@ describe "FindItem", :vcr do
|
|
113
148
|
assert_equal true, @find_item.find(:isbn => @requestable_item_isbn).requestable?
|
114
149
|
end
|
115
150
|
|
151
|
+
|
152
|
+
|
116
153
|
it "requestable with multiple items if at least one is requestable" do
|
117
|
-
assert_equal true, @find_item.find(:isbn => [@requestable_item_isbn,
|
154
|
+
assert_equal true, @find_item.find(:isbn => [@requestable_item_isbn, @not_in_BD_at_all_isbn]).requestable?
|
118
155
|
end
|
119
156
|
|
120
157
|
it "not requestable for locally available item" do
|
@@ -126,7 +163,7 @@ describe "FindItem", :vcr do
|
|
126
163
|
end
|
127
164
|
|
128
165
|
it "not requestable for item that does not exist in BD" do
|
129
|
-
assert_equal false, @find_item.find(:isbn =>
|
166
|
+
assert_equal false, @find_item.find(:isbn => @not_in_BD_at_all_isbn).requestable?
|
130
167
|
end
|
131
168
|
|
132
169
|
it "not requestable for item that no libraries will lend" do
|
@@ -138,18 +175,36 @@ describe "FindItem", :vcr do
|
|
138
175
|
end
|
139
176
|
|
140
177
|
it "has an auth_id" do
|
178
|
+
assert @find_item.auth_id.nil?
|
141
179
|
assert_present @find_item.find(:isbn => @requestable_item_isbn).auth_id
|
142
|
-
|
143
|
-
|
144
|
-
it "has nil auth_id when BD doesn't want to give us one" do
|
145
|
-
assert_nil @find_item.find(:isbn => @returns_PUBFI002_ISBN).auth_id
|
146
|
-
end
|
180
|
+
assert_present @find_item.auth_id
|
181
|
+
end
|
147
182
|
|
148
183
|
it "has pickup locations" do
|
149
184
|
pickup_locations = @find_item.find(:isbn => @requestable_item_isbn).pickup_locations
|
150
185
|
|
151
186
|
assert_present pickup_locations
|
152
187
|
assert_kind_of Array, pickup_locations
|
188
|
+
pickup_locations.each do |location|
|
189
|
+
assert_kind_of String, location
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#pickup_location_data" do
|
194
|
+
it "returns array of PickupLocations" do
|
195
|
+
pickup_locations = @find_item.find(:isbn => @requestable_item_isbn).pickup_location_data
|
196
|
+
|
197
|
+
assert_present pickup_locations
|
198
|
+
assert_kind_of Array, pickup_locations
|
199
|
+
pickup_locations.each do |location|
|
200
|
+
assert_kind_of BorrowDirect::PickupLocation, location
|
201
|
+
assert_present location.code
|
202
|
+
assert_present location.description
|
203
|
+
|
204
|
+
assert_equal [location.description, location.code], location.to_a
|
205
|
+
assert_equal( {"PickupLocationCode" => location.code, "PickupLocationDescription" => location.description}, location.to_h )
|
206
|
+
end
|
207
|
+
end
|
153
208
|
end
|
154
209
|
|
155
210
|
it "has nil pickup locations when BD doesn't want to give us them" do
|
data/test/request_item_test.rb
CHANGED
@@ -13,8 +13,38 @@ describe "RequestItem", :vcr => {:tag => :bd_requestitem } do
|
|
13
13
|
@requestable_item_isbn = "9797994864" # item is in BD, and can be requested
|
14
14
|
@locally_avail_item_isbn = "0745649890" # item is in BD, but is avail locally so not BD-requestable
|
15
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
|
-
@
|
16
|
+
@returns_PUBRI003_ISBN = "0109836413" # BD returns an error PUBRI004 for this one, which we want to treat as simply not available.
|
17
17
|
@pickup_location = "Some location" # BD seems to allow anything, which is disturbing
|
18
|
+
@pickup_location_obj = BorrowDirect::PickupLocation.new({"PickupLocationCode" => "a", "PickupLocationDescription" => @pickup_location})
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raw RequestItem sanity check" do
|
22
|
+
findable = BorrowDirect::FindItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).find(:isbn => @requestable_item_isbn)
|
23
|
+
|
24
|
+
assert findable.requestable?
|
25
|
+
|
26
|
+
pickup = findable.pickup_locations.first
|
27
|
+
aid = findable.auth_id
|
28
|
+
|
29
|
+
uri = BorrowDirect::Defaults.api_base.chomp("/") + "/dws/item/add?aid=#{CGI.escape aid}"
|
30
|
+
|
31
|
+
request_hash = {
|
32
|
+
"PartnershipId" => BorrowDirect::Defaults.partnership_id,
|
33
|
+
"PickupLocation" => pickup,
|
34
|
+
"ExactSearch" => [
|
35
|
+
{"Type" => "ISBN","Value" => @requestable_item_isbn}
|
36
|
+
]
|
37
|
+
}
|
38
|
+
|
39
|
+
http = HTTPClient.new
|
40
|
+
response = http.post uri, JSON.generate(request_hash), BorrowDirect::Request.new('').request_headers
|
41
|
+
|
42
|
+
assert_equal 200, response.code
|
43
|
+
assert_present response.body
|
44
|
+
|
45
|
+
response_hash = JSON.parse response.body
|
46
|
+
|
47
|
+
assert_present response_hash
|
18
48
|
end
|
19
49
|
|
20
50
|
|
@@ -43,7 +73,8 @@ describe "RequestItem", :vcr => {:tag => :bd_requestitem } do
|
|
43
73
|
resp = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).request_item_request(nil, :isbn => @not_requestable_item_isbn)
|
44
74
|
|
45
75
|
assert_present resp
|
46
|
-
|
76
|
+
|
77
|
+
assert_present resp["RequestLink"]
|
47
78
|
end
|
48
79
|
|
49
80
|
it "uses manually set auth_id" do
|
@@ -52,7 +83,17 @@ describe "RequestItem", :vcr => {:tag => :bd_requestitem } do
|
|
52
83
|
resp = bd.request_item_request(nil, :isbn => @requestable_item_isbn)
|
53
84
|
|
54
85
|
assert_present resp
|
55
|
-
|
86
|
+
|
87
|
+
assert_present resp["RequestNumber"], "Was not able to succesfully make a request: #{resp}"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises proper error on bad AID" do
|
91
|
+
e = assert_raises(BorrowDirect::InvalidAidError) do
|
92
|
+
BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).with_auth_id("bad_expired_aid").make_request(nil, :isbn => @requestable_item_isbn)
|
93
|
+
end
|
94
|
+
assert_present e.message
|
95
|
+
assert_present e.bd_code
|
96
|
+
assert_present e.aid
|
56
97
|
end
|
57
98
|
|
58
99
|
describe "make_request" do
|
@@ -62,6 +103,15 @@ describe "RequestItem", :vcr => {:tag => :bd_requestitem } do
|
|
62
103
|
assert_present request_id
|
63
104
|
end
|
64
105
|
|
106
|
+
it "sets an auth_id" do
|
107
|
+
requester = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol])
|
108
|
+
|
109
|
+
assert requester.auth_id.nil?
|
110
|
+
|
111
|
+
requester.make_request(nil, :isbn => @requestable_item_isbn)
|
112
|
+
assert_present requester.auth_id
|
113
|
+
end
|
114
|
+
|
65
115
|
it "make_request for an unrequestable item" do
|
66
116
|
resp = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @not_requestable_item_isbn)
|
67
117
|
|
@@ -74,18 +124,25 @@ describe "RequestItem", :vcr => {:tag => :bd_requestitem } do
|
|
74
124
|
assert_nil resp
|
75
125
|
end
|
76
126
|
|
77
|
-
it "says no for item that BD returns
|
78
|
-
assert_nil BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @
|
127
|
+
it "says no for item that BD returns PUBRI003" do
|
128
|
+
assert_nil BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(nil, :isbn => @returns_PUBRI003_ISBN)
|
79
129
|
end
|
80
130
|
|
81
131
|
end
|
82
132
|
|
83
|
-
describe "with pickup location and requestable item"
|
84
|
-
it "
|
133
|
+
describe "with pickup location and requestable item" do
|
134
|
+
it "works with String pickup_location" do
|
85
135
|
request_id = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(@pickup_location, :isbn => @requestable_item_isbn)
|
86
136
|
|
87
|
-
assert_present request_id
|
137
|
+
assert_present request_id, "Was not able to succesfully make a request"
|
138
|
+
end
|
139
|
+
|
140
|
+
it "works with structured PickupLocation" do
|
141
|
+
request_id = BorrowDirect::RequestItem.new(VCRFilter[:bd_patron] , VCRFilter[:bd_library_symbol]).make_request(@pickup_location_obj, :isbn => @requestable_item_isbn)
|
142
|
+
|
143
|
+
assert_present request_id, "Was not able to succesfully make a request"
|
88
144
|
end
|
145
|
+
|
89
146
|
end
|
90
147
|
|
91
148
|
describe "make_request!" do
|
data/test/request_query_test.rb
CHANGED
@@ -12,35 +12,22 @@ describe "RequestQuery", :vcr => {:tag => :bd_request_query} do
|
|
12
12
|
it "raw request to verify the BD HTTP API" do
|
13
13
|
|
14
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
|
-
|
15
|
+
auth_id = BorrowDirect::Authentication.new(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol]).get_auth_id
|
33
16
|
|
34
17
|
# Now use it to make a RequestQuery request. Note, BD API requires
|
35
18
|
# you to use the same User-Agent you used to receive the auth id.
|
36
19
|
|
37
|
-
|
38
20
|
query = {
|
39
21
|
"aid" => auth_id,
|
40
22
|
"type" => "open",
|
41
23
|
"fullRecord" => "0"
|
42
24
|
}
|
43
25
|
|
26
|
+
headers = { "Content-Type" => "application/json",
|
27
|
+
"User-Agent" => "ruby borrow_direct gem #{BorrowDirect::VERSION} (HTTPClient #{HTTPClient::VERSION}) https://github.com/jrochkind/borrow_direct",
|
28
|
+
"Accept-Language" => "en"
|
29
|
+
}
|
30
|
+
|
44
31
|
uri = BorrowDirect::Defaults.api_base.chomp("/") + "/portal-service/request/query/my"
|
45
32
|
|
46
33
|
http = HTTPClient.new
|
@@ -52,8 +39,15 @@ describe "RequestQuery", :vcr => {:tag => :bd_request_query} do
|
|
52
39
|
response_hash = JSON.parse http_response.body
|
53
40
|
|
54
41
|
assert_present response_hash
|
55
|
-
|
56
|
-
|
42
|
+
assert_kind_of Array, response_hash["MyRequestRecords"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises proper error on bad AID" do
|
46
|
+
e = assert_raises(BorrowDirect::InvalidAidError) do
|
47
|
+
BorrowDirect::RequestQuery.new(VCRFilter[:bd_patron]).with_auth_id("bad_expired_id").request_query_request
|
48
|
+
end
|
49
|
+
assert_present e.message
|
50
|
+
assert_present e.aid
|
57
51
|
end
|
58
52
|
|
59
53
|
describe "raw request_query_request" do
|
@@ -63,8 +57,8 @@ describe "RequestQuery", :vcr => {:tag => :bd_request_query} do
|
|
63
57
|
|
64
58
|
assert_present response
|
65
59
|
assert_kind_of Hash, response
|
66
|
-
assert_present response["
|
67
|
-
assert_kind_of Array, response["
|
60
|
+
assert_present response["MyRequestRecords"]
|
61
|
+
assert_kind_of Array, response["MyRequestRecords"]
|
68
62
|
end
|
69
63
|
end
|
70
64
|
|
@@ -85,10 +79,12 @@ describe "RequestQuery", :vcr => {:tag => :bd_request_query} do
|
|
85
79
|
assert_includes [true, false], item.send(key)
|
86
80
|
end
|
87
81
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
# Huh, records don't seem to reliably have these, so we
|
83
|
+
# can't test for them, bah.
|
84
|
+
#[:request_status_date, :date_submitted].each do |key|
|
85
|
+
# assert_present item.send(key)
|
86
|
+
# assert_kind_of DateTime, item.send(key)
|
87
|
+
#end
|
92
88
|
end
|
93
89
|
|
94
90
|
it "fetches full records" do
|
data/test/request_test.rb
CHANGED
@@ -4,9 +4,11 @@ require 'borrow_direct/request'
|
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
-
describe "Request", :vcr => {:tag => :bd_request} do
|
7
|
+
describe "Request", :vcr => {:tag => :bd_request } do
|
8
8
|
before do
|
9
9
|
@successful_item_isbn = "9810743734"
|
10
|
+
|
11
|
+
@aid = BorrowDirect::Authentication.new(VCRFilter[:bd_patron], VCRFilter[:bd_library_symbol]).get_auth_id
|
10
12
|
end
|
11
13
|
|
12
14
|
|
@@ -17,8 +19,8 @@ describe "Request", :vcr => {:tag => :bd_request} do
|
|
17
19
|
end
|
18
20
|
|
19
21
|
it "raises on bad request hash" do
|
20
|
-
assert_raises(BorrowDirect::
|
21
|
-
response = BorrowDirect::Request.new("/dws/item/available").request( "foo" => "bar" )
|
22
|
+
assert_raises(BorrowDirect::Error) do
|
23
|
+
response = BorrowDirect::Request.new("/dws/item/available").request( {"foo" => "bar"}, @aid )
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -46,13 +48,28 @@ describe "Request", :vcr => {:tag => :bd_request} do
|
|
46
48
|
refute_nil e.bd_code
|
47
49
|
end
|
48
50
|
|
49
|
-
it "
|
51
|
+
it "gets BD error info from a bad AID" do
|
52
|
+
request = {
|
53
|
+
"PartnershipId" => "BD",
|
54
|
+
"ExactSearch" => [
|
55
|
+
{
|
56
|
+
"Type" => "ISBN",
|
57
|
+
"Value" => @successful_item_isbn
|
58
|
+
}
|
59
|
+
]
|
60
|
+
}
|
61
|
+
|
62
|
+
e = assert_raises(BorrowDirect::InvalidAidError) do
|
63
|
+
response = BorrowDirect::Request.new("/dws/item/available").request( request, "bad_aid" )
|
64
|
+
end
|
65
|
+
|
66
|
+
refute_nil e
|
67
|
+
assert_equal "PUBFI003", e.bd_code
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can make a succesful request with AID" do
|
50
71
|
request = {
|
51
72
|
"PartnershipId" => "BD",
|
52
|
-
"Credentials" => {
|
53
|
-
"LibrarySymbol" => VCRFilter[:bd_library_symbol],
|
54
|
-
"Barcode" => VCRFilter[:bd_patron]
|
55
|
-
},
|
56
73
|
"ExactSearch" => [
|
57
74
|
{
|
58
75
|
"Type" => "ISBN",
|
@@ -62,7 +79,7 @@ describe "Request", :vcr => {:tag => :bd_request} do
|
|
62
79
|
}
|
63
80
|
|
64
81
|
|
65
|
-
response = BorrowDirect::Request.new("/dws/item/available").request( request )
|
82
|
+
response = BorrowDirect::Request.new("/dws/item/available").request( request, @aid )
|
66
83
|
end
|
67
84
|
|
68
85
|
it "uses timeout for HttpClient" do
|
@@ -76,13 +93,12 @@ describe "Request", :vcr => {:tag => :bd_request} do
|
|
76
93
|
assert_equal 5, http_client.connect_timeout
|
77
94
|
end
|
78
95
|
|
96
|
+
|
79
97
|
it "raises exception on timeout, live" do
|
98
|
+
skip "Can't get this to work with VCR and new API"
|
99
|
+
|
80
100
|
request = {
|
81
101
|
"PartnershipId" => "BD",
|
82
|
-
"Credentials" => {
|
83
|
-
"LibrarySymbol" => VCRFilter[:bd_library_symbol],
|
84
|
-
"Barcode" => VCRFilter[:bd_patron]
|
85
|
-
},
|
86
102
|
"ExactSearch" => [
|
87
103
|
{
|
88
104
|
"Type" => "ISBN",
|
@@ -90,19 +106,20 @@ describe "Request", :vcr => {:tag => :bd_request} do
|
|
90
106
|
}
|
91
107
|
]
|
92
108
|
}
|
93
|
-
|
109
|
+
# Using a Bad URI here keeps VCR from interfering with us too much.
|
110
|
+
bd = BorrowDirect::Request.new("/dws/item/available_bad_uri")
|
94
111
|
# tiny timeout, it'll def timeout, and on connect no less
|
95
|
-
bd.timeout = 0.
|
112
|
+
bd.timeout = 0.00000001
|
96
113
|
timeout_error = assert_raises(BorrowDirect::HttpTimeoutError) do
|
97
|
-
response = bd.request( request )
|
114
|
+
response = bd.request( request, @aid )
|
98
115
|
end
|
99
116
|
assert_equal bd.timeout, timeout_error.timeout
|
100
117
|
|
101
118
|
# little bit longer to get maybe a receive timeout instead
|
102
|
-
bd = BorrowDirect::Request.new("/dws/item/
|
119
|
+
bd = BorrowDirect::Request.new("/dws/item/available_bad_uri")
|
103
120
|
bd.timeout = 0.10
|
104
121
|
timeout_error = assert_raises(BorrowDirect::HttpTimeoutError) do
|
105
|
-
response = bd.request( request )
|
122
|
+
response = bd.request( request, @aid )
|
106
123
|
end
|
107
124
|
assert_equal bd.timeout, timeout_error.timeout
|
108
125
|
end
|
@@ -110,22 +127,18 @@ describe "Request", :vcr => {:tag => :bd_request} do
|
|
110
127
|
describe "with expected errors" do
|
111
128
|
it "still returns result" do
|
112
129
|
request = {
|
113
|
-
"PartnershipId" => "
|
114
|
-
"Credentials" => {
|
115
|
-
"LibrarySymbol" => "librarySymbol",
|
116
|
-
"Barcode" => "barcode/patronId"
|
117
|
-
},
|
130
|
+
"PartnershipId" => "BD",
|
118
131
|
"ExactSearch" => [
|
119
132
|
{
|
120
|
-
"Type" => "
|
121
|
-
"Value" => "
|
133
|
+
"Type" => "BADBAD",
|
134
|
+
"Value" => "2292389283928392382938"
|
122
135
|
}
|
123
136
|
]
|
124
137
|
}
|
125
138
|
|
126
139
|
bd = BorrowDirect::Request.new("/dws/item/available")
|
127
|
-
bd.expected_error_codes << "
|
128
|
-
response = bd.request( request )
|
140
|
+
bd.expected_error_codes << "PRIFI001"
|
141
|
+
response = bd.request( request, @aid )
|
129
142
|
|
130
143
|
assert_present response
|
131
144
|
|
data/test/test_helper.rb
CHANGED
@@ -9,6 +9,12 @@ require 'minitest-vcr'
|
|
9
9
|
|
10
10
|
require 'borrow_direct'
|
11
11
|
|
12
|
+
# Want to run tests against PRODUCTION BD? It WILL result in real requests being
|
13
|
+
# made to BD production system, so you probably don't -- but if you're not sure
|
14
|
+
# if production API is really behaving like test, you might want to anyway.
|
15
|
+
if ENV["RAILS_ENV"] == "production"
|
16
|
+
BorrowDirect::Defaults.api_base = BorrowDirect::Defaults::PRODUCTION_API_BASE
|
17
|
+
end
|
12
18
|
|
13
19
|
# Load support files
|
14
20
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
@@ -19,13 +25,16 @@ VCR.configure do |c|
|
|
19
25
|
|
20
26
|
# BD API requests tend to have their distinguishing
|
21
27
|
# features in a POSTed JSON request body
|
22
|
-
c.default_cassette_options = { :match_requests_on => [:method, :
|
28
|
+
c.default_cassette_options = { :match_requests_on => [:method, VCR.request_matchers.uri_without_param(:aid), :body] }
|
23
29
|
end
|
24
30
|
|
25
31
|
MinitestVcr::Spec.configure!
|
26
32
|
|
27
33
|
VCRFilter.sensitive_data! :bd_library_symbol
|
28
34
|
VCRFilter.sensitive_data! :bd_patron
|
35
|
+
VCRFilter.sensitive_data! :bd_api_key
|
36
|
+
|
37
|
+
BorrowDirect::Defaults.api_key = VCRFilter[:bd_api_key]
|
29
38
|
|
30
39
|
# Silly way to not have to rewrite all our tests if we
|
31
40
|
# temporarily disable VCR, make VCR.use_cassette a no-op
|