ruby-saml 0.9 → 0.9.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.

Potentially problematic release.


This version of ruby-saml might be problematic. Click here for more details.

@@ -1,12 +1,13 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
- class SettingsTest < Test::Unit::TestCase
3
+ class SettingsTest < Minitest::Test
4
4
 
5
- context "Settings" do
6
- setup do
5
+ describe "Settings" do
6
+ before do
7
7
  @settings = OneLogin::RubySaml::Settings.new
8
8
  end
9
- should "should provide getters and settings" do
9
+
10
+ it "should provide getters and settings" do
10
11
  accessors = [
11
12
  :idp_entity_id, :idp_sso_target_url, :idp_slo_target_url, :idp_cert, :idp_cert_fingerprint,
12
13
  :issuer, :assertion_consumer_service_url, :assertion_consumer_service_binding,
@@ -28,7 +29,7 @@ class SettingsTest < Test::Unit::TestCase
28
29
 
29
30
  end
30
31
 
31
- should "create settings from hash" do
32
+ it "create settings from hash" do
32
33
 
33
34
  config = {
34
35
  :assertion_consumer_service_url => "http://app.muda.no/sso",
@@ -49,18 +50,16 @@ class SettingsTest < Test::Unit::TestCase
49
50
  end
50
51
  end
51
52
 
52
- should "configure attribute service attributes correctly" do
53
+ it "configure attribute service attributes correctly" do
53
54
  @settings = OneLogin::RubySaml::Settings.new
54
55
  @settings.attribute_consuming_service.configure do
55
56
  service_name "Test Service"
56
- add_attribute :name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name"
57
+ add_attribute :name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name"
57
58
  end
58
59
 
59
60
  assert_equal @settings.attribute_consuming_service.configured?, true
60
61
  assert_equal @settings.attribute_consuming_service.name, "Test Service"
61
62
  assert_equal @settings.attribute_consuming_service.attributes, [{:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name" }]
62
63
  end
63
-
64
64
  end
65
-
66
65
  end
@@ -1,63 +1,62 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
  require 'responses/logoutresponse_fixtures'
3
3
 
4
- class RubySamlTest < Test::Unit::TestCase
4
+ class RubySamlTest < Minitest::Test
5
5
 
6
- context "SloLogoutrequest" do
7
- should "raise an exception when response is initialized with nil" do
6
+ describe "SloLogoutrequest" do
7
+ it "raise an exception when response is initialized with nil" do
8
8
  assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
9
9
  end
10
10
 
11
- context "#is_valid?" do
12
- should "return false when response is initialized with blank data" do
11
+ describe "#is_valid?" do
12
+ it "return false when response is initialized with blank data" do
13
13
  request = OneLogin::RubySaml::SloLogoutrequest.new('')
14
14
  assert !request.is_valid?
15
15
  end
16
16
 
17
- should "return true when the request is initialized with valid data" do
17
+ it "return true when the request is initialized with valid data" do
18
18
  request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
19
19
  assert request.is_valid?
20
20
  assert_equal 'someone@example.org', request.name_id
21
21
  end
22
22
 
23
- should "should be idempotent when the response is initialized with invalid data" do
23
+ it "should be idempotent when the response is initialized with invalid data" do
24
24
  request = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_response)
25
25
  assert !request.is_valid?
26
26
  assert !request.is_valid?
27
27
  end
28
28
 
29
- should "should be idempotent when the response is initialized with valid data" do
29
+ it "should be idempotent when the response is initialized with valid data" do
30
30
  request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
31
31
  assert request.is_valid?
32
32
  assert request.is_valid?
33
33
  end
34
34
 
35
- should "raise error for invalid xml" do
35
+ it "raise error for invalid xml" do
36
36
  logout_request = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_response)
37
37
  assert_raises(OneLogin::RubySaml::ValidationError) { logout_request.validate! }
38
38
  end
39
39
  end
40
40
 
41
- context "#name_id" do
42
- should "extract the value of the name id element" do
41
+ describe "#name_id" do
42
+ it "extract the value of the name id element" do
43
43
  request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
44
44
  assert_equal "someone@example.org", request.name_id
45
45
  end
46
46
  end
47
47
 
48
- context "#issuer" do
49
- should "return the issuer inside the request" do
48
+ describe "#issuer" do
49
+ it "return the issuer inside the request" do
50
50
  request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
51
51
  assert_equal "https://app.onelogin.com/saml/metadata/SOMEACCOUNT", request.issuer
52
52
  end
53
53
  end
54
54
 
55
- context "#id" do
56
- should "extract the value of the ID attribute" do
55
+ describe "#id" do
56
+ it "extract the value of the ID attribute" do
57
57
  request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
58
58
  assert_equal "_c0348950-935b-0131-1060-782bcb56fcaa", request.id
59
59
  end
60
60
  end
61
-
62
61
  end
63
62
  end
@@ -1,11 +1,11 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
- class SloLogoutresponseTest < Test::Unit::TestCase
3
+ class SloLogoutresponseTest < Minitest::Test
4
4
 
5
- context "SloLogoutresponse" do
6
- settings = OneLogin::RubySaml::Settings.new
5
+ describe "SloLogoutresponse" do
6
+ let(:settings) { OneLogin::RubySaml::Settings.new }
7
7
 
8
- should "create the deflated SAMLResponse URL parameter" do
8
+ it "create the deflated SAMLResponse URL parameter" do
9
9
  settings.idp_slo_target_url = "http://unauth.com/logout"
10
10
  settings.name_identifier_value = "f00f00"
11
11
  settings.compress_request = true
@@ -22,7 +22,7 @@ class SloLogoutresponseTest < Test::Unit::TestCase
22
22
  assert_match /^<samlp:LogoutResponse/, inflated
23
23
  end
24
24
 
25
- should "support additional params" do
25
+ it "support additional params" do
26
26
  settings.idp_slo_target_url = "http://unauth.com/logout"
27
27
  settings.name_identifier_value = "f00f00"
28
28
  settings.compress_request = true
@@ -39,7 +39,7 @@ class SloLogoutresponseTest < Test::Unit::TestCase
39
39
  assert unauth_url =~ /&RelayState=http%3A%2F%2Fidp.example.com$/
40
40
  end
41
41
 
42
- should "set InResponseTo to the ID from the logout request" do
42
+ it "set InResponseTo to the ID from the logout request" do
43
43
  settings.idp_slo_target_url = "http://unauth.com/logout"
44
44
  settings.name_identifier_value = "f00f00"
45
45
  settings.compress_request = true
@@ -52,7 +52,7 @@ class SloLogoutresponseTest < Test::Unit::TestCase
52
52
  assert_match /InResponseTo='_c0348950-935b-0131-1060-782bcb56fcaa'/, inflated
53
53
  end
54
54
 
55
- should "set a custom successful logout message on the response" do
55
+ it "set a custom successful logout message on the response" do
56
56
  settings.idp_slo_target_url = "http://unauth.com/logout"
57
57
  settings.name_identifier_value = "f00f00"
58
58
  settings.compress_request = true
@@ -65,8 +65,8 @@ class SloLogoutresponseTest < Test::Unit::TestCase
65
65
  assert_match /<samlp:StatusMessage>Custom Logout Message<\/samlp:StatusMessage>/, inflated
66
66
  end
67
67
 
68
- context "when the settings indicate to sign (embebed) the logout response" do
69
- should "create a signed logout response" do
68
+ describe "when the settings indicate to sign (embebed) the logout response" do
69
+ it "create a signed logout response" do
70
70
  settings = OneLogin::RubySaml::Settings.new
71
71
  settings.compress_response = false
72
72
  settings.idp_slo_target_url = "http://example.com?field=value"
@@ -84,7 +84,7 @@ class SloLogoutresponseTest < Test::Unit::TestCase
84
84
  response_xml =~ /<ds:DigestMethod Algorithm='http:\/\/www.w3.org\/2000\/09\/xmldsig#rsa-sha1'\/>/
85
85
  end
86
86
 
87
- should "create a signed logout response with 256 digest and signature methods" do
87
+ it "create a signed logout response with 256 digest and signature methods" do
88
88
  settings = OneLogin::RubySaml::Settings.new
89
89
  settings.compress_response = false
90
90
  settings.idp_slo_target_url = "http://example.com?field=value"
@@ -105,8 +105,8 @@ class SloLogoutresponseTest < Test::Unit::TestCase
105
105
  end
106
106
  end
107
107
 
108
- context "when the settings indicate to sign the logout response" do
109
- should "create a signature parameter" do
108
+ describe "when the settings indicate to sign the logout response" do
109
+ it "create a signature parameter" do
110
110
  settings = OneLogin::RubySaml::Settings.new
111
111
  settings.compress_response = false
112
112
  settings.idp_slo_target_url = "http://example.com?field=value"
@@ -129,18 +129,5 @@ class SloLogoutresponseTest < Test::Unit::TestCase
129
129
  assert params['SigAlg'] == XMLSecurity::Document::SHA1
130
130
  end
131
131
  end
132
-
133
132
  end
134
-
135
- def decode_saml_response_payload(unauth_url)
136
- payload = CGI.unescape(unauth_url.split("SAMLResponse=").last)
137
- decoded = Base64.decode64(payload)
138
-
139
- zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
140
- inflated = zstream.inflate(decoded)
141
- zstream.finish
142
- zstream.close
143
- inflated
144
- end
145
-
146
133
  end
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- require 'test/unit'
3
+ require 'minitest/autorun'
4
4
  require 'mocha/setup'
5
5
 
6
6
  Bundler.require :default, :test
@@ -11,7 +11,7 @@ require 'ruby-saml'
11
11
 
12
12
  ENV["ruby-saml/testing"] = "1"
13
13
 
14
- class Test::Unit::TestCase
14
+ class Minitest::Test
15
15
  def fixture(document, base64 = true)
16
16
  response = Dir.glob(File.join(File.dirname(__FILE__), "responses", "#{document}*")).first
17
17
  if base64 && response =~ /\.xml$/
@@ -109,4 +109,38 @@ class Test::Unit::TestCase
109
109
  File.read(File.join(File.dirname(__FILE__), 'certificates', 'ruby-saml.key'))
110
110
  end
111
111
 
112
+ #
113
+ # logoutresponse fixtures
114
+ #
115
+ def random_id
116
+ "_#{UUID.new.generate}"
117
+ end
118
+
119
+ #
120
+ # decodes a base64 encoded SAML response for use in SloLogoutresponse tests
121
+ #
122
+ def decode_saml_response_payload(unauth_url)
123
+ payload = CGI.unescape(unauth_url.split("SAMLResponse=").last)
124
+ decoded = Base64.decode64(payload)
125
+
126
+ zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
127
+ inflated = zstream.inflate(decoded)
128
+ zstream.finish
129
+ zstream.close
130
+ inflated
131
+ end
132
+
133
+ #
134
+ # decodes a base64 encoded SAML request for use in Logoutrequest tests
135
+ #
136
+ def decode_saml_request_payload(unauth_url)
137
+ payload = CGI.unescape(unauth_url.split("SAMLRequest=").last)
138
+ decoded = Base64.decode64(payload)
139
+
140
+ zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
141
+ inflated = zstream.inflate(decoded)
142
+ zstream.finish
143
+ zstream.close
144
+ inflated
145
+ end
112
146
  end
@@ -1,112 +1,109 @@
1
- require 'test_helper'
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
  require 'xml_security'
3
+ require 'timecop'
3
4
 
4
- class XmlSecurityTest < Test::Unit::TestCase
5
+ class XmlSecurityTest < Minitest::Test
5
6
  include XMLSecurity
6
7
 
7
- context "XmlSecurity" do
8
- setup do
8
+ describe "XmlSecurity" do
9
+ before do
9
10
  @document = XMLSecurity::SignedDocument.new(Base64.decode64(response_document))
10
11
  @base64cert = @document.elements["//ds:X509Certificate"].text
11
12
  end
12
13
 
13
- should "should run validate without throwing NS related exceptions" do
14
+ it "should run validate without throwing NS related exceptions" do
14
15
  assert !@document.validate_signature(@base64cert, true)
15
16
  end
16
17
 
17
- should "should run validate with throwing NS related exceptions" do
18
- assert_raise(OneLogin::RubySaml::ValidationError) do
18
+ it "should run validate with throwing NS related exceptions" do
19
+ assert_raises(OneLogin::RubySaml::ValidationError) do
19
20
  @document.validate_signature(@base64cert, false)
20
21
  end
21
22
  end
22
23
 
23
- should "not raise an error when softly validating the document multiple times" do
24
- assert_nothing_raised do
25
- 2.times { @document.validate_signature(@base64cert, true) }
26
- end
24
+ it "not raise an error when softly validating the document multiple times" do
25
+ 2.times { assert_equal @document.validate_signature(@base64cert, true), false }
27
26
  end
28
27
 
29
- should "not raise an error when softly validating the document and the X509Certificate is missing" do
28
+ it "not raise an error when softly validating the document and the X509Certificate is missing" do
30
29
  response = Base64.decode64(response_document)
31
30
  response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
32
31
  document = XMLSecurity::SignedDocument.new(response)
33
- assert_nothing_raised do
34
- assert !document.validate_document("a fingerprint", true) # The fingerprint isn't relevant to this test
35
- end
32
+ assert !document.validate_document("a fingerprint", true) # The fingerprint isn't relevant to this test
36
33
  end
37
34
 
38
- should "should raise Fingerprint mismatch" do
39
- exception = assert_raise(OneLogin::RubySaml::ValidationError) do
35
+ it "should raise Fingerprint mismatch" do
36
+ exception = assert_raises(OneLogin::RubySaml::ValidationError) do
40
37
  @document.validate_document("no:fi:ng:er:pr:in:t", false)
41
38
  end
42
39
  assert_equal("Fingerprint mismatch", exception.message)
43
40
  assert @document.errors.include? "Fingerprint mismatch"
44
41
  end
45
42
 
46
- should "should raise Digest mismatch" do
47
- exception = assert_raise(OneLogin::RubySaml::ValidationError) do
43
+ it "should raise Digest mismatch" do
44
+ exception = assert_raises(OneLogin::RubySaml::ValidationError) do
48
45
  @document.validate_signature(@base64cert, false)
49
46
  end
50
47
  assert_equal("Digest mismatch", exception.message)
51
48
  assert @document.errors.include? "Digest mismatch"
52
49
  end
53
50
 
54
- should "should raise Key validation error" do
51
+ it "should raise Key validation error" do
55
52
  response = Base64.decode64(response_document)
56
53
  response.sub!("<ds:DigestValue>pJQ7MS/ek4KRRWGmv/H43ReHYMs=</ds:DigestValue>",
57
54
  "<ds:DigestValue>b9xsAXLsynugg3Wc1CI3kpWku+0=</ds:DigestValue>")
58
55
  document = XMLSecurity::SignedDocument.new(response)
59
56
  base64cert = document.elements["//ds:X509Certificate"].text
60
- exception = assert_raise(OneLogin::RubySaml::ValidationError) do
57
+ exception = assert_raises(OneLogin::RubySaml::ValidationError) do
61
58
  document.validate_signature(base64cert, false)
62
59
  end
63
60
  assert_equal("Key validation error", exception.message)
64
61
  assert document.errors.include? "Key validation error"
65
62
  end
66
63
 
67
- should "correctly obtain the digest method with alternate namespace declaration" do
64
+ it "correctly obtain the digest method with alternate namespace declaration" do
68
65
  document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_xmlns, false))
