xrd 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,122 @@
1
+ require 'time'
2
+ require 'sax-machine'
3
+ require 'addressable/uri'
4
+ require 'httpadapter'
5
+ require 'httpadapter/adapters/net_http'
6
+ require 'xrd/properties'
7
+ require 'xrd/link'
8
+
9
+ module XRD
10
+ NAMESPACE = 'http://docs.oasis-open.org/ns/xri/xrd-1.0'
11
+
12
+ class ResourceDescriptor
13
+ include SAXMachine
14
+ include XRD::Properties
15
+
16
+ element "XRD", :as => :xml_id, :value => "xml:id"
17
+ element "Expires", :as => :expires
18
+ element "Subject", :as => :subject
19
+ elements "Alias", :as => :aliases
20
+ elements "Link", :as => :links, :class => XRD::Link
21
+
22
+ remove_method :expires, :expires=
23
+ remove_method :subject, :subject=
24
+ remove_method :aliases, :add_aliases
25
+ remove_method :links
26
+
27
+ def self.fetch_and_parse(
28
+ uri, adapter=HTTPAdapter::NetHTTPRequestAdapter, connection=nil)
29
+ resource_descriptor = XRD::ResourceDescriptor.new
30
+ resource_descriptor.base_uri = uri
31
+ request = [
32
+ 'GET', resource_descriptor.base_uri.to_str,
33
+ [['Accept', 'application/xrd+xml,application/xml;q=0.9,*/*;q=0.9']],
34
+ ['']
35
+ ]
36
+ response = HTTPAdapter.transmit(request, adapter, connection)
37
+ status, headers, body = response
38
+ xrd_content = ""
39
+ body.each do |chunk|
40
+ xrd_content += chunk
41
+ end
42
+ return self.parse(xrd_content)
43
+ end
44
+
45
+ def base_uri
46
+ return @base_uri ||= nil
47
+ end
48
+
49
+ def base_uri=(new_base_uri)
50
+ @base_uri = Addressable::URI.parse(new_base_uri)
51
+ end
52
+
53
+ attr_reader :expires
54
+
55
+ def expires=(new_expires)
56
+ if new_expires.kind_of?(Time)
57
+ @expires = new_expires
58
+ else
59
+ @expires = Time.parse(new_expires.to_s)
60
+ end
61
+ end
62
+
63
+ attr_reader :subject
64
+
65
+ def subject=(new_subject)
66
+ @subject = Addressable::URI.parse(new_subject)
67
+ end
68
+
69
+ def aliases
70
+ return @aliases ||= []
71
+ end
72
+
73
+ def add_aliases(new_alias)
74
+ return self.aliases << Addressable::URI.parse(new_alias)
75
+ end
76
+
77
+ def links(query={})
78
+ @links ||= []
79
+ if query.empty?
80
+ return @links
81
+ else
82
+ result_set = []
83
+ for link in @links
84
+ matched = query.all? do |field, condition|
85
+ case field
86
+ when :rel
87
+ condition === link.rel
88
+ when :media_type, :type
89
+ if link.media_type.kind_of?(String) &&
90
+ !condition.include?('/')
91
+ link.media_type.to_s.index(condition) == 0
92
+ else
93
+ condition === link.media_type
94
+ end
95
+ when :href, :uri
96
+ if condition.respond_to?(:match)
97
+ condition.match(link.href)
98
+ else
99
+ condition === link.href
100
+ end
101
+ end
102
+ end
103
+ result_set << link if matched
104
+ end
105
+ return result_set
106
+ end
107
+ end
108
+
109
+ ##
110
+ # Returns a <code>String</code> representation of the resource descriptor
111
+ # object's state.
112
+ #
113
+ # @return [String]
114
+ # The resource descriptor object's state, as a <code>String</code>.
115
+ def inspect
116
+ sprintf(
117
+ "#<%s:%#0x SUBJECT:%s>",
118
+ self.class.to_s, self.object_id, self.subject
119
+ )
120
+ end
121
+ end
122
+ end
data/lib/xrd/title.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'sax-machine'
2
+
3
+ module XRD
4
+ class Title < String
5
+ include SAXMachine
6
+
7
+ element 'Title', :as => :title
8
+ element 'Title', :as => :lang, :value => 'xml:lang'
9
+
10
+ remove_method :title, :title=
11
+
12
+ protected
13
+ def title=(new_title)
14
+ # Replace self with new title
15
+ self[0..-1] = new_title
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright 2010 Google, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Used to prevent the class/module from being loaded more than once
16
+ unless defined? XRD::VERSION
17
+ module XRD
18
+ module VERSION
19
+ MAJOR = 0
20
+ MINOR = 1
21
+ TINY = 0
22
+
23
+ STRING = [MAJOR, MINOR, TINY].join('.')
24
+ end
25
+ end
26
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format specdoc
@@ -0,0 +1,21 @@
1
+ # Copyright 2010 Google, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ spec_dir = File.expand_path(File.dirname(__FILE__))
16
+ lib_dir = File.expand_path(File.join(spec_dir, '../lib'))
17
+
18
+ $:.unshift(lib_dir)
19
+ $:.uniq!
20
+
21
+ require 'xrd'
@@ -0,0 +1,111 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ require 'xrd/link'
18
+
19
+ describe XRD::Link do
20
+ describe 'when attempting to parse an XRD document' do
21
+ describe 'with a Link element containing an auth link' do
22
+ before do
23
+ @xml = <<-XML
24
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
25
+ <Link rel="http://spec.example.net/auth/1.0"
26
+ href="http://services.example.com/auth" />
27
+ </XRD>
28
+ XML
29
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
30
+ end
31
+
32
+ it 'should return the correct rel value' do
33
+ @xrd.links.first.rel.should == 'http://spec.example.net/auth/1.0'
34
+ end
35
+
36
+ it 'should return the correct href value' do
37
+ @xrd.links.first.href.should == 'http://services.example.com/auth'
38
+ end
39
+
40
+ it 'should be inspectable' do
41
+ @xrd.links.first.inspect.should be_kind_of(String)
42
+ @xrd.links.first.inspect.should include(
43
+ 'http://services.example.com/auth'
44
+ )
45
+ end
46
+ end
47
+
48
+ describe 'with a Link element containing an image link' do
49
+ before do
50
+ @xml = <<-XML
51
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
52
+ <Link rel="http://spec.example.net/photo/1.0" type="image/jpeg"
53
+ href="http://photos.example.com/gpburdell.jpg">
54
+ </XRD>
55
+ XML
56
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
57
+ end
58
+
59
+ it 'should return the correct rel value' do
60
+ @xrd.links.first.rel.should == 'http://spec.example.net/photo/1.0'
61
+ end
62
+
63
+ it 'should return the correct media type value' do
64
+ @xrd.links.first.media_type.should == 'image/jpeg'
65
+ end
66
+
67
+ it 'should return the correct href value' do
68
+ @xrd.links.first.href.should ==
69
+ 'http://photos.example.com/gpburdell.jpg'
70
+ end
71
+
72
+ it 'should be inspectable' do
73
+ @xrd.links.first.inspect.should be_kind_of(String)
74
+ @xrd.links.first.inspect.should include(
75
+ 'http://photos.example.com/gpburdell.jpg'
76
+ )
77
+ end
78
+ end
79
+
80
+ describe 'with a Link element containing a template value' do
81
+ before do
82
+ @xml = <<-XML
83
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
84
+ <Link type="text/html"
85
+ template="http://people.example.com/{user}">
86
+ </XRD>
87
+ XML
88
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
89
+ end
90
+
91
+ it 'should return the correct media type value' do
92
+ @xrd.links.first.media_type.should == 'text/html'
93
+ end
94
+
95
+ it 'should return the correct href value' do
96
+ @xrd.links.first.href.should == nil
97
+ end
98
+
99
+ it 'should return the correct template value' do
100
+ @xrd.links.first.template.should == 'http://people.example.com/{user}'
101
+ end
102
+
103
+ it 'should be inspectable' do
104
+ @xrd.links.first.inspect.should be_kind_of(String)
105
+ @xrd.links.first.inspect.should include(
106
+ 'http://people.example.com/{user}'
107
+ )
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,431 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ require 'httpadapter/adapters/mock'
18
+ require 'addressable/uri'
19
+ require 'addressable/template'
20
+
21
+ require 'xrd'
22
+
23
+ describe XRD::ResourceDescriptor do
24
+ describe 'with an initialized resource descriptor' do
25
+ before do
26
+ @xrd = XRD::ResourceDescriptor.new
27
+ end
28
+
29
+ it 'should allow expiration dates to be set to Time objects' do
30
+ now = Time.now
31
+ @xrd.expires = now
32
+ @xrd.expires.should == now
33
+ end
34
+
35
+ it 'should allow expiration dates to be set to String objects' do
36
+ now = Time.now
37
+ @xrd.expires = now.to_s
38
+ @xrd.expires.to_s.should == now.to_s
39
+ end
40
+
41
+ it 'should allow subject values to be set to URI objects' do
42
+ @xrd.subject = Addressable::URI.parse('http://example.com/subject')
43
+ @xrd.subject.should == Addressable::URI.parse(
44
+ 'http://example.com/subject'
45
+ )
46
+ end
47
+
48
+ it 'should allow subject values to be set to String objects' do
49
+ @xrd.subject = 'http://example.com/subject'
50
+ @xrd.subject.should == Addressable::URI.parse(
51
+ 'http://example.com/subject'
52
+ )
53
+ end
54
+
55
+ it 'should not allow direct access to the property_keys' do
56
+ (lambda do
57
+ @xrd.property_keys
58
+ end).should raise_error(NoMethodError)
59
+ (lambda do
60
+ @xrd.property_keys = []
61
+ end).should raise_error(NoMethodError)
62
+ end
63
+
64
+ it 'should not allow direct access to the property_values' do
65
+ (lambda do
66
+ @xrd.property_values
67
+ end).should raise_error(NoMethodError)
68
+ (lambda do
69
+ @xrd.property_values = []
70
+ end).should raise_error(NoMethodError)
71
+ end
72
+
73
+ it 'should be inspectable' do
74
+ @xrd.inspect.should be_kind_of(String)
75
+ end
76
+ end
77
+
78
+ describe 'when attempting to parse an empty XRD document' do
79
+ before do
80
+ @xml = <<-XML
81
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
82
+ </XRD>
83
+ XML
84
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
85
+ end
86
+
87
+ it 'should return a blank resource descriptor' do
88
+ @xrd.xml_id.should == nil
89
+ @xrd.expires.should == nil
90
+ @xrd.subject.should == nil
91
+ @xrd.aliases.should == []
92
+ @xrd.properties.should == []
93
+ @xrd.links.should == []
94
+ end
95
+ end
96
+
97
+ describe 'when attempting to parse an XRD document with an id' do
98
+ before do
99
+ @xml = <<-XML
100
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0" xml:id="identifier">
101
+ </XRD>
102
+ XML
103
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
104
+ end
105
+
106
+ it 'should return the correct id' do
107
+ @xrd.xml_id.should == "identifier"
108
+ end
109
+ end
110
+
111
+ describe 'when attempting to parse an XRD document with an Expires value' do
112
+ before do
113
+ @xml = <<-XML
114
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
115
+ <Expires>1970-01-01T00:00:00Z</Expires>
116
+ </XRD>
117
+ XML
118
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
119
+ end
120
+
121
+ it 'should return the correct expiration date' do
122
+ @xrd.expires.should == Time.gm(1970)
123
+ end
124
+ end
125
+
126
+ describe 'when attempting to parse an XRD document with a Subject value' do
127
+ before do
128
+ @xml = <<-XML
129
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
130
+ <Subject>http://example.com/subject</Expires>
131
+ </XRD>
132
+ XML
133
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
134
+ end
135
+
136
+ it 'should return the correct subject' do
137
+ @xrd.subject.to_str.should == 'http://example.com/subject'
138
+ end
139
+
140
+ it 'should return a parsed subject URI' do
141
+ @xrd.subject.should be_kind_of(Addressable::URI)
142
+ end
143
+
144
+ it 'should be inspectable' do
145
+ @xrd.inspect.should be_kind_of(String)
146
+ @xrd.inspect.should include('http://example.com/subject')
147
+ end
148
+ end
149
+
150
+ describe 'when attempting to parse an XRD document with Alias values' do
151
+ before do
152
+ @xml = <<-XML
153
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
154
+ <Alias>http://people.example.com/subject</Alias>
155
+ <Alias>acct:subject@example.com</Alias>
156
+ </XRD>
157
+ XML
158
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
159
+ end
160
+
161
+ it 'should return the correct aliases' do
162
+ (@xrd.aliases.map { |a| a.to_str }).should include(
163
+ 'http://people.example.com/subject'
164
+ )
165
+ (@xrd.aliases.map { |a| a.to_str }).should include(
166
+ 'acct:subject@example.com'
167
+ )
168
+ end
169
+
170
+ it 'should return parsed alias URIs' do
171
+ @xrd.aliases.each do |a|
172
+ a.should be_kind_of(Addressable::URI)
173
+ end
174
+ end
175
+ end
176
+
177
+ describe 'when attempting to parse an XRD document with Property values' do
178
+ before do
179
+ @xml = <<-XML
180
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
181
+ <Property type="http://spec.example.net/version">1.0</Property>
182
+ <Property type="http://spec.example.net/version">2.0</Property>
183
+ </XRD>
184
+ XML
185
+ @xrd = XRD::ResourceDescriptor.parse(@xml)
186
+ end
187
+
188
+ it 'should return the correct properties' do
189
+ (@xrd.properties.map { |k, v| [k.to_str, v] }).should include(
190
+ ['http://spec.example.net/version', '1.0']
191
+ )
192
+ (@xrd.properties.map { |k, v| [k.to_str, v] }).should include(
193
+ ['http://spec.example.net/version', '2.0']
194
+ )
195
+ end
196
+
197
+ it 'should return parsed property key URIs' do
198
+ @xrd.properties.each do |k, v|
199
+ k.should be_kind_of(Addressable::URI)
200
+ v.should be_kind_of(String)
201
+ end
202
+ end
203
+ end
204
+
205
+ shared_examples_for 'simple XRD example' do
206
+ it 'should return the correct expiration date' do
207
+ @xrd.expires.should == Time.gm(1970)
208
+ end
209
+
210
+ it 'should return the correct subject' do
211
+ @xrd.subject.to_str.should == 'http://example.com/subject'
212
+ end
213
+
214
+ it 'should return a parsed subject URI' do
215
+ @xrd.subject.should be_kind_of(Addressable::URI)
216
+ end
217
+
218
+ it 'should return the correct properties' do
219
+ (@xrd.properties.map { |k, v| [k.to_str, v] }).should include(
220
+ ['http://spec.example.net/type/person', nil]
221
+ )
222
+ end
223
+
224
+ it 'should return parsed property key URIs' do
225
+ @xrd.properties.each do |k, v|
226
+ k.should be_kind_of(Addressable::URI)
227
+ v.should be_kind_of(NilClass)
228
+ end
229
+ end
230
+
231
+ it 'should return the correct links' do
232
+ @xrd.links[0].rel.should == 'http://spec.example.net/auth/1.0'
233
+ @xrd.links[0].href.should == 'http://services.example.com/auth'
234
+ @xrd.links[1].rel.should == 'http://spec.example.net/photo/1.0'
235
+ @xrd.links[1].media_type.should == 'image/jpeg'
236
+ @xrd.links[1].href.should == 'http://photos.example.com/gpburdell.jpg'
237
+ end
238
+
239
+ it 'should return the correct link titles' do
240
+ @xrd.links[1].title.should == 'User Photo'
241
+ @xrd.links[1].title('en').should == 'User Photo'
242
+ @xrd.links[1].title('de').should == 'Benutzerfoto'
243
+
244
+ @xrd.links[1].title.lang.should == 'en'
245
+ @xrd.links[1].title('en').lang.should == 'en'
246
+ @xrd.links[1].title('de').lang.should == 'de'
247
+ end
248
+
249
+ it 'should return the correct link properties' do
250
+ @xrd.links[1].properties[0][0].should ===
251
+ 'http://spec.example.net/created/1.0'
252
+ @xrd.links[1].properties[0][1].should == '1970-01-01'
253
+ end
254
+
255
+ it 'should allow links to be queried by rel value' do
256
+ links = @xrd.links(:rel => 'http://spec.example.net/auth/1.0')
257
+ links.length.should == 1
258
+ links[0].rel.should == 'http://spec.example.net/auth/1.0'
259
+ end
260
+
261
+ it 'should allow links to be queried by rel value' do
262
+ links = @xrd.links(:rel => 'alternate')
263
+ links.length.should == 0
264
+ end
265
+
266
+ it 'should allow links to be queried by media type' do
267
+ links = @xrd.links(:media_type => 'image/jpeg')
268
+ links.length.should == 1
269
+ links[0].media_type.should == 'image/jpeg'
270
+ end
271
+
272
+ it 'should allow links to be queried by media type' do
273
+ links = @xrd.links(:media_type => 'text/html')
274
+ links.length.should == 0
275
+ end
276
+
277
+ it 'should allow links to be queried by media type' do
278
+ links = @xrd.links(:media_type => 'image')
279
+ links.length.should == 1
280
+ links[0].media_type.should == 'image/jpeg'
281
+ end
282
+
283
+ it 'should allow links to be queried by media type' do
284
+ links = @xrd.links(:media_type => 'text')
285
+ links.length.should == 0
286
+ end
287
+
288
+ it 'should allow links to be queried by href' do
289
+ links = @xrd.links(:href => 'http://services.example.com/auth')
290
+ links.length.should == 1
291
+ links[0].href.should == 'http://services.example.com/auth'
292
+ end
293
+
294
+ it 'should allow links to be queried by href' do
295
+ links = @xrd.links(:href => 'http://www.example.org/')
296
+ links.length.should == 0
297
+ end
298
+
299
+ it 'should allow links to be queried by href' do
300
+ links = @xrd.links(
301
+ :href => Addressable::URI.parse('http://services.example.com/auth')
302
+ )
303
+ links.length.should == 1
304
+ links[0].href.should == 'http://services.example.com/auth'
305
+ end
306
+
307
+ it 'should allow links to be queried by href' do
308
+ links = @xrd.links(
309
+ :href => Addressable::URI.parse('http://www.example.org/')
310
+ )
311
+ links.length.should == 0
312
+ end
313
+
314
+ it 'should allow links to be queried by href' do
315
+ links = @xrd.links(:href => /services\.example\.com/)
316
+ links.length.should == 1
317
+ links[0].href.should == 'http://services.example.com/auth'
318
+ end
319
+
320
+ it 'should allow links to be queried by href' do
321
+ links = @xrd.links(:href => /www\.example\.org/)
322
+ links.length.should == 0
323
+ end
324
+
325
+ it 'should allow links to be queried by href' do
326
+ links = @xrd.links(
327
+ :href => Addressable::Template.new('http://{sub}.example.com/{path}')
328
+ )
329
+ links.length.should == 2
330
+ links[0].href.should == 'http://services.example.com/auth'
331
+ links[1].href.should == 'http://photos.example.com/gpburdell.jpg'
332
+ end
333
+
334
+ it 'should allow links to be queried by href' do
335
+ links = @xrd.links(
336
+ :href => Addressable::Template.new('http://www.example.org/{path}')
337
+ )
338
+ links.length.should == 0
339
+ end
340
+ end
341
+
342
+ describe 'when attempting to fetch and parse an XRD document' do
343
+ before do
344
+ @xml = <<-XML
345
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"
346
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
347
+ <Expires>1970-01-01T00:00:00Z</Expires>
348
+ <Subject>http://example.com/subject</Subject>
349
+ <Property type="http://spec.example.net/type/person" xsi:nil="true" />
350
+ <Link rel="http://spec.example.net/auth/1.0"
351
+ href="http://services.example.com/auth" />
352
+ <Link rel="http://spec.example.net/photo/1.0" type="image/jpeg"
353
+ href="http://photos.example.com/gpburdell.jpg">
354
+ <Title xml:lang="en">User Photo</Title>
355
+ <Title xml:lang="de">Benutzerfoto</Title>
356
+ <Property type="http://spec.example.net/created/1.0">1970-01-01</Property>
357
+ </Link>
358
+ </XRD>
359
+ XML
360
+ @adapter = HTTPAdapter::MockAdapter.request_adapter do |request, conn|
361
+ [
362
+ 200,
363
+ [['Content-Type', 'application/xrd+xml']],
364
+ [@xml],
365
+ ]
366
+ end
367
+ @xrd = XRD::ResourceDescriptor.fetch_and_parse(
368
+ 'http://example.com/xrd', @adapter
369
+ )
370
+ end
371
+
372
+ it_should_behave_like 'simple XRD example'
373
+ end
374
+
375
+ describe 'when attempting to fetch and parse an XRD document' do
376
+ before do
377
+ @xml = <<-XML
378
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"
379
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
380
+ <Expires>1970-01-01T00:00:00Z</Expires>
381
+ <Subject>http://example.com/subject</Subject>
382
+ <Property type="http://spec.example.net/type/person" xsi:nil="true" />
383
+ <Link rel="http://spec.example.net/auth/1.0"
384
+ href="http://services.example.com/auth" />
385
+ <Link rel="http://spec.example.net/photo/1.0" type="image/jpeg"
386
+ href="http://photos.example.com/gpburdell.jpg">
387
+ <Title xml:lang="en">User Photo</Title>
388
+ <Title xml:lang="de">Benutzerfoto</Title>
389
+ <Property type="http://spec.example.net/created/1.0">1970-01-01</Property>
390
+ </Link>
391
+ </XRD>
392
+ XML
393
+ @adapter = HTTPAdapter::MockAdapter.request_adapter do |request, conn|
394
+ [
395
+ 200,
396
+ [['Content-Type', 'application/xrd+xml']],
397
+ [@xml],
398
+ ]
399
+ end
400
+ @xrd = XRD.fetch_and_parse('http://example.com/xrd', @adapter)
401
+ end
402
+
403
+ it_should_behave_like 'simple XRD example'
404
+ end
405
+
406
+ describe 'when attempting to parse an XRD document with no title lang' do
407
+ before do
408
+ @xml = <<-XML
409
+ <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"
410
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
411
+ <Link rel="http://spec.example.net/photo/1.0" type="image/jpeg"
412
+ href="http://photos.example.com/gpburdell.jpg">
413
+ <Title>User Photo</Title>
414
+ <Title xml:lang="de">Benutzerfoto</Title>
415
+ </Link>
416
+ </XRD>
417
+ XML
418
+ @xrd = XRD.parse(@xml)
419
+ end
420
+
421
+ it 'should return the correct link titles' do
422
+ @xrd.links[0].title.should == 'User Photo'
423
+ @xrd.links[0].title('en').should == 'User Photo'
424
+ @xrd.links[0].title('de').should == 'Benutzerfoto'
425
+
426
+ @xrd.links[0].title.lang.should == nil
427
+ @xrd.links[0].title('en').lang.should == nil
428
+ @xrd.links[0].title('de').lang.should == 'de'
429
+ end
430
+ end
431
+ end