wf4ever-rosrs-client 0.1.1

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.
@@ -0,0 +1,200 @@
1
+ # Test suite for ROSRS_Session
2
+ require 'helper'
3
+
4
+
5
+ class TestAbstractInteraction < Test::Unit::TestCase
6
+
7
+ API_URI = "http://sandbox.wf4ever-project.org/rodl/ROs/"
8
+ AUTH_TOKEN = "32801fc0-1df1-4e34-b"
9
+ TEST_RO = "TestSessionRO_ruby"
10
+
11
+ def setup
12
+ @session = ROSRS::Session.new(API_URI, AUTH_TOKEN)
13
+ @ro = ROSRS::ResearchObject.create(@session, TEST_RO)
14
+ end
15
+
16
+ def teardown
17
+ @ro.delete
18
+ if @session
19
+ @session.close
20
+ end
21
+ end
22
+
23
+ def test_get_research_object
24
+ ro = ROSRS::ResearchObject.new(@session, @ro.uri)
25
+ assert(!ro.loaded?)
26
+ ro.load # Fetch and parse the manifest
27
+ assert(ro.loaded?)
28
+ assert_not_nil(ro.manifest)
29
+ #assert_empty(ro.annotations)
30
+ end
31
+
32
+ def test_create_root_folder
33
+ assert_nil(@ro.root_folder)
34
+ @ro.create_folder("test_root")
35
+ @ro.load
36
+ assert_not_nil(@ro.root_folder)
37
+ assert_equal("test_root", @ro.root_folder.name)
38
+ end
39
+
40
+ def test_delete_research_object
41
+ assert_nothing_raised { @ro.manifest }
42
+ @ro.delete
43
+ assert_raise(ROSRS::NotFoundException) { @ro.manifest }
44
+ end
45
+
46
+ def test_aggregating_resources
47
+ # Check can add resources
48
+ assert_equal(0, @ro.resources.size)
49
+ external = @ro.aggregate("http://www.google.com")
50
+ assert_equal(1, @ro.resources.size)
51
+ internal = @ro.aggregate('text_example.txt', "Hello world", 'text/plain')
52
+ assert_equal(2, @ro.resources.size)
53
+
54
+ # Check still there after reloading and parsing manifest
55
+ @ro.load
56
+ assert_equal(2, @ro.resources.size)
57
+
58
+ # Check URI of aggregated resources
59
+ resource_uris = @ro.resources.collect {|r| r.uri}
60
+ assert_include(resource_uris, internal.uri)
61
+ assert_include(resource_uris, external.uri)
62
+
63
+ # Check proxy URI of aggregated resources
64
+ proxy_uris = @ro.resources.collect {|r| r.proxy_uri}
65
+ assert_include(proxy_uris, internal.proxy_uri)
66
+ assert_include(proxy_uris, external.proxy_uri)
67
+
68
+ # Check resources are flagged as internal/external correctly
69
+ internal_resource = @ro.resources.select {|r| r.uri == internal.uri}.first
70
+ assert(internal_resource.internal?)
71
+ external_resource = @ro.resources.select {|r| r.uri == external.uri}.first
72
+ assert(external_resource.external?)
73
+
74
+ # Check deaggregating resources
75
+ @ro.remove(external_resource)
76
+ assert_equal(1, @ro.resources.size)
77
+ resource_uris = @ro.resources.collect {|r| r.uri}
78
+ assert_not_include(resource_uris, external_resource.uri)
79
+ assert_include(resource_uris, internal_resource.uri)
80
+
81
+ internal_resource.delete
82
+ assert_equal(0, @ro.resources.size)
83
+
84
+ # And check after reloading manifest
85
+ @ro.load
86
+ assert_equal(0, @ro.resources.size)
87
+ end
88
+
89
+ def test_annotating_resources
90
+ # Check can add annotations
91
+ external = @ro.aggregate("http://www.google.com")
92
+ internal = @ro.aggregate('text_example.txt', "Hello world", 'text/plain')
93
+ assert_equal(0, external.annotations.size)
94
+ assert_equal(0, internal.annotations.size)
95
+
96
+ # Create some annotations
97
+ remote_annotation = internal.annotate("http://www.example.com/annotation")
98
+ body = create_annotation_body(@ro.uri, external.uri)
99
+ local_annotation = external.annotate(body)
100
+
101
+ # Check added to local object
102
+ assert_equal(1, external.annotations.size)
103
+ assert_equal(1, internal.annotations.size)
104
+
105
+ # Reload RO by fetching and parsing manifest
106
+ @ro.load
107
+ # Check annotations still there
108
+ external = @ro.resources.select {|r| r.uri == external.uri}.first
109
+ internal = @ro.resources.select {|r| r.uri == internal.uri}.first
110
+ assert_equal(1, external.annotations.size)
111
+ assert_equal(1, internal.annotations.size)
112
+
113
+ # Check annotations content is the same
114
+ assert_equal(remote_annotation.uri, internal.annotations.first.uri)
115
+ assert_equal(remote_annotation.body_uri, internal.annotations.first.body_uri)
116
+ assert_equal(local_annotation.uri, external.annotations.first.uri)
117
+ assert_equal(local_annotation.body_uri, external.annotations.first.body_uri)
118
+ end
119
+
120
+ def test_adding_to_a_folder
121
+ # Aggregate some resources
122
+ external = @ro.aggregate("http://www.google.com")
123
+ internal = @ro.aggregate('text_example.txt', "Hello world", 'text/plain')
124
+
125
+ # Create a folder
126
+ folder = @ro.create_folder("test_root")
127
+ assert_not_nil(@ro.root_folder)
128
+
129
+ # Add the resources to the folder
130
+ assert_equal(0, folder.contents)
131
+ folder.add(external, "Google")
132
+ assert_equal(1, folder.contents)
133
+ folder.add(internal, "great_expectations.txt")
134
+ assert_equal(2, folder.contents)
135
+
136
+ # Check folder entries point to same resource
137
+ folder_resources = folder.contents.collect {|fe| fe.resource}
138
+ assert_includes(folder_resources, external)
139
+ assert_includes(folder_resources, internal)
140
+
141
+ # Reload folder
142
+ folder.load!
143
+ # Check contents the same
144
+ assert_equal(2, folder.contents)
145
+ folder_entry_names = folder.contents.collect {|fe| fe.name}
146
+ assert_include(folder_entry_names, "Google")
147
+ assert_include(folder_entry_names, "great_expectations.txt")
148
+ folder_resource_uris = folder.contents.collect {|fe| fe.resource.uri}
149
+ assert_include(folder_resource_uris, external.uri)
150
+ assert_include(folder_resource_uris, internal.uri)
151
+ end
152
+
153
+ def test_nesting_folders
154
+ root = @ro.create_folder("root")
155
+ assert_not_nil(@ro.root_folder)
156
+ assert_equal(1, @ro.folders.size)
157
+ # Create nested folder
158
+ level1 = root.create_folder("level1")
159
+ assert_equal(2, @ro.folders.size)
160
+ assert_equal(root.uri + "level1/", level1.uri)
161
+ assert_equal(1, root.contents.size)
162
+ entry = root.contents.first
163
+ assert_equal(entry.class, ROSRS::FolderEntry)
164
+ assert_equal(entry.resource.class, ROSRS::Folder)
165
+ assert_equal(entry.resource.uri, level1.uri)
166
+ # Reload and test again
167
+ @ro.load
168
+ assert_equal(2, @ro.folders.size)
169
+ folder_names = @ro.folders.collect {|f| f.name}
170
+ assert_includes(folder_names, "level1")
171
+ assert_includes(folder_names, "root")
172
+ assert_equal(root.uri, @ro.root_folder.uri)
173
+ assert_equal(1, root.contents.size)
174
+ entry = root.contents.first
175
+ assert_equal(entry.class, ROSRS::FolderEntry)
176
+ assert_equal(entry.resource.class, ROSRS::Folder)
177
+ assert_equal(entry.resource.uri, level1.uri)
178
+ end
179
+
180
+ private
181
+
182
+ def create_annotation_body(ro_uri, resource_uri)
183
+ body = %(<?xml version="1.0" encoding="UTF-8"?>
184
+ <rdf:RDF
185
+ xmlns:dct="http://purl.org/dc/terms/"
186
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
187
+ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
188
+ xml:base="#{ro_uri}"
189
+ >
190
+ <rdf:Description rdf:about="#{resource_uri}">
191
+ <dct:title>Title 1</dct:title>
192
+ <rdfs:seeAlso rdf:resource="http://example.org/test1" />
193
+ </rdf:Description>
194
+ </rdf:RDF>
195
+ )
196
+
197
+ ROSRS::RDFGraph.new(:data => body, :format => :xml)
198
+ end
199
+
200
+ end
@@ -0,0 +1,393 @@
1
+ # Test suite for ROSRS_Session
2
+ require 'helper'
3
+
4
+
5
+ class TestROSRSSession < Test::Unit::TestCase
6
+
7
+ # Test configuration values - may be imported later
8
+ #
9
+ # @@TODO: create separate module for test configuration (RODL, etc)
10
+ #
11
+ class Config
12
+ def self.rosrs_api_uri; "http://sandbox.wf4ever-project.org/rodl/ROs/"; end
13
+ def self.authorization; "32801fc0-1df1-4e34-b"; end
14
+ def self.test_ro_name; "TestSessionRO_ruby"; end
15
+ def self.test_ro_path; test_ro_name+"/"; end
16
+ def self.test_ro_uri; rosrs_api_uri+test_ro_path; end
17
+ def self.test_res1_rel; "subdir/res1.txt"; end
18
+ def self.test_res2_rel; "subdir/res2.rdf"; end
19
+ def self.test_res1_uri; test_ro_uri+test_res1_rel; end
20
+ def self.test_res2_uri; test_ro_uri+test_res2_rel; end
21
+ end
22
+
23
+ def setup
24
+ @rouri = nil
25
+ @rosrs = ROSRS::Session.new(Config.rosrs_api_uri, Config.authorization)
26
+ end
27
+
28
+ def teardown
29
+ if @rosrs
30
+ @rosrs.close
31
+ end
32
+ end
33
+
34
+ def uri(str)
35
+ RDF::URI(str)
36
+ end
37
+
38
+ def lit(str)
39
+ RDF::Literal(str)
40
+ end
41
+
42
+ def stmt(triple)
43
+ s,p,o = triple
44
+ RDF::Statement(:subject=>s, :predicate=>p, :object=>o)
45
+ end
46
+
47
+ def assert_contains(triple, graph)
48
+ assert(graph.match?(stmt(triple)), "Expected triple #{triple}")
49
+ end
50
+
51
+ def assert_not_contains(triple, graph)
52
+ assert(!graph.match?(stmt(triple)), "Unexpected triple #{triple}")
53
+ end
54
+
55
+ def assert_includes(item, list)
56
+ assert(list.include?(item), "Expected item #{item} in list: #{list.inspect}")
57
+ end
58
+
59
+ def assert_not_includes(item, list)
60
+ assert(!list.include?(item), "Unexpected item #{item} in list: #{list.inspect}")
61
+ end
62
+
63
+ def create_test_research_object
64
+ c, r = @rosrs.delete_research_object(Config.test_ro_uri)
65
+ c,r,u,m = @rosrs.create_research_object(Config.test_ro_name)
66
+ assert_equal(c, 201)
67
+ @rouri = u
68
+ [c,r,u,m]
69
+ end
70
+
71
+ def populate_test_research_object
72
+ # Add plain text resource
73
+ res1_body = %q(#{test_res1_uri}
74
+ resource body line 2
75
+ resource body line 3
76
+ end
77
+ )
78
+ options = { :body => res1_body, :ctype => "text/plain" }
79
+ c, r, puri, ruri = @rosrs.aggregate_internal_resource(
80
+ @rouri, Config.test_res1_rel, options)
81
+ assert_equal(201, c)
82
+ assert_equal("Created", r)
83
+ assert_equal(Config.test_res1_uri, ruri.to_s)
84
+ @res_txt = ruri
85
+ # Add RDF resource
86
+ res2_body = %q(
87
+ <rdf:RDF
88
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
89
+ xmlns:ex="http://example.org/" >
90
+ <ex:Resource rdf:about="http:/example.com/res/1">
91
+ <ex:foo rdf:resource="http://example.com/res/1" />
92
+ <ex:bar>Literal property</ex:bar>
93
+ </ex:Resource>
94
+ </rdf:RDF>
95
+ )
96
+ options = { :body => res2_body, :ctype => "application/rdf+xml" }
97
+ c, r, puri, ruri = @rosrs.aggregate_internal_resource(
98
+ @rouri, Config.test_res2_rel, options)
99
+ assert_equal(201, c)
100
+ assert_equal("Created", r)
101
+ assert_equal(Config.test_res2_uri, ruri.to_s)
102
+ @res_rdf = ruri
103
+ # @@TODO Add external resource
104
+ end
105
+
106
+ def delete_test_research_object
107
+ c, r = @rosrs.delete_research_object(@rouri)
108
+ [c, r]
109
+ end
110
+
111
+ # ----------
112
+ # Test cases
113
+ # ----------
114
+
115
+ def test_namespaces
116
+ assert_equal(RDF::URI("http://www.openarchives.org/ore/terms/Aggregation"), RDF::ORE.Aggregation)
117
+ assert_equal(RDF::URI("http://purl.org/wf4ever/ro#ResearchObject"), RDF::RO.ResearchObject)
118
+ assert_equal(RDF::URI("http://www.w3.org/2000/01/rdf-schema#seeAlso"), RDF::RDFS.seeAlso)
119
+ end
120
+
121
+ def test_create_serialize_graph
122
+ b = %q(
123
+ <rdf:RDF
124
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
125
+ xmlns:ex="http://example.org/" >
126
+ <ex:Resource rdf:about="http:/example.com/res/1">
127
+ <ex:foo rdf:resource="http://example.com/res/1" />
128
+ <ex:bar>Literal property</ex:bar>
129
+ </ex:Resource>
130
+ </rdf:RDF>
131
+ )
132
+ g = ROSRS::RDFGraph.new(:data => b)
133
+ b1 = g.serialize(format=:ntriples)
134
+ r1 = %r{<http:/example\.com/res/1> <http://example\.org/foo> <http://example\.com/res/1> \.}
135
+ r2 = %r{<http:/example\.com/res/1> <http://example\.org/bar> "Literal property" \.}
136
+ [r1,r2].each do |r|
137
+ assert(b1 =~ r, "Not matched: #{r}")
138
+ end
139
+ end
140
+
141
+ def test_query_graph
142
+ b = %q(
143
+ <rdf:RDF
144
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
145
+ xmlns:ex="http://example.org/" >
146
+ <ex:Resource rdf:about="http:/example.com/res/1">
147
+ <ex:foo rdf:resource="http://example.com/res/1" />
148
+ <ex:bar>Literal property</ex:bar>
149
+ </ex:Resource>
150
+ </rdf:RDF>
151
+ )
152
+ g = ROSRS::RDFGraph.new(:data => b)
153
+ stmts = []
154
+ g.query([nil, nil, nil]) { |s| stmts << s }
155
+ s1 = stmt([uri("http:/example.com/res/1"),uri("http://example.org/foo"),uri("http://example.com/res/1")])
156
+ s2 = stmt([uri("http:/example.com/res/1"),uri("http://example.org/bar"),lit("Literal property")])
157
+ assert_includes(s1, stmts)
158
+ assert_includes(s2, stmts)
159
+ stmts = []
160
+ g.query(:object => uri("http://example.com/res/1")) { |s| stmts << s }
161
+ assert_includes(s1, stmts)
162
+ assert_not_includes(s2, stmts)
163
+ end
164
+
165
+ def test_http_simple_get
166
+ c,r,u,m = create_test_research_object
167
+ assert_equal(201, c)
168
+ c,r,h,b = @rosrs.do_request("GET", @rouri,
169
+ {:accept => "application/rdf+xml"})
170
+ assert_equal(303, c)
171
+ assert_equal("See Other", r)
172
+ assert_equal("application/rdf+xml", h["content-type"])
173
+ assert_equal("", b)
174
+ c,r = delete_test_research_object
175
+ end
176
+
177
+ def test_http_redirected_get
178
+ c,r,u,m = create_test_research_object
179
+ assert_equal(201, c)
180
+ c,r,h,u,b = @rosrs.do_request_follow_redirect("GET", @rouri,
181
+ {:accept => "application/rdf+xml"})
182
+ assert_equal(200, c)
183
+ assert_equal("OK", r)
184
+ assert_equal("application/rdf+xml", h["content-type"])
185
+ assert_equal(Config.test_ro_uri+".ro/manifest.rdf", u.to_s)
186
+ #assert_match(???, b)
187
+ c,r = delete_test_research_object
188
+ end
189
+
190
+ def test_create_research_object
191
+ c,r,u,m = create_test_research_object
192
+ assert_equal(201, c)
193
+ assert_equal("Created", r)
194
+ assert_equal(Config.test_ro_uri, u)
195
+ s = stmt([uri(Config.test_ro_uri), RDF.type, RDF::RO.ResearchObject])
196
+ assert_contains(s, m)
197
+ c,r = delete_test_research_object
198
+ assert_equal(204, c)
199
+ assert_equal("No Content", r)
200
+ end
201
+
202
+ def test_get_manifest
203
+ # [manifesturi, manifest] = get_ro_manifest(rouri)
204
+ c,r,u,m = create_test_research_object
205
+ assert_equal(201, c)
206
+ # Get manifest
207
+ manifesturi, manifest = @rosrs.get_manifest(u)
208
+ assert_equal(@rouri.to_s+".ro/manifest.rdf", manifesturi.to_s)
209
+ # Check manifest RDF graph
210
+ assert_contains([uri(@rouri), RDF.type, RDF::RO.ResearchObject], manifest)
211
+ assert_contains([uri(@rouri), RDF::DC.creator, nil], manifest)
212
+ assert_contains([uri(@rouri), RDF::DC.created, nil], manifest)
213
+ assert_contains([uri(@rouri), RDF::ORE.isDescribedBy, uri(manifesturi)], manifest)
214
+ end
215
+
216
+ def test_aggregate_internal_resource
217
+ c,r,u,m = create_test_research_object
218
+ assert_equal(201, c)
219
+ body = "test_aggregate_internal_resource resource body\n"
220
+ options = { :body => body, :ctype => "text/plain" }
221
+ c, r, puri, ruri = @rosrs.aggregate_internal_resource(
222
+ @rouri, "test_aggregate_internal_resource", options)
223
+ assert_equal(201, c)
224
+ assert_equal("Created", r)
225
+ puri_exp = Config.test_ro_uri+".ro/proxies/"
226
+ puri_act = puri.to_s.slice(0...puri_exp.length)
227
+ assert_equal(puri_exp, puri_act)
228
+ assert_equal(Config.test_ro_uri+"test_aggregate_internal_resource", ruri.to_s)
229
+ c,r = delete_test_research_object
230
+ end
231
+
232
+ def test_create_annotation_body
233
+ c,r,u,m = create_test_research_object
234
+ assert_equal(201, c)
235
+ b = %q(
236
+ <rdf:RDF
237
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
238
+ xmlns:ex="http://example.org" >
239
+ <ex:Resource rdf:about="http:/example.com/res/1">
240
+ <ex:foo rdf:resource="http://example..com/res/1" />
241
+ <ex:bar>Literal property</ex:bar>
242
+ </ex:Resource>
243
+ </rdf:RDF>
244
+ )
245
+ g = ROSRS::RDFGraph.new(:data => b)
246
+ # Create an annotation body from a supplied annnotation graph.
247
+ # Params: (rouri, anngr)
248
+ # Returns: (status, reason, bodyuri)
249
+ c,r,u = @rosrs.create_annotation_body(@rouri, g)
250
+ assert_equal(201, c)
251
+ assert_equal("Created", r)
252
+ assert_match(%r(http://sandbox.wf4ever-project.org/rodl/ROs/TestSessionRO_ruby/), u.to_s)
253
+ #assert_equal(nil, u)
254
+ c,r = delete_test_research_object
255
+ end
256
+
257
+ def test_create_annotation_stub
258
+ # [code, reason, stuburi] = create_annotation_stub(rouri, resuri, bodyuri)
259
+ c,r,u,m = create_test_research_object
260
+ assert_equal(201, c)
261
+ c,r,u = @rosrs.create_annotation_stub(@rouri,
262
+ "http://example.org/resource", "http://example.org/body")
263
+ assert_equal(201, c)
264
+ assert_equal("Created", r)
265
+ assert_match(%r(http://sandbox.wf4ever-project.org/rodl/ROs/TestSessionRO_ruby/\.ro/), u.to_s)
266
+ c,r = delete_test_research_object
267
+ end
268
+
269
+ def test_create_internal_annotation
270
+ # [code, reason, annuri, bodyuri] = create_internal_annotation(rouri, resuri, anngr)
271
+ c,r,u,m = create_test_research_object
272
+ assert_equal(201, c)
273
+ populate_test_research_object
274
+ # Create internal annotation on @res_txt
275
+ annbody1 = %Q(<?xml version="1.0" encoding="UTF-8"?>
276
+ <rdf:RDF
277
+ xmlns:dct="http://purl.org/dc/terms/"
278
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
279
+ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
280
+ xml:base="#@rouri"
281
+ >
282
+ <rdf:Description rdf:about="#@res_txt">
283
+ <dct:title>Title 1</dct:title>
284
+ <rdfs:seeAlso rdf:resource="http://example.org/test1" />
285
+ </rdf:Description>
286
+ </rdf:RDF>
287
+ )
288
+ agraph1 = ROSRS::RDFGraph.new(:data => annbody1, :format => :xml)
289
+ c,r,annuri,bodyuri1 = @rosrs.create_internal_annotation(
290
+ @rouri, @res_txt, agraph1)
291
+ assert_equal(201, c)
292
+ assert_equal("Created", r)
293
+ # Retrieve annotation URIs
294
+ auris1 = @rosrs.get_annotation_stub_uris(@rouri, @res_txt)
295
+ assert_includes(uri(annuri), auris1)
296
+ buris1 = @rosrs.get_annotation_body_uris(@rouri, @res_txt)
297
+ assert_includes(uri(bodyuri1), buris1)
298
+ # Retrieve annotation
299
+ c,r,auri1,agr1a = @rosrs.get_annotation(annuri)
300
+ assert_equal(200, c)
301
+ assert_equal("OK", r)
302
+ # The following test fails, due to a temp[orary redirect from the annotation
303
+ # body URI in the stub to the actual URI used to retrieve the body:
304
+ # assert_includes(auri1, buris1)
305
+ s1a = [uri(@res_txt), RDF::DC.title, lit("Title 1")]
306
+ s1b = [uri(@res_txt), RDF::RDFS.seeAlso, uri("http://example.org/test1")]
307
+ assert_contains(s1a,agr1a)
308
+ assert_contains(s1b,agr1a)
309
+ # Retrieve merged annotations
310
+ agr1b = @rosrs.get_annotation_graph(@rouri, @res_txt)
311
+ assert_contains(s1a,agr1b)
312
+ assert_contains(s1b,agr1b)
313
+ # Update internal annotation
314
+ annbody2 = %Q(<?xml version="1.0" encoding="UTF-8"?>
315
+ <rdf:RDF
316
+ xmlns:dct="http://purl.org/dc/terms/"
317
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
318
+ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
319
+ xml:base="#@rouri"
320
+ >
321
+ <rdf:Description rdf:about="#@res_txt">
322
+ <dct:title>Title 2</dct:title>
323
+ <rdfs:seeAlso rdf:resource="http://example.org/test2" />
324
+ </rdf:Description>
325
+ </rdf:RDF>
326
+ )
327
+ agraph2 = ROSRS::RDFGraph.new(:data => annbody2, :format => :xml)
328
+ c,r,bodyuri2 = @rosrs.update_internal_annotation(
329
+ @rouri, annuri, @res_txt, agraph2)
330
+ assert_equal(c, 200)
331
+ assert_equal(r, "OK")
332
+ # Retrieve annotation URIs
333
+ auris2 = @rosrs.get_annotation_stub_uris(@rouri, @res_txt)
334
+ assert_includes(uri(annuri), auris2)
335
+ buris2 = @rosrs.get_annotation_body_uris(@rouri, @res_txt)
336
+ assert_includes(uri(bodyuri2), buris2)
337
+ # Retrieve annotation
338
+ c,r,auri2,agr2a = @rosrs.get_annotation(annuri)
339
+ assert_equal(c, 200)
340
+ assert_equal(r, "OK")
341
+ s2a = [uri(@res_txt), RDF::DC.title, lit("Title 2")]
342
+ s2b = [uri(@res_txt), RDF::RDFS.seeAlso, uri("http://example.org/test2")]
343
+ assert_not_contains(s1a,agr2a)
344
+ assert_not_contains(s1b,agr2a)
345
+ assert_contains(s2a,agr2a)
346
+ assert_contains(s2b,agr2a)
347
+ # Retrieve merged annotations
348
+ agr2b = @rosrs.get_annotation_graph(@rouri, @res_txt)
349
+ assert_not_contains(s1a,agr2b)
350
+ assert_not_contains(s1b,agr2b)
351
+ assert_contains(s2a,agr2b)
352
+ assert_contains(s2b,agr2b)
353
+ # Clean up
354
+ c,r = delete_test_research_object
355
+ end
356
+
357
+ def test_create_external_annotation
358
+ c,r,u,m = create_test_research_object
359
+ assert_equal(201, c)
360
+ populate_test_research_object
361
+
362
+ # Create external annotation on @res_txt
363
+ c,r,annuri = @rosrs.create_external_annotation(@rouri, @res_txt, "http://www.example.com/something")
364
+ assert_equal(201, c)
365
+ assert_equal("Created", r)
366
+
367
+ # Retrieve annotation URIs
368
+ auris1 = @rosrs.get_annotation_stub_uris(@rouri, @res_txt)
369
+ assert_includes(uri(annuri), auris1)
370
+ buris1 = @rosrs.get_annotation_body_uris(@rouri, @res_txt)
371
+ assert_includes("http://www.example.com/something", buris1)
372
+
373
+ # Update external annotation
374
+ c,r = @rosrs.update_external_annotation(@rouri, annuri, @res_txt, "http://www.example.com/other")
375
+ assert_equal(c, 200)
376
+ assert_equal(r, "OK")
377
+
378
+ # Retrieve annotation URIs
379
+ auris2 = @rosrs.get_annotation_stub_uris(@rouri, @res_txt)
380
+ assert_includes(uri(annuri), auris2)
381
+ buris2 = @rosrs.get_annotation_body_uris(@rouri, @res_txt)
382
+ assert_includes("http://www.example.com/other", buris2)
383
+
384
+ # Remove annotation
385
+ code, reason = @rosrs.remove_annotation(annuri)
386
+ assert_equal(code, 204)
387
+
388
+ # Clean up
389
+ c,r = delete_test_research_object
390
+ end
391
+
392
+
393
+ end