69
66
  base64cert = document.elements["//X509Certificate"].text
70
67
  assert document.validate_signature(base64cert, false)
71
68
  end
72
69
 
73
- should "raise validation error when the X509Certificate is missing" do
70
+ it "raise validation error when the X509Certificate is missing" do
74
71
  response = Base64.decode64(response_document)
75
72
  response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
76
73
  document = XMLSecurity::SignedDocument.new(response)
77
- exception = assert_raise(OneLogin::RubySaml::ValidationError) do
74
+ exception = assert_raises(OneLogin::RubySaml::ValidationError) do
78
75
  document.validate_document("a fingerprint", false) # The fingerprint isn't relevant to this test
79
76
  end
80
77
  assert_equal("Certificate element missing in response (ds:X509Certificate)", exception.message)
81
78
  end
82
79
  end
83
80
 
84
- context "Algorithms" do
85
- should "validate using SHA1" do
81
+ describe "Algorithms" do
82
+ it "validate using SHA1" do
86
83
  @document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
87
84
  assert @document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
88
85
  end
89
86
 
90
- should "validate using SHA256" do
87
+ it "validate using SHA256" do
91
88
  @document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false))
92
89
  assert @document.validate_document("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")
93
90
  end
94
91
 
95
- should "validate using SHA384" do
92
+ it "validate using SHA384" do
96
93
  @document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false))
