wf4ever-rosrs-client 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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