triannon-client 0.1.0 → 0.2.0.pre.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env_example +1 -1
- data/.travis.yml +1 -2
- data/README.md +12 -3
- data/bin/test.sh +8 -9
- data/lib/triannon-client.rb +8 -3
- data/lib/triannon-client/triannon_client.rb +180 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -0
- 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 +4088 -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/ld_json_.yml +4946 -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/n-quads_.yml +4088 -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/n-triples_.yml +4088 -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_json_.yml +4088 -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_n3_.yml +4088 -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 +2565 -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/trig_.yml +4088 -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/trix_.yml +4088 -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/turtle_.yml +4088 -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/x-ld_json_.yml +4088 -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/x-trig_.yml +4088 -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/x-turtle_.yml +2566 -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_text/n3_.yml +4088 -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_text/rdf_n3_.yml +4088 -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_text/rdf_turtle_.yml +4088 -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_text/turtle_.yml +2566 -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_text/x-nquads_.yml +4088 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_accepting_JSON-LD_content.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_accepting_a_default_JSON-LD_content.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_using_a_default_JSON-LD_content.yml +2502 -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/ld_json_.yml +2502 -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 +2502 -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-triples_.yml +2502 -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 +2502 -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_n3_.yml +2502 -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_xml_.yml +2502 -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/trig_.yml +2502 -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/trix_.yml +2502 -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/turtle_.yml +2502 -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/x-ld_json_.yml +2502 -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/x-trig_.yml +2502 -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/x-turtle_.yml +2502 -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_text/n3_.yml +2502 -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_text/rdf_n3_.yml +2502 -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_text/rdf_turtle_.yml +2502 -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_text/turtle_.yml +2502 -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_text/x-nquads_.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_optional_content_type_parameter.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_content_type/requests_an_open_annotation_by_ID_with_turtle_content_type_parameter.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/checks_the_annotation_ID.yml +2561 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/logs_exceptions.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/raises_an_argument_error_with_a_nil_ID.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/raises_an_argument_error_with_an_empty_string_ID.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/raises_an_argument_error_with_an_integer_ID.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/returns_an_EMPTY_RDF_graph_for_a_500_server_response.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/returns_an_EMPTY_RDF_graph_with_a_valid_ID_for_NO_annotation_on_the_server.yml +3623 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/with_no_content_type/returns_an_RDF_graph_with_a_valid_ID_for_an_annotation_on_the_server.yml +4946 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/checks_the_annotation_ID.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/logs_exceptions.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/raises_an_argument_error_with_a_nil_ID.yml +2502 -0
- 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 +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_annotation/without_content_type/raises_an_argument_error_with_an_integer_ID.yml +2502 -0
- 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 +2502 -0
- 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 +2502 -0
- 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 +3328 -0
- 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 +4946 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_iiif_annotation/requests_an_open_annotation_by_ID_using_a_IIIF_profile.yml +2746 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_iiif_annotation/returns_an_RDF_Graph_of_an_open_annotation.yml +2746 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_oa_annotation/requests_an_open_annotation_by_ID_using_an_OA_profile.yml +4946 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/GET_annotation_by_ID_/_get_oa_annotation/returns_an_RDF_Graph_of_an_open_annotation.yml +4946 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/deletes_an_open_annotation_that_exists.yml +2548 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/fails_to_delete_an_open_annotation_that_does_NOT_exist.yml +123 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_false_for_a_500_response_to_a_DELETE_request.yml +64 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_true_for_a_200_response_to_a_DELETE_request.yml +64 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_true_for_a_202_response_to_a_DELETE_request.yml +64 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/returns_true_for_a_204_response_to_a_DELETE_request.yml +64 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_delete_annotation/validates_the_annotation_ID.yml +64 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_get_annotations/returns_an_RDF_Graph.yml +295 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_get_annotations/returns_an_RDF_Graph_that_contains_an_AnnotationList.yml +295 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_get_annotations/returns_an_annotation_list_with_an_annotation_created_by_a_prior_POST.yml +2795 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_post_annotation/does_not_raise_an_error_when_submitting_a_valid_open_annotation.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/_post_annotation/returns_a_RestClient_Response_object.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_id/returns_a_String_ID_from_the_RDF_URI_of_an_annotation.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_id/returns_a_String_ID_that_is_not_empty.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_uri/returns_an_RDF_URI_from_an_RDF_Graph_of_an_annotation.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_annotation_uri/returns_an_RDF_URI_that_is_a_valid_URI.yml +2550 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/accepts_a_RestClient_Response_instance.yml +4898 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/raises_ArgumentError_when_given_an_empty_String.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/raises_ArgumentError_when_given_nil.yml +2502 -0
- data/spec/fixtures/vcr_cassettes/TriannonClient/response_processing_utilities/_response2graph/returns_an_RDF_Graph.yml +2502 -0
- data/spec/lib/triannon-client/triannon_client_spec.rb +502 -0
- data/spec/spec_helper.rb +12 -1
- data/triannon-client.gemspec +5 -2
- metadata +234 -7
- data/Gemfile.lock +0 -203
- data/lib/triannon-client/triannon-client.rb +0 -135
- data/spec/lib/triannon-client/triannon-client_spec.rb +0 -44
@@ -0,0 +1,502 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# ::TriannonClient::TriannonClient class specs
|
4
|
+
|
5
|
+
describe TriannonClient, :vcr do
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
Dotenv.load
|
9
|
+
@oa_jsonld = '{"@context":"http://iiif.io/api/presentation/2/context.json","@graph":[{"@id":"_:g70349699654640","@type":["dctypes:Text","cnt:ContentAsText"],"chars":"I love this!","format":"text/plain","language":"en"},{"@type":"oa:Annotation","motivation":"oa:commenting","on":"http://purl.stanford.edu/kq131cs7229","resource":"_:g70349699654640"}]}'
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:tc) { TriannonClient::TriannonClient.new }
|
13
|
+
|
14
|
+
# Note: not using `let` approach for these methods because it
|
15
|
+
# makes it very difficult to delete any annotations created by
|
16
|
+
# the `tc.post_annotation`; so the `create_annotation` and the
|
17
|
+
# `delete_annotation` methods are used in several before/after
|
18
|
+
# blocks within describe blocks, as required.
|
19
|
+
# let(:post_response) { tc.post_annotation(@oa_jsonld) }
|
20
|
+
# let(:anno_graph) { tc.response2graph(post_response) }
|
21
|
+
# let(:anno_uri) { tc.annotation_uri(anno_graph) }
|
22
|
+
# let(:anno_id) { tc.annotation_id(anno_uri) }
|
23
|
+
|
24
|
+
def create_annotation
|
25
|
+
r = tc.post_annotation(@oa_jsonld)
|
26
|
+
g = tc.response2graph(r)
|
27
|
+
uri = tc.annotation_uri(g)
|
28
|
+
id = tc.annotation_id(uri)
|
29
|
+
{
|
30
|
+
response: r,
|
31
|
+
graph: g,
|
32
|
+
uri: uri,
|
33
|
+
id: id
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_annotation(id)
|
38
|
+
tc.delete_annotation(id)
|
39
|
+
end
|
40
|
+
|
41
|
+
def graph_has_statements(graph)
|
42
|
+
expect(graph).to be_instance_of RDF::Graph
|
43
|
+
expect(graph).not_to be_empty
|
44
|
+
expect(graph.size).to be > 2
|
45
|
+
end
|
46
|
+
|
47
|
+
def graph_is_empty(graph)
|
48
|
+
expect(graph).to be_instance_of RDF::Graph
|
49
|
+
expect(graph).to be_empty
|
50
|
+
end
|
51
|
+
|
52
|
+
def graph_contains_open_annotation(graph, uri)
|
53
|
+
result = graph.query([nil, RDF.type, RDF::Vocab::OA.Annotation])
|
54
|
+
expect(result.size).to be > 0
|
55
|
+
expect(result.each_subject.collect{|s| s}).to include(uri)
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'has constants:' do
|
59
|
+
it 'CONTENT_TYPES' do
|
60
|
+
const = TriannonClient::TriannonClient::CONTENT_TYPES
|
61
|
+
expect(const).to be_instance_of Array
|
62
|
+
expect(const).to include('application/ld+json')
|
63
|
+
end
|
64
|
+
it 'PROFILE_TYPE_IIIF' do
|
65
|
+
const = TriannonClient::TriannonClient::PROFILE_IIIF
|
66
|
+
expect(const).to be_instance_of String
|
67
|
+
expect(const).to include('http://iiif.io/api/presentation/2/context.json')
|
68
|
+
end
|
69
|
+
it 'PROFILE_TYPE_OA' do
|
70
|
+
const = TriannonClient::TriannonClient::PROFILE_OA
|
71
|
+
expect(const).to be_instance_of String
|
72
|
+
expect(const).to include('http://www.w3.org/ns/oa-context-20130208.json')
|
73
|
+
end
|
74
|
+
it 'CONTENT_TYPE_IIIF' do
|
75
|
+
const = TriannonClient::TriannonClient::CONTENT_TYPE_IIIF
|
76
|
+
expect(const).to be_instance_of String
|
77
|
+
expect(const).to include('application/ld+json')
|
78
|
+
expect(const).to include('http://iiif.io/api/presentation/2/context.json')
|
79
|
+
end
|
80
|
+
it 'CONTENT_TYPE_OA' do
|
81
|
+
const = TriannonClient::TriannonClient::CONTENT_TYPE_OA
|
82
|
+
expect(const).to be_instance_of String
|
83
|
+
expect(const).to include('application/ld+json')
|
84
|
+
expect(const).to include('http://www.w3.org/ns/oa-context-20130208.json')
|
85
|
+
end
|
86
|
+
it 'JSONLD_TYPE' do
|
87
|
+
const = TriannonClient::TriannonClient::JSONLD_TYPE
|
88
|
+
expect(const).to be_instance_of String
|
89
|
+
expect(const).to eql('application/ld+json')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'has public methods:' do
|
94
|
+
it 'delete_annotation' do
|
95
|
+
expect(tc).to respond_to(:delete_annotation)
|
96
|
+
end
|
97
|
+
it 'get_annotations' do
|
98
|
+
expect(tc).to respond_to(:get_annotations)
|
99
|
+
end
|
100
|
+
it 'get_annotation' do
|
101
|
+
expect(tc).to respond_to(:get_annotation)
|
102
|
+
end
|
103
|
+
it 'get_iiif_annotation' do
|
104
|
+
expect(tc).to respond_to(:get_iiif_annotation)
|
105
|
+
end
|
106
|
+
it 'get_oa_annotation' do
|
107
|
+
expect(tc).to respond_to(:get_oa_annotation)
|
108
|
+
end
|
109
|
+
it 'site' do
|
110
|
+
expect(tc).to respond_to(:site)
|
111
|
+
end
|
112
|
+
# utilities
|
113
|
+
it 'response2graph' do
|
114
|
+
expect(tc).to respond_to(:response2graph)
|
115
|
+
end
|
116
|
+
it 'annotation_id' do
|
117
|
+
expect(tc).to respond_to(:annotation_id)
|
118
|
+
end
|
119
|
+
it 'annotation_uri' do
|
120
|
+
expect(tc).to respond_to(:annotation_uri)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'has private methods:' do
|
125
|
+
it 'check_id' do
|
126
|
+
expect(tc).not_to respond_to(:check_id)
|
127
|
+
end
|
128
|
+
it 'check_content_type' do
|
129
|
+
expect(tc).not_to respond_to(:check_content_type)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "#delete_annotation" do
|
134
|
+
def test_delete_for_response_code(status, response)
|
135
|
+
allow_any_instance_of(RestClient::Response).to receive(:code).and_return(status)
|
136
|
+
expect(tc.delete_annotation('anything_here_is_OK')).to be response
|
137
|
+
end
|
138
|
+
it "returns false for a 500 response to a DELETE request" do
|
139
|
+
test_delete_for_response_code(500, false)
|
140
|
+
end
|
141
|
+
it "returns true for a 200 response to a DELETE request" do
|
142
|
+
test_delete_for_response_code(200, true)
|
143
|
+
end
|
144
|
+
it "returns true for a 202 response to a DELETE request" do
|
145
|
+
test_delete_for_response_code(202, true)
|
146
|
+
end
|
147
|
+
it "returns true for a 204 response to a DELETE request" do
|
148
|
+
test_delete_for_response_code(204, true)
|
149
|
+
end
|
150
|
+
it 'validates the annotation ID' do
|
151
|
+
expect(tc).to receive(:check_id)
|
152
|
+
tc.delete_annotation('anything_here_is_OK')
|
153
|
+
end
|
154
|
+
it 'deletes an open annotation that exists' do
|
155
|
+
anno = create_annotation
|
156
|
+
expect( tc.delete_annotation(anno[:id]) ).to be true
|
157
|
+
graph = tc.get_annotation(anno[:id])
|
158
|
+
graph_is_empty(graph)
|
159
|
+
end
|
160
|
+
it 'fails to delete an open annotation that does NOT exist' do
|
161
|
+
id = 'anno_does_not_exist'
|
162
|
+
graph = tc.get_annotation(id)
|
163
|
+
graph_is_empty(graph)
|
164
|
+
expect( tc.delete_annotation(id) ).to be false
|
165
|
+
end
|
166
|
+
it 'logs exceptions' do
|
167
|
+
allow_any_instance_of(RestClient::Resource).to receive(:delete).and_raise('delete_exception')
|
168
|
+
expect(TriannonClient.configuration.logger).to receive(:error).with(/delete_exception/)
|
169
|
+
tc.delete_annotation('raise_delete_exception')
|
170
|
+
end
|
171
|
+
it 'quits after detecting an invalid annotation ID' do
|
172
|
+
expect_any_instance_of(RestClient::Resource).not_to receive(:delete)
|
173
|
+
tc.delete_annotation('') rescue nil
|
174
|
+
tc.delete_annotation(nil) rescue nil
|
175
|
+
end
|
176
|
+
it 'uses RestClient::Resource.delete to DELETE a valid annotation ID' do
|
177
|
+
expect_any_instance_of(RestClient::Resource).to receive(:delete)
|
178
|
+
tc.delete_annotation(SecureRandom.uuid)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "#get_annotations" do
|
183
|
+
it 'returns an RDF::Graph' do
|
184
|
+
graph = tc.get_annotations
|
185
|
+
graph_has_statements(graph)
|
186
|
+
end
|
187
|
+
it 'returns an RDF::Graph that contains an AnnotationList' do
|
188
|
+
graph = tc.get_annotations
|
189
|
+
anno_list_uri = RDF::URI.parse('http://iiif.io/api/presentation/2#AnnotationList')
|
190
|
+
result = graph.query([nil, nil, anno_list_uri])
|
191
|
+
expect(result.size).to eql(1)
|
192
|
+
end
|
193
|
+
it 'returns an annotation list with an annotation created by a prior POST' do
|
194
|
+
anno = create_annotation
|
195
|
+
graph = tc.get_annotations
|
196
|
+
graph_contains_open_annotation(graph, anno[:uri])
|
197
|
+
delete_annotation(anno[:id])
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "GET annotation by ID:" do
|
202
|
+
before(:example) do
|
203
|
+
# create a new annotation and call all the response processing utils.
|
204
|
+
@anno = create_annotation
|
205
|
+
end
|
206
|
+
after(:example) do
|
207
|
+
delete_annotation(@anno[:id]) # cleanup after create_annotation
|
208
|
+
end
|
209
|
+
|
210
|
+
describe "#get_annotation" do
|
211
|
+
context 'with content_type' do
|
212
|
+
# Content types could be supported for RDF::Format.content_types.keys,
|
213
|
+
# but not all of them are supported. The supported content types for
|
214
|
+
# triannon are defined in
|
215
|
+
# https://github.com/sul-dlss/triannon/blob/master/config/initializers/mime_types.rb
|
216
|
+
# https://github.com/sul-dlss/triannon/blob/master/app/controllers/triannon/annotations_controller.rb
|
217
|
+
# https://github.com/sul-dlss/triannon/blob/master/app/controllers/triannon/search_controller.rb
|
218
|
+
# The default content type is "application/ld+json" and, at the time of
|
219
|
+
# writing, triannon also supports:
|
220
|
+
# turtle as: ["application/x-turtle", "text/turtle"]
|
221
|
+
# rdf+xml as: ["application/rdf+xml", "text/rdf+xml", "text/rdf"]
|
222
|
+
# json as: ["application/json", "text/x-json", "application/jsonrequest"]
|
223
|
+
# xml as: ["application/xml", "text/xml", "application/x-xml"]
|
224
|
+
# html
|
225
|
+
def request_anno_with_content_type(content_type)
|
226
|
+
expect_any_instance_of(RestClient::Resource).to receive(:get).with(hash_including(:accept => content_type) )
|
227
|
+
tc.get_annotation(@anno[:id], content_type)
|
228
|
+
end
|
229
|
+
def gets_anno_with_content_type(content_type)
|
230
|
+
graph = tc.get_annotation(@anno[:id], content_type)
|
231
|
+
graph_has_statements(graph)
|
232
|
+
graph_contains_open_annotation(graph, @anno[:uri])
|
233
|
+
end
|
234
|
+
def cannot_get_anno_with_content_type(content_type)
|
235
|
+
graph = tc.get_annotation(@anno[:id], content_type)
|
236
|
+
graph_is_empty(graph)
|
237
|
+
end
|
238
|
+
# "text/plain",
|
239
|
+
# "text/html",
|
240
|
+
# "application/xhtml+xml",
|
241
|
+
it 'requests an open annotation by ID, with content type "application/ld+json"' do
|
242
|
+
request_anno_with_content_type("application/ld+json")
|
243
|
+
end
|
244
|
+
it 'gets an open annotation by ID, with content type "application/ld+json"' do
|
245
|
+
gets_anno_with_content_type("application/ld+json")
|
246
|
+
end
|
247
|
+
it 'requests an open annotation by ID, with content type "application/x-ld+json"' do
|
248
|
+
request_anno_with_content_type("application/x-ld+json")
|
249
|
+
end
|
250
|
+
it 'cannot get an open annotation by ID, with content type "application/x-ld+json"' do
|
251
|
+
cannot_get_anno_with_content_type("application/x-ld+json")
|
252
|
+
end
|
253
|
+
it 'requests an open annotation by ID, with content type "application/rdf+json"' do
|
254
|
+
request_anno_with_content_type("application/rdf+json")
|
255
|
+
end
|
256
|
+
it 'cannot get an open annotation by ID, with content type "application/rdf+json"' do
|
257
|
+
cannot_get_anno_with_content_type("application/rdf+json")
|
258
|
+
end
|
259
|
+
it 'requests an open annotation by ID, with content type "application/rdf+xml"' do
|
260
|
+
request_anno_with_content_type("application/rdf+xml")
|
261
|
+
end
|
262
|
+
it 'gets an open annotation by ID, with content type "application/rdf+xml"' do
|
263
|
+
gets_anno_with_content_type("application/rdf+xml")
|
264
|
+
end
|
265
|
+
it 'requests an open annotation by ID, with content type "text/turtle"' do
|
266
|
+
request_anno_with_content_type("text/turtle")
|
267
|
+
end
|
268
|
+
it 'gets an open annotation by ID, with content type "text/turtle"' do
|
269
|
+
gets_anno_with_content_type("text/turtle")
|
270
|
+
end
|
271
|
+
it 'requests an open annotation by ID, with content type "text/rdf+turtle"' do
|
272
|
+
request_anno_with_content_type("text/rdf+turtle")
|
273
|
+
end
|
274
|
+
it 'cannot get an open annotation by ID, with content type "text/rdf+turtle"' do
|
275
|
+
cannot_get_anno_with_content_type("text/rdf+turtle")
|
276
|
+
end
|
277
|
+
it 'requests an open annotation by ID, with content type "application/turtle"' do
|
278
|
+
request_anno_with_content_type("application/turtle")
|
279
|
+
end
|
280
|
+
it 'cannot get an open annotation by ID, with content type "application/turtle"' do
|
281
|
+
cannot_get_anno_with_content_type("application/turtle")
|
282
|
+
end
|
283
|
+
it 'requests an open annotation by ID, with content type "application/x-turtle"' do
|
284
|
+
request_anno_with_content_type("application/x-turtle")
|
285
|
+
end
|
286
|
+
it 'gets an open annotation by ID, with content type "application/x-turtle"' do
|
287
|
+
gets_anno_with_content_type("application/x-turtle")
|
288
|
+
end
|
289
|
+
it 'requests an open annotation by ID, with content type "application/n-triples"' do
|
290
|
+
request_anno_with_content_type("application/n-triples")
|
291
|
+
end
|
292
|
+
it 'cannot get an open annotation by ID, with content type "application/n-triples"' do
|
293
|
+
cannot_get_anno_with_content_type("application/n-triples")
|
294
|
+
end
|
295
|
+
it 'requests an open annotation by ID, with content type "application/rdf+n3"' do
|
296
|
+
request_anno_with_content_type("application/rdf+n3")
|
297
|
+
end
|
298
|
+
it 'cannot get an open annotation by ID, with content type "application/rdf+n3"' do
|
299
|
+
cannot_get_anno_with_content_type("application/rdf+n3")
|
300
|
+
end
|
301
|
+
it 'requests an open annotation by ID, with content type "text/n3"' do
|
302
|
+
request_anno_with_content_type("text/n3")
|
303
|
+
end
|
304
|
+
it 'cannot get an open annotation by ID, with content type "text/n3"' do
|
305
|
+
cannot_get_anno_with_content_type("text/n3")
|
306
|
+
end
|
307
|
+
it 'requests an open annotation by ID, with content type "text/rdf+n3"' do
|
308
|
+
request_anno_with_content_type("text/rdf+n3")
|
309
|
+
end
|
310
|
+
it 'cannot get an open annotation by ID, with content type "text/rdf+n3"' do
|
311
|
+
cannot_get_anno_with_content_type("text/rdf+n3")
|
312
|
+
end
|
313
|
+
it 'requests an open annotation by ID, with content type "application/n-quads"' do
|
314
|
+
request_anno_with_content_type("application/n-quads")
|
315
|
+
end
|
316
|
+
it 'cannot get an open annotation by ID, with content type "application/n-quads"' do
|
317
|
+
cannot_get_anno_with_content_type("application/n-quads")
|
318
|
+
end
|
319
|
+
it 'requests an open annotation by ID, with content type "text/x-nquads"' do
|
320
|
+
request_anno_with_content_type("text/x-nquads")
|
321
|
+
end
|
322
|
+
it 'cannot get an open annotation by ID, with content type "text/x-nquads"' do
|
323
|
+
cannot_get_anno_with_content_type("text/x-nquads")
|
324
|
+
end
|
325
|
+
it 'requests an open annotation by ID, with content type "application/trig"' do
|
326
|
+
request_anno_with_content_type("application/trig")
|
327
|
+
end
|
328
|
+
it 'cannot get an open annotation by ID, with content type "application/trig"' do
|
329
|
+
cannot_get_anno_with_content_type("application/trig")
|
330
|
+
end
|
331
|
+
it 'requests an open annotation by ID, with content type "application/x-trig"' do
|
332
|
+
request_anno_with_content_type("application/x-trig")
|
333
|
+
end
|
334
|
+
it 'cannot get an open annotation by ID, with content type "application/x-trig"' do
|
335
|
+
cannot_get_anno_with_content_type("application/x-trig")
|
336
|
+
end
|
337
|
+
it 'requests an open annotation by ID, with content type "application/trix"' do
|
338
|
+
request_anno_with_content_type("application/trix")
|
339
|
+
end
|
340
|
+
it 'cannot get an open annotation by ID, with content type "application/trix"' do
|
341
|
+
cannot_get_anno_with_content_type("application/trix")
|
342
|
+
end
|
343
|
+
end
|
344
|
+
context 'without content_type' do
|
345
|
+
it 'requests an open annotation by ID, accepting a default JSON-LD content' do
|
346
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uri])
|
347
|
+
content_type = TriannonClient::TriannonClient::JSONLD_TYPE
|
348
|
+
expect_any_instance_of(RestClient::Resource).to receive(:get).with(hash_including(:accept => content_type) )
|
349
|
+
tc.get_annotation(@anno[:id])
|
350
|
+
end
|
351
|
+
it 'checks the annotation ID' do
|
352
|
+
expect(tc).to receive(:check_id) # tested by #create_annotation
|
353
|
+
graph_has_statements(@anno[:graph]) # check #create_annotation worked
|
354
|
+
end
|
355
|
+
it 'raises an argument error with a nil ID' do
|
356
|
+
expect{tc.get_annotation(nil)}.to raise_error(ArgumentError)
|
357
|
+
end
|
358
|
+
it 'raises an argument error with an integer ID' do
|
359
|
+
expect{tc.get_annotation(0)}.to raise_error(ArgumentError)
|
360
|
+
end
|
361
|
+
it 'raises an argument error with an empty string ID' do
|
362
|
+
expect{tc.get_annotation('')}.to raise_error(ArgumentError)
|
363
|
+
end
|
364
|
+
it 'returns an RDF graph with a valid ID for an annotation on the server' do
|
365
|
+
graph = tc.get_annotation(@anno[:id])
|
366
|
+
graph_has_statements(graph)
|
367
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uri])
|
368
|
+
end
|
369
|
+
it 'returns an EMPTY RDF graph with a valid ID for NO annotation on the server' do
|
370
|
+
id = SecureRandom.uuid
|
371
|
+
graph = tc.get_annotation(id)
|
372
|
+
graph_is_empty(graph)
|
373
|
+
end
|
374
|
+
it 'returns an EMPTY RDF graph for a 500 server response' do
|
375
|
+
response = double
|
376
|
+
allow(response).to receive(:is_a?).and_return(RestClient::Response)
|
377
|
+
allow(response).to receive(:headers).and_return({content_type: 'application/ld+json'})
|
378
|
+
allow(response).to receive(:code).and_return(500)
|
379
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_return(response)
|
380
|
+
graph = tc.get_annotation(@anno[:id])
|
381
|
+
graph_is_empty(graph)
|
382
|
+
end
|
383
|
+
it 'logs exceptions' do
|
384
|
+
allow_any_instance_of(RestClient::Resource).to receive(:get).and_raise('get_exception')
|
385
|
+
expect(TriannonClient.configuration.logger).to receive(:error).with(/get_exception/)
|
386
|
+
tc.get_annotation('raise_get_exception')
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe "#get_iiif_annotation" do
|
392
|
+
# the mime type is fixed for this method
|
393
|
+
it 'requests an open annotation by ID, using a IIIF profile' do
|
394
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uri])
|
395
|
+
content_type = TriannonClient::TriannonClient::CONTENT_TYPE_IIIF
|
396
|
+
expect(tc).to receive(:get_annotation).with(@anno[:id], content_type)
|
397
|
+
tc.get_iiif_annotation(@anno[:id])
|
398
|
+
end
|
399
|
+
it 'returns an RDF::Graph of an open annotation' do
|
400
|
+
graph = tc.get_iiif_annotation(@anno[:id])
|
401
|
+
graph_has_statements(graph)
|
402
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uri])
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
describe "#get_oa_annotation" do
|
407
|
+
# the mime type is fixed for this method
|
408
|
+
it 'requests an open annotation by ID, using an OA profile' do
|
409
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uri])
|
410
|
+
content_type = TriannonClient::TriannonClient::CONTENT_TYPE_OA
|
411
|
+
expect(tc).to receive(:get_annotation).with(@anno[:id], content_type)
|
412
|
+
tc.get_oa_annotation(@anno[:id])
|
413
|
+
end
|
414
|
+
it 'returns an RDF::Graph of an open annotation' do
|
415
|
+
graph = tc.get_oa_annotation(@anno[:id])
|
416
|
+
graph_has_statements(graph)
|
417
|
+
graph_contains_open_annotation(@anno[:graph], @anno[:uri])
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
end
|
422
|
+
|
423
|
+
describe "#post_annotation" do
|
424
|
+
it 'does not raise an error when submitting a valid open annotation' do
|
425
|
+
response = nil
|
426
|
+
expect do
|
427
|
+
response = tc.post_annotation(@oa_jsonld)
|
428
|
+
end.not_to raise_error
|
429
|
+
# Double check the POST by deleting the annotation.
|
430
|
+
# If the POST was successful, the DELETE should work too.
|
431
|
+
graph = tc.response2graph(response)
|
432
|
+
uri = tc.annotation_uri(graph)
|
433
|
+
id = tc.annotation_id(uri)
|
434
|
+
expect(tc.delete_annotation(id)).to be true
|
435
|
+
end
|
436
|
+
it 'returns a RestClient::Response object' do
|
437
|
+
# The response behaves primarily as a String, so it can not be tested
|
438
|
+
# as an instance of RestClient::Response, but it can be tested to respond
|
439
|
+
# to RestClient::Response methods.
|
440
|
+
anno = create_annotation
|
441
|
+
r = anno[:response]
|
442
|
+
expect(r.is_a? RestClient::Response).to be true
|
443
|
+
expect(r).to respond_to(:code)
|
444
|
+
expect(r).to respond_to(:body)
|
445
|
+
expect(r).to respond_to(:headers)
|
446
|
+
delete_annotation(anno[:id]) # cleanup after create_annotation
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
|
451
|
+
describe 'response processing utilities' do
|
452
|
+
|
453
|
+
before(:example) do
|
454
|
+
# create a new annotation and call all the response processing utils.
|
455
|
+
@anno = create_annotation
|
456
|
+
end
|
457
|
+
after(:example) do
|
458
|
+
delete_annotation(@anno[:id]) # cleanup after create_annotation
|
459
|
+
end
|
460
|
+
|
461
|
+
describe '#response2graph' do
|
462
|
+
it 'accepts a RestClient::Response instance' do
|
463
|
+
r = @anno[:response]
|
464
|
+
expect{tc.response2graph(r)}.not_to raise_error
|
465
|
+
end
|
466
|
+
it 'raises ArgumentError when given nil' do
|
467
|
+
expect{tc.response2graph(nil)}.to raise_error(ArgumentError)
|
468
|
+
end
|
469
|
+
it 'raises ArgumentError when given an empty String' do
|
470
|
+
expect{tc.response2graph('')}.to raise_error(ArgumentError)
|
471
|
+
end
|
472
|
+
it 'returns an RDF::Graph' do
|
473
|
+
expect(@anno[:graph]).to be_instance_of RDF::Graph
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
describe "#annotation_uri" do
|
478
|
+
it "returns an RDF::URI from an RDF::Graph of an annotation" do
|
479
|
+
expect(@anno[:graph]).to be_instance_of RDF::Graph
|
480
|
+
expect(@anno[:uri]).to be_instance_of RDF::URI
|
481
|
+
end
|
482
|
+
it "returns an RDF::URI that is a valid URI" do
|
483
|
+
expect(@anno[:uri]).to match(/\A#{URI::regexp}\z/)
|
484
|
+
delete_annotation(@anno[:id]) # cleanup after create_annotation
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
describe "#annotation_id" do
|
489
|
+
it "returns a String ID from the RDF::URI of an annotation" do
|
490
|
+
expect(@anno[:uri]).to be_instance_of RDF::URI
|
491
|
+
expect(@anno[:id]).to be_instance_of String
|
492
|
+
end
|
493
|
+
it "returns a String ID that is not empty" do
|
494
|
+
expect(@anno[:id]).to be_instance_of String
|
495
|
+
expect(@anno[:id].empty?).to be false
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
end
|
500
|
+
|
501
|
+
end
|
502
|
+
|