97
94
  assert @document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
98
95
  end
99
96
 
100
- should "validate using SHA512" do
97
+ it "validate using SHA512" do
101
98
  @document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false))
102
99
  assert @document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
103
100
  end
104
101
  end
105
102
 
106
- context "XmlSecurity::SignedDocument" do
103
+ describe "XmlSecurity::SignedDocument" do
107
104
 
108
- context "#extract_inclusive_namespaces" do
109
- should "support explicit namespace resolution for exclusive canonicalization" do
105
+ describe "#extract_inclusive_namespaces" do
106
+ it "support explicit namespace resolution for exclusive canonicalization" do
110
107
  response = fixture(:open_saml_response, false)
111
108
  document = XMLSecurity::SignedDocument.new(response)
112
109
  inclusive_namespaces = document.send(:extract_inclusive_namespaces)
@@ -114,7 +111,7 @@ class XmlSecurityTest < Test::Unit::TestCase
114
111
  assert_equal %w[ xs ], inclusive_namespaces
115
112
  end
116
113
 
117
- should "support implicit namespace resolution for exclusive canonicalization" do
114
+ it "support implicit namespace resolution for exclusive canonicalization" do
118
115
  response = fixture(:no_signature_ns, false)
119
116
  document = XMLSecurity::SignedDocument.new(response)
