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.
Files changed (76) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +183 -0
  6. data/Rakefile +11 -0
  7. data/bd_metrics/finditem_measure.rb +61 -0
  8. data/bd_metrics/isbn.txt +1088 -0
  9. data/bd_metrics/lccn.txt +1668 -0
  10. data/bd_metrics/oclc.txt +167 -0
  11. data/borrow_direct.gemspec +30 -0
  12. data/lib/borrow_direct/authentication.rb +55 -0
  13. data/lib/borrow_direct/defaults.rb +38 -0
  14. data/lib/borrow_direct/error.rb +17 -0
  15. data/lib/borrow_direct/find_item.rb +149 -0
  16. data/lib/borrow_direct/generate_query.rb +78 -0
  17. data/lib/borrow_direct/request.rb +185 -0
  18. data/lib/borrow_direct/request_item.rb +119 -0
  19. data/lib/borrow_direct/request_query.rb +124 -0
  20. data/lib/borrow_direct/util.rb +18 -0
  21. data/lib/borrow_direct/version.rb +3 -0
  22. data/lib/borrow_direct.rb +19 -0
  23. data/test/authentication_test.rb +79 -0
  24. data/test/find_item_test.rb +159 -0
  25. data/test/generate_query_test.rb +91 -0
  26. data/test/request_item_test.rb +109 -0
  27. data/test/request_query_test.rb +113 -0
  28. data/test/request_test.rb +141 -0
  29. data/test/support/assertions.rb +23 -0
  30. data/test/support/vcr_filter.rb +45 -0
  31. data/test/test_helper.rb +39 -0
  32. data/test/util_test.rb +32 -0
  33. data/test/vcr_cassettes/Authentication/Makes_a_request_succesfully.yml +52 -0
  34. data/test/vcr_cassettes/Authentication/Raises_for_bad_library_symbol.yml +52 -0
  35. data/test/vcr_cassettes/Authentication/Raises_for_bad_patron_barcode.yml +53 -0
  36. data/test/vcr_cassettes/Authentication/get_auth_id/raises_for_a_bad_library_symbol.yml +52 -0
  37. data/test/vcr_cassettes/Authentication/get_auth_id/raises_for_a_bad_patron_barcode.yml +53 -0
  38. data/test/vcr_cassettes/Authentication/get_auth_id/returns_an_auth_id_for_a_good_request.yml +52 -0
  39. data/test/vcr_cassettes/Authentication/raw_request_to_verify_HTTP_api/.yml +52 -0
  40. data/test/vcr_cassettes/FindItem/_find_item_request/finds_a_locally_available_item.yml +49 -0
  41. data/test/vcr_cassettes/FindItem/_find_item_request/finds_a_requestable_item.yml +49 -0
  42. data/test/vcr_cassettes/FindItem/_find_item_request/finds_an_item_that_does_not_exist_in_BD.yml +50 -0
  43. data/test/vcr_cassettes/FindItem/_find_item_request/with_expected_error_PUBFI002/returns_result.yml +40 -0
  44. data/test/vcr_cassettes/FindItem/_find_item_request/works_with_multiple_values.yml +49 -0
  45. data/test/vcr_cassettes/FindItem/find_with_Response/has_an_auth_id.yml +49 -0
  46. data/test/vcr_cassettes/FindItem/find_with_Response/has_nil_auth_id_when_BD_doesn_t_want_to_give_us_one.yml +40 -0
  47. data/test/vcr_cassettes/FindItem/find_with_Response/has_nil_pickup_locations_when_BD_doesn_t_want_to_give_us_them.yml +40 -0
  48. data/test/vcr_cassettes/FindItem/find_with_Response/has_pickup_locations.yml +49 -0
  49. data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_BD_returns_PUBFI002.yml +40 -0
  50. data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_does_not_exist_in_BD.yml +50 -0
  51. data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_item_that_no_libraries_will_lend.yml +50 -0
  52. data/test/vcr_cassettes/FindItem/find_with_Response/not_requestable_for_locally_available_item.yml +49 -0
  53. data/test/vcr_cassettes/FindItem/find_with_Response/requestable_for_requestable_item.yml +49 -0
  54. data/test/vcr_cassettes/FindItem/find_with_Response/requestable_with_multiple_items_if_at_least_one_is_requestable.yml +49 -0
  55. data/test/vcr_cassettes/Request/authentication_id/automatically_fetches_one_when_needed.yml +52 -0
  56. data/test/vcr_cassettes/Request/authentication_id/can_refetch_when_instructed.yml +52 -0
  57. data/test/vcr_cassettes/Request/can_make_a_succesful_request.yml +49 -0
  58. data/test/vcr_cassettes/Request/gets_BD_error_info.yml +41 -0
  59. data/test/vcr_cassettes/Request/raises_on_bad_path.yml +53 -0
  60. data/test/vcr_cassettes/Request/raises_on_bad_request_hash.yml +63 -0
  61. data/test/vcr_cassettes/Request/with_expected_errors/still_returns_result.yml +41 -0
  62. data/test/vcr_cassettes/RequestItem/make_request/make_request_for_a_locally_available_item.yml +90 -0
  63. data/test/vcr_cassettes/RequestItem/make_request/make_request_for_a_requestable_item.yml +89 -0
  64. data/test/vcr_cassettes/RequestItem/make_request/make_request_for_an_unrequestable_item.yml +91 -0
  65. data/test/vcr_cassettes/RequestItem/make_request/raises_for_unrequestable.yml +91 -0
  66. data/test/vcr_cassettes/RequestItem/make_request/returns_number_for_succesful_request.yml +89 -0
  67. data/test/vcr_cassettes/RequestItem/make_request/says_no_for_item_that_BD_returns_PUBRI004.yml +89 -0
  68. data/test/vcr_cassettes/RequestItem/raw_requests_an_unrequestable_item.yml +91 -0
  69. data/test/vcr_cassettes/RequestItem/uses_manually_set_auth_id.yml +89 -0
  70. data/test/vcr_cassettes/RequestItem/with_pickup_location_and_requestable_item/still_works.yml +90 -0
  71. data/test/vcr_cassettes/RequestQuery/raw_request_query_request/returns_results.yml +381 -0
  72. data/test/vcr_cassettes/RequestQuery/raw_request_to_verify_the_BD_HTTP_API.yml +381 -0
  73. data/test/vcr_cassettes/RequestQuery/requests/fetches_default_records.yml +384 -0
  74. data/test/vcr_cassettes/RequestQuery/requests/fetches_full_records.yml +481 -0
  75. data/test/vcr_cassettes/top_level_describe/an_inner_describe/.yml +76 -0
  76. 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