borrow_direct 1.1.0 → 1.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|