120
117
  inclusive_namespaces = document.send(:extract_inclusive_namespaces)
@@ -122,8 +119,8 @@ class XmlSecurityTest < Test::Unit::TestCase
122
119
  assert_equal %w[ #default saml ds xs xsi ], inclusive_namespaces
123
120
  end
124
121
 
125
- should_eventually 'support inclusive canonicalization' do
126
-
122
+ it 'support inclusive canonicalization' do
123
+ skip('test not yet implemented')
127
124
  response = OneLogin::RubySaml::Response.new(fixture("tdnf_response.xml"))
128
125
  response.stubs(:conditions).returns(nil)
129
126
  assert !response.is_valid?
@@ -135,7 +132,7 @@ class XmlSecurityTest < Test::Unit::TestCase
135
132
  assert response.validate!
136
133
  end
137
134
 
138
- should "return an empty list when inclusive namespace element is missing" do
135
+ it "return an empty list when inclusive namespace element is missing" do
139
136
  response = fixture(:no_signature_ns, false)
140
137
  response.slice! %r{<InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="#default saml ds xs xsi"/>}
141
138
 
@@ -146,8 +143,8 @@ class XmlSecurityTest < Test::Unit::TestCase
146
143
  end
147
144
  end
148
145
 
149
- context "XMLSecurity::DSIG" do
150
- should "sign a AuthNRequest" do
146
+ describe "XMLSecurity::DSIG" do
147
+ it "sign a AuthNRequest" do
151
148
  settings = OneLogin::RubySaml::Settings.new({
152
149
  :idp_sso_target_url => "https://idp.example.com/sso",
153
150
  :protocol_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
@@ -163,7 +160,7 @@ class XmlSecurityTest < Test::Unit::TestCase
163
160
  signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
164
161
  end
165
162
 
166
- should "sign a LogoutRequest" do
163
+ it "sign a LogoutRequest" do
167
164
  settings = OneLogin::RubySaml::Settings.new({
168
165
  :idp_slo_target_url => "https://idp.example.com/slo",
169
166
  :protocol_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
@@ -179,7 +176,7 @@ class XmlSecurityTest < Test::Unit::TestCase
179
176
  signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
180
177
  end
181
178
 
182
- should "sign a LogoutResponse" do
179
+ it "sign a LogoutResponse" do
183
180
  settings = OneLogin::RubySaml::Settings.new({
184
181
  :idp_slo_target_url => "https://idp.example.com/slo",
185
182
  :protocol_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
@@ -196,33 +193,31 @@ class XmlSecurityTest < Test::Unit::TestCase
196
193
  end
197
194
  end
198
195
 
199
- context "StarfieldTMS" do
200
- setup do
196
+ describe "StarfieldTMS" do
197
+ before do
201
198
  @response = OneLogin::RubySaml::Response.new(fixture(:starfield_response))
202
199
  @response.settings = OneLogin::RubySaml::Settings.new(
203
200
  :idp_cert_fingerprint => "8D:BA:53:8E:A3:B6:F9:F1:69:6C:BB:D9:D8:BD:41:B3:AC:4F:9D:4D"
204
201
  )
205
202
  end
206
203
 
207
- should "be able to validate a good response" do
204
+ it "be able to validate a good response" do
208
205
  Timecop.freeze Time.parse('2012-11-28 17:55:00 UTC') do
209
206
  assert @response.validate!
210
207
  end
211
208
  end
212
209
 
213
- should "fail before response is valid" do
210
+ it "fail before response is valid" do
214
211
  Timecop.freeze Time.parse('2012-11-20 17:55:00 UTC') do
215
212
  assert ! @response.is_valid?
216
213
  end
217
214
  end
218
215
 
219
- should "fail after response expires" do
216
+ it "fail after response expires" do
220
217
  Timecop.freeze Time.parse('2012-11-30 17:55:00 UTC') do
221
218
  assert ! @response.is_valid?
222
219
  end
223
220
  end
224
221
  end
225
-
226
222
  end
227
-
228
223
  end