xcapclient 1.2.2 → 1.3.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.
- data/README.rdoc +5 -5
- data/lib/xcapclient.rb +17 -24
- data/lib/xcapclient/application.rb +60 -60
- data/lib/xcapclient/client.rb +719 -698
- data/lib/xcapclient/document.rb +51 -38
- data/lib/xcapclient/errors.rb +21 -21
- data/lib/xcapclient/version.rb +17 -0
- data/test/PRES_RULES_EXAMPLE.xml +46 -46
- data/test/test_unit_01.rb +322 -322
- metadata +4 -5
data/lib/xcapclient/document.rb
CHANGED
@@ -1,40 +1,53 @@
|
|
1
1
|
module XCAPClient
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
2
|
+
|
3
|
+
class Document
|
4
|
+
|
5
|
+
# The name of the document as it exists in the server.
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
# Contains the plain document fetched from the server or manually set.
|
9
|
+
attr_accessor :plain
|
10
|
+
|
11
|
+
# The last received ETag value in a response from the server. It can be set manually.
|
12
|
+
attr_accessor :etag
|
13
|
+
|
14
|
+
# This attribute contains the parsed instance of the XML document after calling _parse_ method.
|
15
|
+
attr_accessor :parsed
|
16
|
+
|
17
|
+
# The last response received from the server. It's a HTTP::Message[http://dev.ctor.org/doc/httpclient/] object.
|
18
|
+
attr_accessor :last_response
|
19
|
+
|
20
|
+
# Create a new instance. _name_, _plain_ and _etag_ are String.
|
21
|
+
def initialize(name, plain=nil, etag=nil, parsed=nil)
|
22
|
+
@name = name
|
23
|
+
@plain = plain
|
24
|
+
@parsed = parsed
|
25
|
+
@etag = etag
|
26
|
+
|
27
|
+
# Check name.
|
28
|
+
raise ConfigError, "Document `name' must be a non empty string" unless String === @name && ! @name.empty?
|
29
|
+
end
|
30
|
+
|
31
|
+
# Delete the local plain and parsed document and the ETag.
|
32
|
+
def reset
|
33
|
+
@plain = nil
|
34
|
+
@parsed = nil
|
35
|
+
@etag = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
if XCAPClient::NOKOGIRI_INSTALLED
|
39
|
+
# Parse the plain XML document using Nokogiri and store it into @parsed attribute.
|
40
|
+
# NOTE: This method is just available if Nokogiri is installed.
|
41
|
+
def parse
|
42
|
+
raise DocumentError, "Cannot parse the document as the plain document doesn't exist"
|
43
|
+
begin
|
44
|
+
@parsed = ::Nokogiri::XML::Document.parse(@plain, nil, "UTF-8", PARSE_OPTIONS)
|
45
|
+
rescue ::Nokogiri::SyntaxError => e
|
46
|
+
raise XMLParsingError, "XML parsing error: #{e.message}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
40
53
|
end
|
data/lib/xcapclient/errors.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
module XCAPClient
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
2
|
+
|
3
|
+
class XCAPClientError < StandardError ; end
|
4
|
+
class ConfigError < XCAPClientError ; end
|
5
|
+
class ArgumentError < XCAPClientError ; end
|
6
|
+
class ConnectionError < XCAPClientError ; end
|
7
|
+
class WrongAUID < XCAPClientError ; end
|
8
|
+
class DocumentError < XCAPClientError ; end
|
9
|
+
class HTTPError < XCAPClientError ; end
|
10
|
+
class HTTPAuthenticationError < HTTPError ; end
|
11
|
+
class HTTPForbidden < HTTPError ; end
|
12
|
+
class HTTPNoMatchingETag < HTTPError ; end
|
13
|
+
class HTTPConflictError < HTTPError ; end
|
14
|
+
class HTTPDocumentNotModified < HTTPError ; end
|
15
|
+
class HTTPDocumentNotFound < HTTPError ; end
|
16
|
+
class HTTPWrongContentType < HTTPError ; end
|
17
|
+
class HTTPBadRequest < HTTPError ; end
|
18
|
+
class HTTPServerError < HTTPError ; end
|
19
|
+
class HTTPNotImplemented < HTTPError ; end
|
20
|
+
class HTTPUnknownError < HTTPError ; end
|
21
|
+
class XMLParsingError < XCAPClientError ; end
|
22
|
+
|
23
23
|
end
|
data/test/PRES_RULES_EXAMPLE.xml
CHANGED
@@ -1,49 +1,49 @@
|
|
1
1
|
<?xml version='1.0' encoding='UTF-8'?>
|
2
2
|
<cp:ruleset xmlns:pr="urn:ietf:params:xml:ns:pres-rules" xmlns:cp="urn:ietf:params:xml:ns:common-policy">
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
3
|
+
<cp:rule id="pres_whitelist">
|
4
|
+
<cp:conditions>
|
5
|
+
<cp:identity>
|
6
|
+
<cp:one id="sip:alice@example.org"/>
|
7
|
+
<cp:one id="sip:bob@example.org"/>
|
8
|
+
<cp:one id="sip:carol@example2.net"/>
|
9
|
+
</cp:identity>
|
10
|
+
</cp:conditions>
|
11
|
+
<cp:actions>
|
12
|
+
<pr:sub-handling>allow</pr:sub-handling>
|
13
|
+
</cp:actions>
|
14
|
+
<cp:transformations>
|
15
|
+
<pr:provide-services>
|
16
|
+
<pr:all-services/>
|
17
|
+
</pr:provide-services>
|
18
|
+
<pr:provide-persons>
|
19
|
+
<pr:all-persons/>
|
20
|
+
</pr:provide-persons>
|
21
|
+
<pr:provide-devices>
|
22
|
+
<pr:all-devices/>
|
23
|
+
</pr:provide-devices>
|
24
|
+
<pr:provide-all-attributes/>
|
25
|
+
</cp:transformations>
|
26
|
+
</cp:rule>
|
27
|
+
<cp:rule id="pres_blacklist">
|
28
|
+
<cp:conditions>
|
29
|
+
<cp:identity>
|
30
|
+
<cp:one id="sip:bill@microsoft.com"/>
|
31
|
+
</cp:identity>
|
32
|
+
</cp:conditions>
|
33
|
+
<cp:actions>
|
34
|
+
<pr:sub-handling>block</pr:sub-handling>
|
35
|
+
</cp:actions>
|
36
|
+
<cp:transformations/>
|
37
|
+
</cp:rule>
|
38
|
+
<cp:rule id="pres_polite_blacklist">
|
39
|
+
<cp:conditions>
|
40
|
+
<cp:identity>
|
41
|
+
<cp:one id="sip:steve@apple.com"/>
|
42
|
+
</cp:identity>
|
43
|
+
</cp:conditions>
|
44
|
+
<cp:actions>
|
45
|
+
<pr:sub-handling>polite-block</pr:sub-handling>
|
46
|
+
</cp:actions>
|
47
|
+
<cp:transformations/>
|
48
|
+
</cp:rule>
|
49
49
|
</cp:ruleset>
|
data/test/test_unit_01.rb
CHANGED
@@ -12,8 +12,8 @@ SSL_VERIFY_CERT = false
|
|
12
12
|
|
13
13
|
# Let's check that the user has customized the above settings.
|
14
14
|
if USER == "sip:user@example.org"
|
15
|
-
|
16
|
-
|
15
|
+
STDERR.puts "ERROR: You must configure the settings with your own values. Edit the top lines of this script."
|
16
|
+
exit 1
|
17
17
|
end
|
18
18
|
|
19
19
|
|
@@ -29,324 +29,324 @@ include XCAPClient
|
|
29
29
|
# It's focused on OpenXCAP[http://www.openxcap.org] server. In fact, some tests fail due to known bugs in OpenXCAP.
|
30
30
|
#
|
31
31
|
class TestXCAPClient < Test::Unit::TestCase
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
32
|
+
|
33
|
+
|
34
|
+
PRES_RULES = File.new(File.join(File.dirname(__FILE__), "PRES_RULES_EXAMPLE.xml")).read
|
35
|
+
NS = {"pr"=>"urn:ietf:params:xml:ns:pres-rules", "cp"=>"urn:ietf:params:xml:ns:common-policy"}
|
36
|
+
|
37
|
+
|
38
|
+
def setup
|
39
|
+
|
40
|
+
xcap_conf = {
|
41
|
+
:xcap_root => XCAP_ROOT,
|
42
|
+
:user => USER,
|
43
|
+
:auth_user => AUTH_USER,
|
44
|
+
:password => PASSWORD,
|
45
|
+
:ssl_verify_cert => SSL_VERIFY_CERT
|
46
|
+
}
|
47
|
+
|
48
|
+
xcap_apps = {
|
49
|
+
"pres-rules" => {
|
50
|
+
:xmlns => "urn:ietf:params:xml:ns:pres-rules",
|
51
|
+
:mime_type => "application/auth-policy+xml",
|
52
|
+
:document_name => "pres-rules"
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
@client = Client.new(xcap_conf, xcap_apps)
|
57
|
+
@client.application("pres-rules").document.plain = PRES_RULES
|
58
|
+
|
59
|
+
@doc = @client.application("pres-rules").document
|
60
|
+
|
61
|
+
reset_document
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def teardown
|
67
|
+
reset_document
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def test_01_get
|
72
|
+
show "Fetching the document (correct ETag) => 304"
|
73
|
+
begin
|
74
|
+
assert @client.get("pres-rules")
|
75
|
+
rescue => e
|
76
|
+
assert_equal( HTTPDocumentNotModified, e.class )
|
77
|
+
else
|
78
|
+
should_fail
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def test_02_get
|
84
|
+
show "Fetching the document (wrong ETag) => 200"
|
85
|
+
@doc.etag = "wrongETag"
|
86
|
+
assert @client.get("pres-rules")
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def test_03_put
|
91
|
+
show "Replace the document (correct ETag)=> 2XX"
|
92
|
+
assert @client.put("pres-rules")
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def test_04_put
|
97
|
+
show "Replace the document (wrong ETag) => 412"
|
98
|
+
begin
|
99
|
+
@doc.etag = "wrongETag"
|
100
|
+
@client.put("pres-rules")
|
101
|
+
rescue => e
|
102
|
+
assert_equal( HTTPNoMatchingETag, e.class )
|
103
|
+
else
|
104
|
+
should_fail
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def test_05_put
|
110
|
+
show "Replace the document (no ETag) => 200"
|
111
|
+
assert @client.put("pres-rules", nil, check_etag=false)
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def test_06_delete
|
116
|
+
show "Deleting the document (correct ETag) => 200"
|
117
|
+
assert @client.delete("pres-rules")
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def test_07_delete
|
122
|
+
show "Deleting a non existing document (no ETag) => 404"
|
123
|
+
@client.delete("pres-rules")
|
124
|
+
begin
|
125
|
+
@client.delete("pres-rules")
|
126
|
+
rescue => e
|
127
|
+
assert_equal( HTTPDocumentNotFound, e.class )
|
128
|
+
else
|
129
|
+
should_fail
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def test_08_delete
|
135
|
+
show "Deleting the document (wrong ETag) => 412"
|
136
|
+
begin
|
137
|
+
@doc.etag = "wrongETag"
|
138
|
+
@client.delete("pres-rules")
|
139
|
+
rescue => e
|
140
|
+
assert_equal( HTTPNoMatchingETag, e.class )
|
141
|
+
else
|
142
|
+
should_fail
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def test_09_delete
|
148
|
+
show "Deleting the document (no ETag) => 200"
|
149
|
+
assert @client.delete("pres-rules", nil, check_etag=false)
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def test_10_get_element
|
154
|
+
show "Fetching a node (no ETag) => 200"
|
155
|
+
assert @client.get_element("pres-rules", nil,
|
156
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
157
|
+
NS,
|
158
|
+
check_etag=false)
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def test_11_get_element
|
163
|
+
show "Fetching a node (correct ETag) => 304"
|
164
|
+
begin
|
165
|
+
@client.get_element("pres-rules", nil,
|
166
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
167
|
+
NS,
|
168
|
+
check_etag=true)
|
169
|
+
rescue => e
|
170
|
+
assert_equal( HTTPDocumentNotModified, e.class )
|
171
|
+
else
|
172
|
+
should_fail
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
# NOTE: OpenXCAP doesn't implement fetching element attributes.
|
178
|
+
# BUG in OpenXCAP: http://openxcap.org/ticket/122
|
179
|
+
def test_12_get_element
|
180
|
+
show "Fetching an attribute (no ETag) => 200 (fails in OpenXCAP, bug http://openxcap.org/ticket/122)"
|
181
|
+
assert @client.get_element("pres-rules", nil,
|
182
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]/@id',
|
183
|
+
NS,
|
184
|
+
check_etag=false)
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
def test_13_put_element
|
189
|
+
show "Creating a node (no ETag) => 201"
|
190
|
+
assert @client.put_element("pres-rules", nil,
|
191
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:new-1@new.net"]',
|
192
|
+
'<cp:one id="sip:new-1@new.net"/>',
|
193
|
+
NS,
|
194
|
+
check_etag=false)
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
def test_14_put_element
|
199
|
+
show "Creating a node (wrong ETag) => 412"
|
200
|
+
begin
|
201
|
+
@doc.etag = "wrongETag"
|
202
|
+
@client.put_element("pres-rules", nil,
|
203
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:condition/cp:identity/cp:one[@id="sip:new-2@new.net"]',
|
204
|
+
'<cp:one id="sip:new-2@new.net"/>',
|
205
|
+
NS,
|
206
|
+
check_etag=true)
|
207
|
+
rescue => e
|
208
|
+
assert_equal( HTTPNoMatchingETag, e.class )
|
209
|
+
else
|
210
|
+
should_fail
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def test_15_put_element
|
216
|
+
show "Creating a node in wrong position => 409"
|
217
|
+
begin
|
218
|
+
@client.put_element("pres-rules", nil,
|
219
|
+
'cp:ruleset/cp:rule[@id="non_existing"]/cp:condition/cp:identity/cp:one[@id="sip:new-3@new.net"]',
|
220
|
+
'<cp:one id="sip:new-3@new.net"/>',
|
221
|
+
NS,
|
222
|
+
check_etag=false)
|
223
|
+
rescue => e
|
224
|
+
assert_equal( HTTPConflictError, e.class )
|
225
|
+
else
|
226
|
+
should_fail
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
def test_16_put_element
|
232
|
+
show "Creating a node using different NS prefixes than the used in the server document (no ETag) => 409/500"
|
233
|
+
begin
|
234
|
+
@client.put_element("pres-rules", nil,
|
235
|
+
'ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]/ccpp:conditions/ccpp:identity/ccpp:one[@id="sip:new-4@new.net"]',
|
236
|
+
'<ccpp:one id="sip:new-4@new.net"/>',
|
237
|
+
{"pprr"=>"urn:ietf:params:xml:ns:pres-rules", "ccpp"=>"urn:ietf:params:xml:ns:common-policy"},
|
238
|
+
check_etag=false)
|
239
|
+
rescue => e
|
240
|
+
assert_equal_options( [ HTTPServerError, HTTPConflictError ], e.class )
|
241
|
+
else
|
242
|
+
should_fail
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
# NOTE: This should fail since the selector doesn't match an unique node, but OpenXCAP allows it.
|
248
|
+
# BUG in OpenXCAP: http://openxcap.org/ticket/123
|
249
|
+
def test_17_put_element
|
250
|
+
show "Creating a node using using a non unique selector (no ETag) => 409 (fails in OpenXCAP, bug http://openxcap.org/ticket/123)"
|
251
|
+
begin
|
252
|
+
@client.put_element("pres-rules", nil,
|
253
|
+
'cp:ruleset/cp:rule/cp:conditions/cp:identity/cp:one[@id="sip:new-5@new.net"]',
|
254
|
+
'<cp:one id="sip:new-5@new.net"/>',
|
255
|
+
NS,
|
256
|
+
check_etag=false)
|
257
|
+
rescue
|
258
|
+
assert_equal( HTTPConflictError, e.class )
|
259
|
+
else
|
260
|
+
should_fail
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
def test_18_delete_element
|
266
|
+
show "Deleting an element (no ETag) => 200"
|
267
|
+
assert @client.delete_element("pres-rules", nil,
|
268
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
269
|
+
NS,
|
270
|
+
check_etag=false)
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
def test_19_delete_element
|
275
|
+
show "Deleting an element (wrong ETag) => 412"
|
276
|
+
begin
|
277
|
+
@doc.etag = "wrongETag"
|
278
|
+
@client.delete_element("pres-rules", nil,
|
279
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:condition/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
280
|
+
NS,
|
281
|
+
check_etag=true)
|
282
|
+
rescue => e
|
283
|
+
assert_equal( HTTPNoMatchingETag, e.class )
|
284
|
+
else
|
285
|
+
should_fail
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
def test_20_delete_element
|
291
|
+
show "Deleting a no existing element (correct ETag) => 404"
|
292
|
+
@client.delete_element("pres-rules", nil,
|
293
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
294
|
+
NS)
|
295
|
+
begin
|
296
|
+
@client.delete_element("pres-rules", nil,
|
297
|
+
'/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
298
|
+
NS)
|
299
|
+
rescue => e
|
300
|
+
assert_equal( HTTPDocumentNotFound, e.class )
|
301
|
+
else
|
302
|
+
should_fail
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
# NOTE: OpenXCAP doesn't implement fetching namespaces.
|
308
|
+
# BUG in OpenXCAP: http://openxcap.org/ticket/124
|
309
|
+
def test_21_get_element_namespaces
|
310
|
+
show "Fetching the namespaces associated to a document node => 200 (fails in OpenXCAP, bug http://openxcap.org/ticket/124)"
|
311
|
+
assert @client.get_element_namespaces("pres-rules", nil,
|
312
|
+
'ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]/ccpp:conditions/ccpp:identity',
|
313
|
+
{"ccpp"=>"urn:ietf:params:xml:ns:common-policy"},
|
314
|
+
check_etag=false)
|
315
|
+
assert_equal( @client.application("pres-rules").document.last_response.header["Content-Type"], "application/xcap-ns+xml" )
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
def test_22_get_xcap_auids
|
320
|
+
show "Fetching the XCAP server available 'auids' => 200"
|
321
|
+
assert @client.get_xcap_auids
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
def reset_document
|
326
|
+
@doc.plain = PRES_RULES
|
327
|
+
@doc.etag = nil
|
328
|
+
@client.put("pres-rules", nil, check_etag=false) # Upload without cheking ETag.
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
def show(text)
|
333
|
+
puts "\n\n[#{name}] #{text}"
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
def should_fail
|
338
|
+
raise RuntimeError, "It should fail but didn't"
|
339
|
+
end
|
340
|
+
|
341
|
+
|
342
|
+
def assert_false(object, message="")
|
343
|
+
assert_equal(object, false, message)
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
def assert_equal_options(options, element)
|
348
|
+
assert options.include?(element)
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
352
|
end
|