triannon-client 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env_example +16 -2
- data/.rspec +1 -0
- data/README.md +49 -18
- data/Rakefile +15 -2
- data/lib/triannon-client.rb +12 -6
- data/lib/triannon-client/configuration.rb +26 -14
- data/lib/triannon-client/triannon_client.rb +139 -44
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/gets_an_open_annotation_by_ID_with_content_type_application/x-turtle_.yml → CRUD/create_annotation.yml} +192 -132
- data/spec/fixtures/vcr_cassettes/TriannonClientAUTH/with_authentication/behaves_like_authenticate/-_authenticate_returns_true.yml +343 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientCREATE/_post_annotation/with_authentication/behaves_like_create_annotations/POST_401_response_retries_and_logs_RestClient_Exception_message.yml +170 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientCREATE/_post_annotation/with_authentication/behaves_like_create_annotations/POST_403_response_does_not_retry_and_logs_RestClient_Exception_message.yml +170 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientCREATE/_post_annotation/with_authentication/behaves_like_create_annotations/POST_500_response_does_not_retry_and_logs_RestClient_Exception_message.yml +170 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/_get_annotations/returns_an_annotation_list_with_an_annotation_created_by_a_prior_POST.yml → TriannonClientCREATE/_post_annotation/with_authentication/behaves_like_create_annotations/does_not_raise_an_error_when_submitting_a_valid_open_annotation.yml} +203 -319
- data/spec/fixtures/vcr_cassettes/TriannonClientCREATE/_post_annotation/with_authentication/behaves_like_create_annotations/logs_RuntimeError_message.yml +170 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientCREATE/_post_annotation/with_authentication/behaves_like_create_annotations/returns_a_RestClient_Response_object.yml +170 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/_post_annotation → TriannonClientCREATE/_post_annotation/without_authentication/behaves_like_create_annotations}/does_not_raise_an_error_when_submitting_a_valid_open_annotation.yml +29 -27
- data/spec/fixtures/vcr_cassettes/TriannonClientCREATE/clear_annotations.yml +590 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientDELETE/_delete_annotation/with_authentication/behaves_like_delete_annotations/returns_TRUE_when_deleting_an_annotation_that_does_NOT_exist.yml +349 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientDELETE/_delete_annotation/with_authentication/behaves_like_delete_annotations/returns_TRUE_when_deleting_an_annotation_that_exists.yml +332 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientDELETE/_delete_annotation/with_authentication/behaves_like_delete_annotations/validates_the_annotation_ID.yml +288 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/_delete_annotation/returns_TRUE_when_deleting_an_open_annotation_that_does_NOT_exist.yml → TriannonClientDELETE/_delete_annotation/without_authentication/behaves_like_delete_annotations/returns_TRUE_when_deleting_an_annotation_that_does_NOT_exist.yml} +13 -9
- data/spec/fixtures/vcr_cassettes/TriannonClientDELETE/_delete_annotation/without_authentication/behaves_like_delete_annotations/returns_TRUE_when_deleting_an_annotation_that_exists.yml +127 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/_delete_annotation → TriannonClientDELETE/_delete_annotation/without_authentication/behaves_like_delete_annotations}/validates_the_annotation_ID.yml +7 -5
- data/spec/fixtures/vcr_cassettes/TriannonClientDELETE/clear_annotations.yml +594 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient → TriannonClientREAD/GET}/_get_annotations/returns_an_RDF_Graph.yml +30 -23
- data/spec/fixtures/vcr_cassettes/{TriannonClient → TriannonClientREAD/GET}/_get_annotations/returns_an_RDF_Graph_that_contains_an_AnnotationList.yml +30 -23
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/_get_annotations/returns_an_annotation_list_with_an_annotation_created_by_a_prior_POST.yml +302 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/n-quads_.yml → TriannonClientREAD/GET/_get_iiif_annotation/returns_an_RDF_Graph_of_an_open_annotation.yml} +25 -78
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/n-triples_.yml → TriannonClientREAD/GET/_get_oa_annotation/returns_an_RDF_Graph_of_an_open_annotation.yml} +25 -78
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/_response2graph/accepts_a_RestClient_Response_instance.yml +2399 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/csvm_json_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/n-quads_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/n-triples_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/rdf_json_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/rdf_n3_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/trig_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/trix_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/turtle_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/x-ld_json_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/x-trig_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/csv_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/n3_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/plain_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/rdf_n3_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/rdf_turtle_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/tab-separated-values_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/x-nquads_.yml +1231 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application → TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/gets_an_open_annotation_by_ID_with_content_type_application}/ld_json_.yml +25 -78
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/gets_an_open_annotation_by_ID_with_content_type_application/rdf_xml_.yml +68 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/gets_an_open_annotation_by_ID_with_content_type_application/x-turtle_.yml +69 -0
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_custom_content_type/gets_an_open_annotation_by_ID_with_content_type_text/turtle_.yml +69 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type → TriannonClientREAD/GET/annotation_by_ID/using_default_content_type}/checks_the_annotation_ID.yml +25 -78
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/GET/annotation_by_ID/using_default_content_type/returns_an_EMPTY_RDF_graph_with_a_valid_ID_for_NO_annotation_on_the_server.yml +186 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/rdf_json_.yml → TriannonClientREAD/GET/annotation_by_ID/using_default_content_type/returns_an_RDF_graph_with_a_valid_ID_for_an_annotation_on_the_server.yml} +25 -78
- data/spec/fixtures/vcr_cassettes/TriannonClientREAD/clear_annotations.yml +648 -0
- data/spec/fixtures/vcr_cassettes/{TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/gets_an_open_annotation_by_ID_with_content_type_application/rdf_xml_.yml → TriannonClientREAD/create_annotation.yml} +192 -131
- data/spec/lib/triannon-client/configuration_spec.rb +83 -27
- data/spec/lib/triannon-client/triannon_client_auth_spec.rb +61 -0
- data/spec/lib/triannon-client/triannon_client_class_spec.rb +104 -0
- data/spec/lib/triannon-client/triannon_client_create_spec.rb +119 -0
- data/spec/lib/triannon-client/triannon_client_delete_spec.rb +117 -0
- data/spec/lib/triannon-client/triannon_client_read_spec.rb +342 -0
- data/spec/spec_helper.rb +140 -4
- data/triannon-client.gemspec +1 -1
- metadata +112 -153
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/n-quads_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/n-triples_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/rdf_json_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/rdf_n3_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/trig_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/trix_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/turtle_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/x-ld_json_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_application/x-trig_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/n3_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/rdf_n3_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/rdf_turtle_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/cannot_get_an_open_annotation_by_ID_with_content_type_text/x-nquads_.yml +0 -3995
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/gets_an_open_annotation_by_ID_with_content_type_application/ld_json_.yml +0 -4946
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/gets_an_open_annotation_by_ID_with_content_type_text/turtle_.yml +0 -2566
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/rdf_n3_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/rdf_xml_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/trig_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/trix_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/turtle_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/x-ld_json_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/x-trig_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_application/x-turtle_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_text/n3_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_text/rdf_n3_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_text/rdf_turtle_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_text/turtle_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_content_type_text/x-nquads_.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/logs_exceptions.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/raises_an_argument_error_with_a_nil_ID.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/raises_an_argument_error_with_an_empty_string_ID.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/raises_an_argument_error_with_an_integer_ID.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/requests_an_open_annotation_by_ID_accepting_a_default_JSON-LD_content.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/returns_an_EMPTY_RDF_graph_for_a_500_server_response.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/returns_an_EMPTY_RDF_graph_with_a_valid_ID_for_NO_annotation_on_the_server.yml +0 -2561
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/returns_an_RDF_graph_with_a_valid_ID_for_an_annotation_on_the_server.yml +0 -4946
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_iiif_annotation/requests_an_open_annotation_by_ID_using_a_IIIF_profile.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_iiif_annotation/returns_an_RDF_Graph_of_an_open_annotation.yml +0 -2746
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_oa_annotation/requests_an_open_annotation_by_ID_using_an_OA_profile.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_oa_annotation/returns_an_RDF_Graph_of_an_open_annotation.yml +0 -4946
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/does_not_log_exceptions_for_missing_annotations_404_responses_.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/does_not_log_exceptions_for_missing_annotations_410_responses_.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/logs_exceptions.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_FALSE_for_a_500_response_to_a_DELETE_request.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_TRUE_for_a_200_response_to_a_DELETE_request.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_TRUE_for_a_202_response_to_a_DELETE_request.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_TRUE_for_a_204_response_to_a_DELETE_request.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_TRUE_for_a_404_response_to_a_DELETE_request.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_TRUE_for_a_410_response_to_a_DELETE_request.yml +0 -64
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_TRUE_when_deleting_an_open_annotation_that_exists.yml +0 -2549
- data/spec/fixtures/vcr_cassettes/TriannonClient/_post_annotation/logs_exceptions.yml +0 -5355
- data/spec/fixtures/vcr_cassettes/TriannonClient/_post_annotation/logs_exceptions_for_RestClient_Exception.yml +0 -5355
- data/spec/fixtures/vcr_cassettes/TriannonClient/_post_annotation/returns_a_RestClient_Response_object.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_id/returns_a_String_ID_from_the_RDF_URI_of_an_annotation.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_id/returns_a_String_ID_that_is_not_empty.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_uris/returns_an_RDF_URI_that_is_a_valid_URI.yml +0 -2551
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_uris/returns_an_array_of_RDF_URI_from_an_RDF_Graph_of_an_annotation.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/accepts_a_RestClient_Response_instance.yml +0 -4898
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/raises_ArgumentError_when_given_an_empty_String.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/raises_ArgumentError_when_given_nil.yml +0 -2502
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/returns_an_RDF_Graph.yml +0 -2502
- data/spec/lib/triannon-client/triannon_client_spec.rb +0 -546
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_examples "authenticate" do |auth_required|
|
4
|
+
|
5
|
+
let(:tc) {
|
6
|
+
if auth_required
|
7
|
+
triannon_config_auth
|
8
|
+
else
|
9
|
+
triannon_config_no_auth
|
10
|
+
end
|
11
|
+
TriannonClient::TriannonClient.new
|
12
|
+
}
|
13
|
+
|
14
|
+
def check_header
|
15
|
+
headers = tc.site.headers
|
16
|
+
expect(headers).to include(:Authorization)
|
17
|
+
expect(headers[:Authorization]).to match(/Bearer/)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "- #authenticate returns #{auth_required}" do
|
21
|
+
if auth_required
|
22
|
+
expect(tc.authenticate).to be_truthy
|
23
|
+
check_header
|
24
|
+
else
|
25
|
+
expect(tc.authenticate).to be false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "- #authenticate! returns #{auth_required}" do
|
30
|
+
# Authenticate and then test that authenticate!
|
31
|
+
# will reset and renew the authentication.
|
32
|
+
auth1 = tc.authenticate
|
33
|
+
check_header if auth_required
|
34
|
+
expect(tc.site.headers).to receive(:delete)
|
35
|
+
if auth_required
|
36
|
+
# renew the authentication
|
37
|
+
expect(tc.authenticate!).to be_truthy
|
38
|
+
check_header
|
39
|
+
auth2 = tc.site.headers[:Authorization]
|
40
|
+
expect(auth1).not_to eql(auth2)
|
41
|
+
else
|
42
|
+
expect(tc.authenticate!).to be false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
describe 'TriannonClientAUTH', :vcr do
|
50
|
+
|
51
|
+
context 'without authentication' do
|
52
|
+
auth_required = false # it's not required
|
53
|
+
it_behaves_like 'authenticate', auth_required
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with authentication' do
|
57
|
+
auth_required = true # it must succeed
|
58
|
+
it_behaves_like 'authenticate', auth_required
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# ::TriannonClient::TriannonClient class specs
|
4
|
+
|
5
|
+
describe 'TriannonClientClass' do
|
6
|
+
|
7
|
+
let(:tc) {
|
8
|
+
triannon_config_no_auth # spec_helper
|
9
|
+
TriannonClient::TriannonClient.new
|
10
|
+
}
|
11
|
+
|
12
|
+
describe 'has constants:' do
|
13
|
+
it 'CONTENT_TYPES' do
|
14
|
+
const = TriannonClient::TriannonClient::CONTENT_TYPES
|
15
|
+
expect(const).to be_instance_of Array
|
16
|
+
expect(const).to include('application/ld+json')
|
17
|
+
end
|
18
|
+
it 'PROFILE_TYPE_IIIF' do
|
19
|
+
const = TriannonClient::TriannonClient::PROFILE_IIIF
|
20
|
+
expect(const).to be_instance_of String
|
21
|
+
expect(const).to include('http://iiif.io/api/presentation/2/context.json')
|
22
|
+
end
|
23
|
+
it 'PROFILE_TYPE_OA' do
|
24
|
+
const = TriannonClient::TriannonClient::PROFILE_OA
|
25
|
+
expect(const).to be_instance_of String
|
26
|
+
expect(const).to include('http://www.w3.org/ns/oa-context-20130208.json')
|
27
|
+
end
|
28
|
+
it 'CONTENT_TYPE_IIIF' do
|
29
|
+
const = TriannonClient::TriannonClient::CONTENT_TYPE_IIIF
|
30
|
+
expect(const).to be_instance_of String
|
31
|
+
expect(const).to include('application/ld+json')
|
32
|
+
expect(const).to include('http://iiif.io/api/presentation/2/context.json')
|
33
|
+
end
|
34
|
+
it 'CONTENT_TYPE_OA' do
|
35
|
+
const = TriannonClient::TriannonClient::CONTENT_TYPE_OA
|
36
|
+
expect(const).to be_instance_of String
|
37
|
+
expect(const).to include('application/ld+json')
|
38
|
+
expect(const).to include('http://www.w3.org/ns/oa-context-20130208.json')
|
39
|
+
end
|
40
|
+
it 'JSONLD_TYPE' do
|
41
|
+
const = TriannonClient::TriannonClient::JSONLD_TYPE
|
42
|
+
expect(const).to be_instance_of String
|
43
|
+
expect(const).to eql('application/ld+json')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'public attributes:' do
|
48
|
+
# attribute accessors
|
49
|
+
it 'config' do
|
50
|
+
expect(tc).to respond_to(:config)
|
51
|
+
end
|
52
|
+
it 'site' do
|
53
|
+
expect(tc).to respond_to(:site)
|
54
|
+
end
|
55
|
+
it 'auth' do
|
56
|
+
expect(tc).to respond_to(:auth)
|
57
|
+
end
|
58
|
+
it 'container' do
|
59
|
+
expect(tc).to respond_to(:container)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'public methods:' do
|
64
|
+
# methods
|
65
|
+
it 'authenticate' do
|
66
|
+
expect(tc).to respond_to(:authenticate)
|
67
|
+
end
|
68
|
+
it 'delete_annotation' do
|
69
|
+
expect(tc).to respond_to(:delete_annotation)
|
70
|
+
end
|
71
|
+
it 'get_annotations' do
|
72
|
+
expect(tc).to respond_to(:get_annotations)
|
73
|
+
end
|
74
|
+
it 'get_annotation' do
|
75
|
+
expect(tc).to respond_to(:get_annotation)
|
76
|
+
end
|
77
|
+
it 'get_iiif_annotation' do
|
78
|
+
expect(tc).to respond_to(:get_iiif_annotation)
|
79
|
+
end
|
80
|
+
it 'get_oa_annotation' do
|
81
|
+
expect(tc).to respond_to(:get_oa_annotation)
|
82
|
+
end
|
83
|
+
# utilities
|
84
|
+
it 'response2graph' do
|
85
|
+
expect(tc).to respond_to(:response2graph)
|
86
|
+
end
|
87
|
+
it 'annotation_id' do
|
88
|
+
expect(tc).to respond_to(:annotation_id)
|
89
|
+
end
|
90
|
+
it 'annotation_uris' do
|
91
|
+
expect(tc).to respond_to(:annotation_uris)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'private:' do
|
96
|
+
it 'check_id' do
|
97
|
+
expect(tc).not_to respond_to(:check_id)
|
98
|
+
end
|
99
|
+
it 'check_content_type' do
|
100
|
+
expect(tc).not_to respond_to(:check_content_type)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_examples "create annotations" do |auth_required|
|
4
|
+
|
5
|
+
let(:tc) {
|
6
|
+
if auth_required
|
7
|
+
triannon_config_auth
|
8
|
+
else
|
9
|
+
triannon_config_no_auth
|
10
|
+
end
|
11
|
+
TriannonClient::TriannonClient.new
|
12
|
+
}
|
13
|
+
|
14
|
+
def check_authentication(required)
|
15
|
+
auth = tc.authenticate
|
16
|
+
if required
|
17
|
+
expect(auth).to be_truthy
|
18
|
+
else
|
19
|
+
expect(auth).to be false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:exception_data) { 'post_exception' }
|
24
|
+
let(:exception_post) {
|
25
|
+
{
|
26
|
+
"commit"=>"Create Annotation",
|
27
|
+
"annotation"=>{"data"=>exception_data}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
let(:exception_msg) { 'create_exception' }
|
31
|
+
|
32
|
+
def raise_restclient_exception(status)
|
33
|
+
response = double
|
34
|
+
allow(response).to receive(:is_a?).and_return(RestClient::Response)
|
35
|
+
allow(response).to receive(:headers).and_return(jsonld_content)
|
36
|
+
allow(response).to receive(:body).and_return(exception_msg)
|
37
|
+
allow(response).to receive(:code).and_return(status)
|
38
|
+
exception = RestClient::Exception.new(response)
|
39
|
+
allow_any_instance_of(RestClient::Resource).to receive(:post).with(exception_post).and_raise(exception)
|
40
|
+
if status == 401
|
41
|
+
expect(tc).to receive(:authenticate).once # retry triggers authentication
|
42
|
+
else
|
43
|
+
expect(tc).not_to receive(:authenticate) # no retry
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'does not raise an error when submitting a valid open annotation' do
|
48
|
+
check_authentication(auth_required)
|
49
|
+
response = nil
|
50
|
+
expect do
|
51
|
+
response = tc.post_annotation(jsonld_oa)
|
52
|
+
end.not_to raise_error
|
53
|
+
# Double check the POST by deleting the annotation.
|
54
|
+
# If the POST was successful, the DELETE should work too.
|
55
|
+
graph = tc.response2graph(response)
|
56
|
+
uri = tc.annotation_uris(graph).first
|
57
|
+
id = tc.annotation_id(uri)
|
58
|
+
expect(tc.delete_annotation(id)).to be true
|
59
|
+
end
|
60
|
+
it 'returns a RestClient::Response object' do
|
61
|
+
# The response behaves primarily as a String, so it can not be tested
|
62
|
+
# as an instance of RestClient::Response, but it can be tested to respond
|
63
|
+
# to RestClient::Response methods.
|
64
|
+
check_authentication(auth_required)
|
65
|
+
anno = create_annotation
|
66
|
+
r = anno[:response]
|
67
|
+
expect(r.is_a? RestClient::Response).to be true
|
68
|
+
expect(r).to respond_to(:code)
|
69
|
+
expect(r).to respond_to(:body)
|
70
|
+
expect(r).to respond_to(:headers)
|
71
|
+
end
|
72
|
+
it 'POST 401 response retries and logs RestClient::Exception message' do
|
73
|
+
check_authentication(auth_required)
|
74
|
+
raise_restclient_exception(401)
|
75
|
+
expect(TriannonClient.configuration.logger).to receive(:error).with(/#{exception_msg}/)
|
76
|
+
tc.post_annotation(exception_data)
|
77
|
+
end
|
78
|
+
it 'POST 403 response does not retry and logs RestClient::Exception message' do
|
79
|
+
check_authentication(auth_required)
|
80
|
+
raise_restclient_exception(403)
|
81
|
+
expect(TriannonClient.configuration.logger).to receive(:error).with(/#{exception_msg}/)
|
82
|
+
tc.post_annotation(exception_data)
|
83
|
+
end
|
84
|
+
it 'POST 500 response does not retry and logs RestClient::Exception message' do
|
85
|
+
check_authentication(auth_required)
|
86
|
+
raise_restclient_exception(500)
|
87
|
+
expect(TriannonClient.configuration.logger).to receive(:error).with(/#{exception_msg}/)
|
88
|
+
tc.post_annotation(exception_data)
|
89
|
+
end
|
90
|
+
it 'logs RuntimeError message' do
|
91
|
+
check_authentication(auth_required)
|
92
|
+
exception = RuntimeError.new(exception_msg)
|
93
|
+
allow_any_instance_of(RestClient::Resource).to receive(:post).with(exception_post).and_raise(exception)
|
94
|
+
expect(TriannonClient.configuration.logger).to receive(:error).with(/#{exception_msg}/)
|
95
|
+
tc.post_annotation(exception_data)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
describe 'TriannonClientCREATE', :vcr do
|
101
|
+
|
102
|
+
after :all do
|
103
|
+
clear_annotations('TriannonClientCREATE/clear_annotations')
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#post_annotation" do
|
107
|
+
|
108
|
+
context 'without authentication' do
|
109
|
+
auth_required = false # it's not required
|
110
|
+
it_behaves_like 'create annotations', auth_required
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'with authentication' do
|
114
|
+
auth_required = true # it must succeed
|
115
|
+
it_behaves_like 'create annotations', auth_required
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_examples "delete annotations" do |auth_required|
|
4
|
+
|
5
|
+
let(:tc) {
|
6
|
+
if auth_required
|
7
|
+
triannon_config_auth
|
8
|
+
else
|
9
|
+
triannon_config_no_auth
|
10
|
+
end
|
11
|
+
TriannonClient::TriannonClient.new
|
12
|
+
}
|
13
|
+
|
14
|
+
def test_delete_for_response_code(anno_id, status, result)
|
15
|
+
response = double
|
16
|
+
allow(response).to receive(:is_a?).and_return(RestClient::Response)
|
17
|
+
allow(response).to receive(:headers).and_return(jsonld_content)
|
18
|
+
allow(response).to receive(:body).and_return('delete_annotation')
|
19
|
+
allow(response).to receive(:code).and_return(status)
|
20
|
+
exception = RestClient::Exception.new(response)
|
21
|
+
if [401, 404, 410, 500].include? status
|
22
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete).and_raise(exception)
|
23
|
+
if status == 401
|
24
|
+
expect(tc).to receive(:authenticate).once # retry triggers auth
|
25
|
+
else
|
26
|
+
expect(tc).not_to receive(:authenticate) # no retry
|
27
|
+
end
|
28
|
+
else
|
29
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete).and_return(response)
|
30
|
+
expect(tc).not_to receive(:authenticate) # no retry
|
31
|
+
end
|
32
|
+
expect(tc.delete_annotation(anno_id)).to be result
|
33
|
+
end
|
34
|
+
it "DELETE 200 response returns true" do
|
35
|
+
test_delete_for_response_code('200_is_true', 200, true)
|
36
|
+
end
|
37
|
+
it "DELETE 202 response returns true" do
|
38
|
+
test_delete_for_response_code('202_is_true', 202, true)
|
39
|
+
end
|
40
|
+
it "DELETE 204 response returns true" do
|
41
|
+
test_delete_for_response_code('204_is_true', 204, true)
|
42
|
+
end
|
43
|
+
it "DELETE 401 response initiates a retry with authentication" do
|
44
|
+
test_delete_for_response_code('401_is_retry', 401, false)
|
45
|
+
end
|
46
|
+
it "DELETE 404 response returns true" do
|
47
|
+
test_delete_for_response_code('404_is_true', 404, true)
|
48
|
+
end
|
49
|
+
it "DELETE 410 response returns true" do
|
50
|
+
test_delete_for_response_code('410_is_true', 410, true)
|
51
|
+
end
|
52
|
+
it "DELETE 500 response returns false" do
|
53
|
+
test_delete_for_response_code('500_is_false', 500, false)
|
54
|
+
end
|
55
|
+
it 'DELETE 404|410 does not log exceptions' do
|
56
|
+
expect(tc.config.logger).not_to receive(:error)
|
57
|
+
test_delete_for_response_code('404_is_true', 404, true)
|
58
|
+
test_delete_for_response_code('410_is_true', 410, true)
|
59
|
+
end
|
60
|
+
it 'DELETE 500 logs exceptions' do
|
61
|
+
expect(tc.config.logger).to receive(:error)
|
62
|
+
test_delete_for_response_code('500_is_false', 500, false)
|
63
|
+
end
|
64
|
+
it 'validates the annotation ID' do
|
65
|
+
expect(tc).to receive(:check_id)
|
66
|
+
tc.delete_annotation('checking_anno_id')
|
67
|
+
end
|
68
|
+
it 'raises ArgumentError for an invalid annotation ID' do
|
69
|
+
expect_any_instance_of(RestClient::Resource).not_to receive(:delete)
|
70
|
+
expect { tc.delete_annotation('') }.to raise_error(ArgumentError)
|
71
|
+
expect { tc.delete_annotation(nil) }.to raise_error(ArgumentError)
|
72
|
+
end
|
73
|
+
it 'uses RestClient::Resource.delete to DELETE a valid annotation ID' do
|
74
|
+
expect_any_instance_of(RestClient::Resource).to receive(:delete)
|
75
|
+
tc.delete_annotation(SecureRandom.uuid)
|
76
|
+
end
|
77
|
+
it 'returns TRUE when deleting an annotation that exists' do
|
78
|
+
anno = create_annotation
|
79
|
+
expect( tc.delete_annotation(anno[:id]) ).to be true
|
80
|
+
graph = tc.get_annotation(anno[:id])
|
81
|
+
graph_is_empty(graph)
|
82
|
+
end
|
83
|
+
it 'returns TRUE when deleting an annotation that does NOT exist' do
|
84
|
+
id = 'anno_does_not_exist'
|
85
|
+
graph = tc.get_annotation(id)
|
86
|
+
graph_is_empty(graph)
|
87
|
+
expect( tc.delete_annotation(id) ).to be true
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
describe 'TriannonClientDELETE', :vcr do
|
94
|
+
|
95
|
+
# before :all do
|
96
|
+
# # create a new annotation and call all the response processing utils.
|
97
|
+
# @anno = create_annotation('TriannonClientDELETE/create_annotation')
|
98
|
+
# end
|
99
|
+
|
100
|
+
after :all do
|
101
|
+
clear_annotations('TriannonClientDELETE/clear_annotations')
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#delete_annotation" do
|
105
|
+
|
106
|
+
context 'without authentication' do
|
107
|
+
auth_required = false # it's not required
|
108
|
+
it_behaves_like 'delete annotations', auth_required
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with authentication' do
|
112
|
+
auth_required = true # it must succeed
|
113
|
+
it_behaves_like 'delete annotations', auth_required
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,342 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# ::TriannonClient::TriannonClient GET specs
|
4
|
+
# The GET requests do not require authentication.
|
5
|
+
|
6
|
+
describe 'TriannonClientREAD', :vcr do
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
# create a new annotation and call all the response processing utils.
|
10
|
+
@anno = create_annotation('TriannonClientREAD/create_annotation')
|
11
|
+
end
|
12
|
+
|
13
|
+
after :all do
|
14
|
+
clear_annotations('TriannonClientREAD/clear_annotations')
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:tc) {
|
18
|
+
# triannon_config_auth
|
19
|
+
TriannonClient::TriannonClient.new
|
20
|
+
}
|
21
|
+
|
22
|
+
def request_anno_with_content_type(content_type)
|
23
|
+
expect_any_instance_of(RestClient::Resource).to receive(:get).with(hash_including(:accept => content_type) )
|
24
|
+
tc.get_annotation(@anno[:id], content_type)
|
25
|
+
end
|
26
|
+
|
27
|
+
def gets_anno_with_content_type(content_type)
|
28
|
+
graph = tc.get_annotation(@anno[:id], content_type)
|
29
|
+
graph_contains_open_annotation(graph, @anno[:uris])
|
30
|
+
end
|
31
|
+
|
32
|
+
def cannot_get_anno_with_content_type(content_type)
|
33
|
+
graph = tc.get_annotation(@anno[:id], content_type)
|
34
|
+
graph_is_empty(graph)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
let(:exception_msg) { 'get_exception' }
|
39
|
+
def raise_restclient_exception(status)
|
40
|
+
response = double
|
41
|
+
allow(response).to receive(:is_a?).and_return(RestClient::Response)
|
42
|
+
allow(response).to receive(:headers).and_return(jsonld_content)
|
43
|
+
allow(response).to receive(:body).and_return(exception_msg)
|
44
|
+
allow(response).to receive(:code).and_return(status)
|
45
|
+
exception = RestClient::Exception.new(response)
|
46
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).with(jsonld_accept).and_raise(exception)
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'GET' do
|
50
|
+
|
51
|
+
describe "#get_annotations" do
|
52
|
+
it 'returns an RDF::Graph' do
|
53
|
+
graph = tc.get_annotations
|
54
|
+
graph_contains_statements(graph)
|
55
|
+
end
|
56
|
+
it 'returns an RDF::Graph that contains an AnnotationList' do
|
57
|
+
graph = tc.get_annotations
|
58
|
+
anno_list_uri = RDF::URI.parse('http://iiif.io/api/presentation/2#AnnotationList')
|
59
|
+
result = graph.query([nil, nil, anno_list_uri])
|
60
|
+
expect(result.size).to eql(1)
|
61
|
+
end
|
62
|
+
it 'returns an annotation list with an annotation created by a prior POST' do
|
63
|
+
graph = tc.get_annotations
|
64
|
+
graph_contains_open_annotation(graph, @anno[:uris])
|
65
|
+
end
|
66
|
+
it '404 response logs exceptions for RestClient::Exception' do
|
67
|
+
raise_restclient_exception(404)
|
68
|
+
expect(tc.config.logger).to receive(:error).with(/404/)
|
69
|
+
tc.get_annotations
|
70
|
+
end
|
71
|
+
it '500 response returns an EMPTY RDF graph' do
|
72
|
+
raise_restclient_exception(500)
|
73
|
+
graph = tc.get_annotations
|
74
|
+
graph_is_empty(graph)
|
75
|
+
end
|
76
|
+
it '500 response logs exceptions for RestClient::Exception' do
|
77
|
+
raise_restclient_exception(500)
|
78
|
+
expect(tc.config.logger).to receive(:error).with(/#{exception_msg}/)
|
79
|
+
tc.get_annotations
|
80
|
+
end
|
81
|
+
it 'logs exceptions for RuntimeError' do
|
82
|
+
exception = RuntimeError.new('get_exception')
|
83
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).with(jsonld_accept).and_raise(exception)
|
84
|
+
expect(tc.config.logger).to receive(:error).with(/get_exception/)
|
85
|
+
tc.get_annotations
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#get_iiif_annotation" do
|
90
|
+
# the mime type is fixed for this method
|
91
|
+
it 'requests an open annotation by ID, using a IIIF profile' do
|
92
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uris])
|
93
|
+
content_type = TriannonClient::TriannonClient::CONTENT_TYPE_IIIF
|
94
|
+
expect(tc).to receive(:get_annotation).with(@anno[:id], content_type)
|
95
|
+
tc.get_iiif_annotation(@anno[:id])
|
96
|
+
end
|
97
|
+
it 'returns an RDF::Graph of an open annotation' do
|
98
|
+
graph = tc.get_iiif_annotation(@anno[:id])
|
99
|
+
graph_contains_statements(graph)
|
100
|
+
graph_contains_open_annotation(graph, @anno[:uris])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#get_oa_annotation" do
|
105
|
+
# the mime type is fixed for this method
|
106
|
+
it 'requests an open annotation by ID, using an OA profile' do
|
107
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uris])
|
108
|
+
content_type = TriannonClient::TriannonClient::CONTENT_TYPE_OA
|
109
|
+
expect(tc).to receive(:get_annotation).with(@anno[:id], content_type)
|
110
|
+
tc.get_oa_annotation(@anno[:id])
|
111
|
+
end
|
112
|
+
it 'returns an RDF::Graph of an open annotation' do
|
113
|
+
graph = tc.get_oa_annotation(@anno[:id])
|
114
|
+
graph_contains_statements(graph)
|
115
|
+
graph_contains_open_annotation(graph, @anno[:uris])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#response2graph' do
|
120
|
+
it 'accepts a RestClient::Response instance' do
|
121
|
+
r = @anno[:response]
|
122
|
+
expect{tc.response2graph(r)}.not_to raise_error
|
123
|
+
end
|
124
|
+
it 'returns an RDF::Graph' do
|
125
|
+
expect(@anno[:graph]).to be_instance_of RDF::Graph
|
126
|
+
graph_contains_statements(@anno[:graph])
|
127
|
+
end
|
128
|
+
it 'raises ArgumentError when given nil' do
|
129
|
+
expect{tc.response2graph(nil)}.to raise_error(ArgumentError)
|
130
|
+
end
|
131
|
+
it 'raises ArgumentError when given an empty String' do
|
132
|
+
expect{tc.response2graph('')}.to raise_error(ArgumentError)
|
133
|
+
end
|
134
|
+
it 'raises ArgumentError when response content-type is unacceptable' do
|
135
|
+
h = {content_type: 'unacceptable'}
|
136
|
+
r = double
|
137
|
+
allow(r).to receive(:is_a?).and_return(RestClient::Response)
|
138
|
+
allow(r).to receive(:headers).and_return(h)
|
139
|
+
expect{tc.response2graph('')}.to raise_error(ArgumentError)
|
140
|
+
end
|
141
|
+
it 'returns an empty RDF::Graph for failure to parse input' do
|
142
|
+
r = double
|
143
|
+
allow(r).to receive(:is_a?).and_return(RestClient::Response)
|
144
|
+
allow(r).to receive(:code).and_return(200)
|
145
|
+
allow(r).to receive(:headers).and_return(jsonld_content)
|
146
|
+
allow(r).to receive(:body).and_return('malformed json')
|
147
|
+
g = tc.response2graph(r)
|
148
|
+
expect(g).to be_instance_of RDF::Graph
|
149
|
+
expect(g).to be_empty
|
150
|
+
h = {content_type: 'application/rdf+xml'}
|
151
|
+
allow(r).to receive(:headers).and_return(h)
|
152
|
+
allow(r).to receive(:body).and_return('malformed rdf+xml')
|
153
|
+
g = tc.response2graph(r)
|
154
|
+
expect(g).to be_instance_of RDF::Graph
|
155
|
+
expect(g).to be_empty
|
156
|
+
# h = {content_type: 'application/turtle'}
|
157
|
+
# allow(r).to receive(:headers).and_return(h)
|
158
|
+
# allow(r).to receive(:body).and_return('malformed turtle')
|
159
|
+
# g = tc.response2graph(r)
|
160
|
+
# expect(g).to be_instance_of RDF::Graph
|
161
|
+
# expect(g).to be_empty
|
162
|
+
end
|
163
|
+
it 'logs exceptions and returns an empty RDF::Graph' do
|
164
|
+
r = double
|
165
|
+
allow(r).to receive(:is_a?).and_return(RestClient::Response)
|
166
|
+
allow(r).to receive(:headers).and_return(jsonld_content)
|
167
|
+
allow(r).to receive(:body).and_raise(RuntimeError, 'oops!')
|
168
|
+
expect(tc.config.logger).to receive(:error).with(/oops!/)
|
169
|
+
g = tc.response2graph(r)
|
170
|
+
expect(g).to be_instance_of RDF::Graph
|
171
|
+
expect(g).to be_empty
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#annotation_uris" do
|
178
|
+
it "returns an array of RDF::URI from an RDF::Graph of an annotation" do
|
179
|
+
expect(@anno[:graph]).to be_instance_of RDF::Graph
|
180
|
+
expect(@anno[:uris]).to be_instance_of Array
|
181
|
+
expect(@anno[:uris]).not_to be_empty
|
182
|
+
expect(@anno[:uris].first).to be_instance_of RDF::URI
|
183
|
+
end
|
184
|
+
it "returns an RDF::URI that is a valid URI" do
|
185
|
+
expect(@anno[:uris].first).to match(/\A#{URI::regexp}\z/)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "#annotation_id" do
|
190
|
+
it "returns a String ID from the RDF::URI of an annotation" do
|
191
|
+
expect(@anno[:uris].first).to be_instance_of RDF::URI
|
192
|
+
expect(@anno[:id]).to be_instance_of String
|
193
|
+
end
|
194
|
+
it "returns a String ID that is not empty" do
|
195
|
+
expect(@anno[:id]).to be_instance_of String
|
196
|
+
expect(@anno[:id]).not_to be_empty
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "annotation by ID" do
|
201
|
+
|
202
|
+
context 'using default content type' do
|
203
|
+
|
204
|
+
it 'checks the annotation ID' do
|
205
|
+
expect(tc).to receive(:check_id)
|
206
|
+
graph = tc.get_annotation(@anno[:id])
|
207
|
+
graph_contains_statements(graph)
|
208
|
+
end
|
209
|
+
it 'raises an argument error with a nil ID' do
|
210
|
+
expect{tc.get_annotation(nil)}.to raise_error(ArgumentError)
|
211
|
+
end
|
212
|
+
it 'raises an argument error with an integer ID' do
|
213
|
+
expect{tc.get_annotation(0)}.to raise_error(ArgumentError)
|
214
|
+
end
|
215
|
+
it 'raises an argument error with an empty string ID' do
|
216
|
+
expect{tc.get_annotation('')}.to raise_error(ArgumentError)
|
217
|
+
end
|
218
|
+
it 'requests an open annotation by ID, using JSON-LD content' do
|
219
|
+
jsonld = TriannonClient::TriannonClient::JSONLD_TYPE
|
220
|
+
expect_any_instance_of(RestClient::Resource).to receive(:get).with(hash_including(:accept => jsonld) )
|
221
|
+
# does not work using expect(tc.container).to receive(:get) etc.
|
222
|
+
tc.get_annotation(@anno[:id])
|
223
|
+
end
|
224
|
+
it 'returns an RDF graph with a valid ID for an annotation on the server' do
|
225
|
+
graph = tc.get_annotation(@anno[:id])
|
226
|
+
graph_contains_open_annotation(graph, @anno[:uris])
|
227
|
+
end
|
228
|
+
it 'returns an EMPTY RDF graph with a valid ID for NO annotation on the server' do
|
229
|
+
id = SecureRandom.uuid
|
230
|
+
graph = tc.get_annotation(id)
|
231
|
+
graph_is_empty(graph)
|
232
|
+
end
|
233
|
+
it '404 response logs exceptions for RestClient::Exception' do
|
234
|
+
raise_restclient_exception(404)
|
235
|
+
expect(tc.config.logger).to receive(:error).with(/404/)
|
236
|
+
tc.get_annotation('raise_get_exception')
|
237
|
+
end
|
238
|
+
it '500 response returns an EMPTY RDF graph' do
|
239
|
+
raise_restclient_exception(500)
|
240
|
+
graph = tc.get_annotation(@anno[:id])
|
241
|
+
graph_is_empty(graph)
|
242
|
+
end
|
243
|
+
it '500 response logs exceptions for RestClient::Exception' do
|
244
|
+
raise_restclient_exception(500)
|
245
|
+
expect(tc.config.logger).to receive(:error).with(/#{exception_msg}/)
|
246
|
+
tc.get_annotation(@anno[:id])
|
247
|
+
end
|
248
|
+
it 'logs exceptions for RuntimeError' do
|
249
|
+
exception = RuntimeError.new('get_exception')
|
250
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).with(jsonld_accept).and_raise(exception)
|
251
|
+
expect(tc.config.logger).to receive(:error).with(/get_exception/)
|
252
|
+
tc.get_annotation(@anno[:id])
|
253
|
+
end
|
254
|
+
end # using default content type
|
255
|
+
|
256
|
+
context 'using custom content type' do
|
257
|
+
# Content types could be supported for RDF::Format.content_types.keys,
|
258
|
+
# but not all of them are supported. The supported content types for
|
259
|
+
# triannon are defined in
|
260
|
+
# https://github.com/sul-dlss/triannon/blob/master/config/initializers/mime_types.rb
|
261
|
+
# https://github.com/sul-dlss/triannon/blob/master/app/controllers/triannon/annotations_controller.rb
|
262
|
+
# https://github.com/sul-dlss/triannon/blob/master/app/controllers/triannon/search_controller.rb
|
263
|
+
# The default content type is "application/ld+json" and, at the time of
|
264
|
+
# writing, triannon also supports:
|
265
|
+
# turtle as: ["application/x-turtle", "text/turtle"]
|
266
|
+
# rdf+xml as: ["application/rdf+xml", "text/rdf+xml", "text/rdf"]
|
267
|
+
# json as: ["application/json", "text/x-json", "application/jsonrequest"]
|
268
|
+
# xml as: ["application/xml", "text/xml", "application/x-xml"]
|
269
|
+
# html
|
270
|
+
|
271
|
+
# The client supports any format in RDF::Format.content_types, so the
|
272
|
+
# following are not included (as of July 2015):
|
273
|
+
# "application/json" => true,
|
274
|
+
# "application/jsonrequest" => true,
|
275
|
+
# "text/x-json" => true,
|
276
|
+
# "text/rdf+xml" => true,
|
277
|
+
# "text/rdf" => true,
|
278
|
+
# "application/xml" => true,
|
279
|
+
# "text/xml" => true,
|
280
|
+
# "application/x-xml" => true,
|
281
|
+
|
282
|
+
# html and xhtml are supported by RDF::Format, so they can be used,
|
283
|
+
# but they fail to return a proper RDF::Graph
|
284
|
+
# "text/html"=> true,
|
285
|
+
# "application/xhtml+xml"=> true,
|
286
|
+
|
287
|
+
# content types that work
|
288
|
+
content_types = {
|
289
|
+
"application/ld+json"=> true,
|
290
|
+
"application/rdf+xml"=> true,
|
291
|
+
"text/turtle"=> true,
|
292
|
+
"application/x-turtle"=> true,
|
293
|
+
}
|
294
|
+
# content types that fail
|
295
|
+
content_types.merge!({
|
296
|
+
"application/x-ld+json"=> false,
|
297
|
+
"application/rdf+json"=> false,
|
298
|
+
"text/rdf+turtle"=> false,
|
299
|
+
"application/turtle"=> false,
|
300
|
+
"application/n-triples"=> false,
|
301
|
+
"application/rdf+n3"=> false,
|
302
|
+
"text/n3"=> false,
|
303
|
+
"text/rdf+n3"=> false,
|
304
|
+
"text/plain"=> false,
|
305
|
+
"application/n-quads"=> false,
|
306
|
+
"text/x-nquads"=> false,
|
307
|
+
"application/trig"=> false,
|
308
|
+
"application/x-trig"=> false,
|
309
|
+
"application/trix"=> false,
|
310
|
+
"text/csv"=> false,
|
311
|
+
"text/tab-separated-values"=>false,
|
312
|
+
"application/csvm+json"=>false,
|
313
|
+
})
|
314
|
+
specs = content_types.map do |type,success|
|
315
|
+
request_spec = <<EOS
|
316
|
+
it 'requests an open annotation by ID, with content type "#{type}"' do
|
317
|
+
request_anno_with_content_type('#{type}')
|
318
|
+
end
|
319
|
+
EOS
|
320
|
+
if success
|
321
|
+
get_spec = <<EOS
|
322
|
+
it 'gets an open annotation by ID, with content type "#{type}"' do
|
323
|
+
gets_anno_with_content_type('#{type}')
|
324
|
+
end
|
325
|
+
EOS
|
326
|
+
else
|
327
|
+
get_spec = <<EOS
|
328
|
+
it 'cannot get an open annotation by ID, with content type "#{type}"' do
|
329
|
+
cannot_get_anno_with_content_type('#{type}')
|
330
|
+
end
|
331
|
+
EOS
|
332
|
+
end
|
333
|
+
request_spec + get_spec
|
334
|
+
end
|
335
|
+
eval(specs.join)
|
336
|
+
end # using custom content type
|
337
|
+
|
338
|
+
end # annotation by ID
|
339
|
+
end # GET context
|
340
|
+
|
341
|
+
end
|
342
|
+
|