ruby-sslyze 0.2.1 → 1.0.0

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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -4
  3. data/.travis.yml +15 -7
  4. data/ChangeLog.md +29 -12
  5. data/Gemfile +3 -2
  6. data/LICENSE.txt +1 -1
  7. data/README.md +5 -5
  8. data/Rakefile +1 -1
  9. data/lib/sslyze/cipher_suites.rb +176 -0
  10. data/lib/sslyze/program.rb +8 -8
  11. data/lib/sslyze/task.rb +40 -33
  12. data/lib/sslyze/version.rb +1 -1
  13. data/lib/sslyze/{certificate/domain_name.rb → x509/domain.rb} +5 -3
  14. data/lib/sslyze/x509/extension.rb +15 -0
  15. data/lib/sslyze/x509/extension_set.rb +140 -0
  16. data/lib/sslyze/x509/extensions.rb +6 -0
  17. data/lib/sslyze/x509/extensions/basic_constraints.rb +41 -0
  18. data/lib/sslyze/x509/extensions/certificate_policies.rb +108 -0
  19. data/lib/sslyze/x509/extensions/crl_distribution_points.rb +47 -0
  20. data/lib/sslyze/x509/extensions/extended_key_usage.rb +58 -0
  21. data/lib/sslyze/x509/extensions/key_usage.rb +66 -0
  22. data/lib/sslyze/x509/extensions/subject_alt_name.rb +144 -0
  23. data/lib/sslyze/x509/name.rb +194 -0
  24. data/lib/sslyze/x509/public_key.rb +53 -0
  25. data/lib/sslyze/xml.rb +26 -37
  26. data/lib/sslyze/xml/attributes.rb +5 -0
  27. data/lib/sslyze/xml/attributes/error.rb +30 -0
  28. data/lib/sslyze/xml/attributes/exception.rb +30 -0
  29. data/lib/sslyze/xml/attributes/is_supported.rb +29 -0
  30. data/lib/sslyze/xml/attributes/is_vulnerable.rb +29 -0
  31. data/lib/sslyze/xml/attributes/title.rb +31 -0
  32. data/lib/sslyze/xml/certinfo.rb +67 -0
  33. data/lib/sslyze/xml/certinfo/certificate.rb +202 -0
  34. data/lib/sslyze/xml/certinfo/certificate_validation.rb +69 -0
  35. data/lib/sslyze/xml/certinfo/certificate_validation/hostname_validation.rb +54 -0
  36. data/lib/sslyze/xml/certinfo/certificate_validation/path_validation.rb +84 -0
  37. data/lib/sslyze/xml/certinfo/certificate_validation/verified_certificate_chain.rb +41 -0
  38. data/lib/sslyze/xml/certinfo/has_certificates.rb +102 -0
  39. data/lib/sslyze/xml/certinfo/ocsp_stapling.rb +45 -0
  40. data/lib/sslyze/xml/certinfo/ocsp_stapling/ocsp_response.rb +87 -0
  41. data/lib/sslyze/xml/certinfo/received_certificate_chain.rb +48 -0
  42. data/lib/sslyze/xml/compression.rb +33 -0
  43. data/lib/sslyze/xml/compression/compression_method.rb +38 -0
  44. data/lib/sslyze/xml/fallback.rb +34 -0
  45. data/lib/sslyze/xml/fallback/tls_fallback_scsv.rb +27 -0
  46. data/lib/sslyze/xml/heartbleed.rb +38 -0
  47. data/lib/sslyze/xml/heartbleed/openssl_heartbleed.rb +29 -0
  48. data/lib/sslyze/xml/http_headers.rb +42 -0
  49. data/lib/sslyze/xml/http_headers/http_public_key_pinning.rb +121 -0
  50. data/lib/sslyze/xml/http_headers/http_strict_transport_security.rb +59 -0
  51. data/lib/sslyze/xml/invalid_target.rb +33 -0
  52. data/lib/sslyze/xml/openssl_ccs.rb +34 -0
  53. data/lib/sslyze/xml/openssl_ccs/openssl_ccs_injection.rb +26 -0
  54. data/lib/sslyze/xml/plugin.rb +27 -0
  55. data/lib/sslyze/xml/protocol.rb +143 -0
  56. data/lib/sslyze/xml/protocol/cipher_suite.rb +93 -0
  57. data/lib/sslyze/xml/protocol/cipher_suite/key_exchange.rb +127 -0
  58. data/lib/sslyze/xml/reneg.rb +28 -0
  59. data/lib/sslyze/xml/reneg/session_renegotiation.rb +51 -0
  60. data/lib/sslyze/xml/resum.rb +42 -0
  61. data/lib/sslyze/xml/resum/session_resumption_with_session_ids.rb +94 -0
  62. data/lib/sslyze/xml/resum/session_resumption_with_tls_tickets.rb +69 -0
  63. data/lib/sslyze/xml/resum_rate.rb +30 -0
  64. data/lib/sslyze/xml/target.rb +371 -0
  65. data/lib/sslyze/xml/types.rb +19 -0
  66. data/ruby-sslyze.gemspec +3 -3
  67. data/spec/spec_helper.rb +2 -4
  68. data/spec/sslyze.xml +2356 -2580
  69. data/spec/x509/domain_spec.rb +125 -0
  70. data/spec/x509/extension_set_spec.rb +208 -0
  71. data/spec/x509/extension_spec.rb +58 -0
  72. data/spec/x509/extensions/basic_constraints_spec.rb +41 -0
  73. data/spec/x509/extensions/certificate_policies_spec.rb +38 -0
  74. data/spec/x509/extensions/crl_distribution_points_spec.rb +38 -0
  75. data/spec/x509/extensions/extended_key_usage_spec.rb +58 -0
  76. data/spec/x509/extensions/key_usage_spec.rb +84 -0
  77. data/spec/x509/extensions/subject_alt_name_spec.rb +146 -0
  78. data/spec/x509/name_spec.rb +85 -0
  79. data/spec/x509/public_key_spec.rb +113 -0
  80. data/spec/xml/certinfo/certificate_spec.rb +166 -0
  81. data/spec/xml/certinfo/certificate_validation/hostname_validation_spec.rb +23 -0
  82. data/spec/xml/certinfo/certificate_validation/path_validation_spec.rb +107 -0
  83. data/spec/xml/certinfo/certificate_validation/verified_certificate_chain_spec.rb +163 -0
  84. data/spec/xml/certinfo/certificate_validation_spec.rb +40 -0
  85. data/spec/xml/certinfo/ocsp_stapling/ocsp_response_spec.rb +61 -0
  86. data/spec/xml/certinfo/ocsp_stapling_spec.rb +31 -0
  87. data/spec/xml/certinfo/received_certificate_chain_spec.rb +165 -0
  88. data/spec/xml/certinfo_spec.rb +45 -0
  89. data/spec/xml/compression/compression_method_spec.rb +23 -0
  90. data/spec/xml/compression_spec.rb +23 -0
  91. data/spec/xml/heartbleed/openssl_heartbleed_spec.rb +17 -0
  92. data/spec/xml/heartbleed_spec.rb +37 -0
  93. data/spec/xml/http_headers/http_public_key_pinning_spec.rb +73 -0
  94. data/spec/xml/http_headers/http_strict_transport_security_spec.rb +107 -0
  95. data/spec/xml/http_headers_spec.rb +63 -0
  96. data/spec/xml/invalid_target_spec.rb +23 -0
  97. data/spec/xml/plugin_examples.rb +14 -0
  98. data/spec/{key_exchange_spec.rb → xml/protocol/cipher_suite/key_exchange_spec.rb} +9 -3
  99. data/spec/xml/protocol/cipher_suite_spec.rb +66 -0
  100. data/spec/xml/protocol_spec.rb +115 -0
  101. data/spec/xml/reneg/session_renegotiation_spec.rb +23 -0
  102. data/spec/xml/reneg_spec.rb +35 -0
  103. data/spec/xml/resum/session_resumption_with_session_ids_spec.rb +103 -0
  104. data/spec/xml/resum/session_resumption_with_tls_tickets_spec.rb +121 -0
  105. data/spec/xml/resum_rate_spec.rb +30 -0
  106. data/spec/xml/resum_spec.rb +47 -0
  107. data/spec/{target_spec.rb → xml/target_spec.rb} +73 -27
  108. data/spec/xml_spec.rb +13 -21
  109. metadata +138 -61
  110. data/lib/sslyze/cert_info.rb +0 -57
  111. data/lib/sslyze/certificate.rb +0 -139
  112. data/lib/sslyze/certificate/extensions.rb +0 -127
  113. data/lib/sslyze/certificate/extensions/authority_information_access.rb +0 -38
  114. data/lib/sslyze/certificate/extensions/extension.rb +0 -26
  115. data/lib/sslyze/certificate/extensions/x509v3_basic_constraints.rb +0 -60
  116. data/lib/sslyze/certificate/extensions/x509v3_certificate_policies.rb +0 -50
  117. data/lib/sslyze/certificate/extensions/x509v3_crl_distribution_points.rb +0 -32
  118. data/lib/sslyze/certificate/extensions/x509v3_extended_key_usage.rb +0 -32
  119. data/lib/sslyze/certificate/extensions/x509v3_key_usage.rb +0 -50
  120. data/lib/sslyze/certificate/extensions/x509v3_subject_alternative_name.rb +0 -71
  121. data/lib/sslyze/certificate/issuer.rb +0 -56
  122. data/lib/sslyze/certificate/public_key.rb +0 -9
  123. data/lib/sslyze/certificate/subject.rb +0 -117
  124. data/lib/sslyze/certificate/subject_public_key_info.rb +0 -53
  125. data/lib/sslyze/certificate/validity.rb +0 -9
  126. data/lib/sslyze/certificate_chain.rb +0 -89
  127. data/lib/sslyze/certificate_validation.rb +0 -70
  128. data/lib/sslyze/cipher_suite.rb +0 -237
  129. data/lib/sslyze/invalid_target.rb +0 -35
  130. data/lib/sslyze/key_exchange.rb +0 -106
  131. data/lib/sslyze/ocsp_response.rb +0 -87
  132. data/lib/sslyze/protocol.rb +0 -133
  133. data/lib/sslyze/target.rb +0 -312
  134. data/lib/sslyze/types.rb +0 -17
  135. data/spec/cert_info_spec.rb +0 -29
  136. data/spec/certificate/subject_name_spec.rb +0 -72
  137. data/spec/certificate_chain_spec.rb +0 -61
  138. data/spec/certificate_spec.rb +0 -330
  139. data/spec/certificate_validation_spec.rb +0 -39
  140. data/spec/cipher_suite_spec.rb +0 -50
  141. data/spec/invalid_target_spec.rb +0 -21
  142. data/spec/issuer_spec.rb +0 -33
  143. data/spec/ocsp_response_spec.rb +0 -59
  144. data/spec/protocol_spec.rb +0 -99
  145. data/spec/subject_public_key_info_spec.rb +0 -35
  146. data/spec/subject_spec.rb +0 -69
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/certificate_validation'
4
-
5
- describe SSLyze::CertificateValidation do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/certinfo/certificateValidation')) }
9
-
10
- describe "#hostname?" do
11
- it "should query hostnameValidation/@certificateMatchesServerHostname" do
12
- expect(subject.hostname?).to be true
13
- end
14
- end
15
-
16
- describe "#results" do
17
- it "should parse the pathValidation elements into a Hash" do
18
- expect(subject.results).to be == {
19
- 'Mozilla NSS' => 'ok',
20
- 'Microsoft' => 'ok',
21
- 'Apple' => 'ok',
22
- 'Java 6' => 'ok',
23
- 'Google' => 'ok'
24
- }
25
- end
26
- end
27
-
28
- describe "#path" do
29
- it "should check if each pathValidation/@validationResult is 'ok'" do
30
- expect(subject.path).to be == {
31
- 'Mozilla NSS' => true,
32
- 'Microsoft' => true,
33
- 'Apple' => true,
34
- 'Java 6' => true,
35
- 'Google' => true
36
- }
37
- end
38
- end
39
- end
@@ -1,50 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/cipher_suite'
4
-
5
- describe SSLyze::CipherSuite do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/tlsv1_2/acceptedCipherSuites/cipherSuite')) }
9
-
10
- describe "#name" do
11
- it "should parse the name attribute" do
12
- expect(subject.name).to be == 'AES128-GCM-SHA256'
13
- end
14
- end
15
-
16
- describe "#rfc_name" do
17
- it "should map the openssl name back to the RFC name" do
18
- expect(subject.rfc_name).to be == 'TLS_RSA_WITH_AES_128_GCM_SHA256'
19
- end
20
- end
21
-
22
- describe "#connection_status" do
23
- it "should parse the connectionStatus attribute" do
24
- expect(subject.connection_status).to be == 'HTTP 200 OK'
25
- end
26
- end
27
-
28
- describe "#anonymous?" do
29
- it "should query the anonymous attribute" do
30
- expect(subject.anonymous?).to be false
31
- end
32
- end
33
-
34
- describe "#key_exchange" do
35
- context "when the keyExchange child is present" do
36
- subject { described_class.new(xml.at('/document/results/target/tlsv1_2/acceptedCipherSuites/cipherSuite[keyExchange]')) }
37
-
38
- it "should return a KeyExchange object" do
39
- expect(subject.key_exchange).to be_kind_of(KeyExchange)
40
- end
41
- end
42
-
43
- context "when the keyExchange object is missing" do
44
- it "should return nil" do
45
- expect(subject.key_exchange).to be nil
46
- end
47
- end
48
- end
49
-
50
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/invalid_target'
4
-
5
- describe SSLyze::InvalidTarget do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/invalidTargets/invalidTarget')) }
9
-
10
- describe "#host" do
11
- it "must parse the host attribute" do
12
- expect(subject.host).to be == '10.10.10.1:443'
13
- end
14
- end
15
-
16
- describe "#error" do
17
- it "must parse the ip attribute" do
18
- expect(subject.error).to be == 'Could not connect (timeout)'
19
- end
20
- end
21
- end
@@ -1,33 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/certificate'
4
-
5
- describe SSLyze::Certificate::Issuer do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/certinfo/certificateChain/certificate/issuer')) }
9
-
10
- describe "#country_name" do
11
- it "should parse the countryName" do
12
- expect(subject.country_name).to be == 'US'
13
- end
14
- end
15
-
16
- describe "#common_name" do
17
- it "should parse the commonName element" do
18
- expect(subject.common_name).to be == 'DigiCert SHA2 Extended Validation Server CA'
19
- end
20
- end
21
-
22
- describe "#organizational_unit_name" do
23
- it "should parse the organizationalUnitName element" do
24
- expect(subject.organizational_unit_name).to be == 'www.digicert.com'
25
- end
26
- end
27
-
28
- describe "#organization_name" do
29
- it "should parse the organizationName element" do
30
- expect(subject.organization_name).to be == 'DigiCert Inc'
31
- end
32
- end
33
- end
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/ocsp_response'
4
-
5
- describe SSLyze::OCSPResponse do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/certinfo/ocspStapling/ocspResponse')) }
9
-
10
- describe "#trusted?" do
11
- it "should query @isTrustedByMozillaCAStore" do
12
- expect(subject.trusted?).to be true
13
- end
14
- end
15
-
16
- describe "#type" do
17
- it "should query responseType" do
18
- expect(subject.type).to be == 'Basic OCSP Response'
19
- end
20
- end
21
-
22
- describe "#responder_id" do
23
- it "should query responderID" do
24
- expect(subject.responder_id).to be == '0E7DB19F96176475CE3E5D98725AF4ACADA03FAF'
25
- end
26
- end
27
-
28
- describe "#version" do
29
- it "should query version" do
30
- expect(subject.version).to be 1
31
- end
32
- end
33
-
34
- describe "#status" do
35
- it "should query responseStatus" do
36
- expect(subject.status).to be == :successful
37
- end
38
- end
39
-
40
- describe "#successful?" do
41
- context "when status is :successful" do
42
- before { expect(subject).to receive(:status).and_return(:successful) }
43
-
44
- specify { expect(subject.successful?).to be true }
45
- end
46
-
47
- context "when status is not :successful" do
48
- before { expect(subject).to receive(:status).and_return(:failure) }
49
-
50
- specify { expect(subject.successful?).to be false }
51
- end
52
- end
53
-
54
- describe "#produced_at" do
55
- it "should query producedAt and return a Time object" do
56
- expect(subject.produced_at).to be == Time.parse('Sep 24 22:58:23 2015 GMT')
57
- end
58
- end
59
- end
@@ -1,99 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/protocol'
4
-
5
- describe SSLyze::Protocol do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/tlsv1_2')) }
9
-
10
- describe "#name" do
11
- it "should return the protocol name" do
12
- expect(subject.name).to be == :tlsv1_2
13
- end
14
- end
15
-
16
- describe "#title" do
17
- it "must parse the title attribute" do
18
- expect(subject.title).to be == 'TLSV1_2 Cipher Suites'
19
- end
20
- end
21
-
22
- describe "#each_error" do
23
- pending "need data"
24
- end
25
-
26
- describe "#each_rejected_cipher_suite" do
27
- it "should yield CipherSuite objects" do
28
- expect { |b|
29
- subject.each_rejected_cipher_suite(&b)
30
- }
31
- end
32
-
33
- context "when given no block" do
34
- specify do
35
- expect(subject.each_rejected_cipher_suite).to be_an(Enumerator)
36
- end
37
- end
38
- end
39
-
40
- describe "#rejected_cipher_suites" do
41
- specify do
42
- expect(subject.rejected_cipher_suites).to be_an(Array).and(
43
- all(be_a(CipherSuite))
44
- )
45
- end
46
- end
47
-
48
- describe "#each_accepted_cipher_suite" do
49
- it "should yield CipherSuite objects" do
50
- expect { |b|
51
- subject.each_accepted_cipher_suite(&b)
52
- }
53
- end
54
-
55
- context "when given no block" do
56
- specify do
57
- expect(subject.each_accepted_cipher_suite).to be_an(Enumerator)
58
- end
59
- end
60
- end
61
-
62
- describe "#accepted_cipher_suites" do
63
- specify do
64
- expect(subject.accepted_cipher_suites).to be_an(Array).and(
65
- all(be_a(CipherSuite))
66
- )
67
- end
68
- end
69
-
70
- describe "#each_preferred_cipher_suite" do
71
- it "should yield CipherSuite objects" do
72
- expect { |b|
73
- subject.each_preferred_cipher_suite(&b)
74
- }
75
- end
76
-
77
- context "when given no block" do
78
- specify do
79
- expect(subject.each_preferred_cipher_suite).to be_an(Enumerator)
80
- end
81
- end
82
- end
83
-
84
- describe "#preferred_cipher_suites" do
85
- specify do
86
- expect(subject.preferred_cipher_suites).to be_an(Array).and(
87
- all(be_a(CipherSuite))
88
- )
89
- end
90
- end
91
-
92
- describe "#supported?" do
93
- context "when there are preferred cipher suites" do
94
- it "should return true" do
95
- expect(subject.supported?).to be(true)
96
- end
97
- end
98
- end
99
- end
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/certificate'
4
-
5
- describe SSLyze::Certificate::SubjectPublicKeyInfo do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/certinfo/certificateChain/certificate/subjectPublicKeyInfo')) }
9
-
10
- describe "#public_key" do
11
- it "should return a PublicKey object" do
12
- expect(subject.public_key).to be_a(Certificate::PublicKey)
13
- end
14
-
15
- it "should parse the publicKey/modulus element" do
16
- expect(subject.public_key.modulus).to be == %{00:b1:d4:dc:3c:af:fd:f3:4e:ed:c1:67:ad:e6:cb:22:e8:b7:e2:ab:28:f2:f7:dc:62:70:08:d1:0c:af:d6:16:6a:21:b0:36:4b:17:0d:36:63:04:ae:bf:ea:20:51:95:65:66:f2:bf:b9:4d:a4:0c:29:eb:f5:15:b1:e8:35:b3:70:10:94:d5:1b:59:b4:26:0f:d6:83:57:59:9d:e1:7c:09:dd:e0:13:ca:4d:6f:43:9b:cd:cf:87:3a:15:a7:85:dd:66:83:ed:93:0c:fe:2b:6d:38:1c:79:88:90:cf:ad:58:18:2d:51:d1:c2:a3:f2:47:8c:6f:38:09:b9:b8:ef:4c:93:0b:cb:83:94:87:ea:e0:a3:b5:d9:7b:9b:6b:0f:43:f9:ca:ee:80:0d:28:a7:76:f1:25:f4:c1:35:3c:f6:74:ad:de:6a:33:82:7b:dc:fd:4b:76:a7:c2:ee:f2:6a:bf:a9:24:a6:5f:e7:2e:7c:0e:db:c3:74:73:fa:7e:c6:d8:cf:60:eb:36:56:21:b6:c1:8a:b8:24:82:4d:78:24:ba:e9:1d:a1:8a:a7:87:be:66:25:69:bf:be:3b:72:6e:4f:e0:e4:85:25:08:b1:91:89:b8:d6:74:65:76:9b:2c:4f:62:1f:a1:fa:3a:be:9c:24:bf:9f:ca:b0:c5:c0:67:8d}
17
- end
18
-
19
- it "should parse the publicKey/exponent element" do
20
- expect(subject.public_key.exponent).to be == 65537
21
- end
22
- end
23
-
24
- describe "#public_key_algorithm" do
25
- it "should parse the publicKeyAlgorithm element" do
26
- expect(subject.public_key_algorithm).to be == 'rsaEncryption'
27
- end
28
- end
29
-
30
- describe "#public_key_size" do
31
- it "should parse the publicKeySize element" do
32
- expect(subject.public_key_size).to be == 2048
33
- end
34
- end
35
- end
@@ -1,69 +0,0 @@
1
- require 'spec_helper'
2
- require 'xml_examples'
3
- require 'sslyze/certificate'
4
-
5
- describe SSLyze::Certificate::Subject do
6
- include_examples "XML specs"
7
-
8
- subject { described_class.new(xml.at('/document/results/target/certinfo/certificateChain/certificate/subject')) }
9
-
10
- describe "#organizational_unit_name" do
11
- it "should parse the organizationUnitName element" do
12
- expect(subject.organizational_unit_name).to be == 'Information Security'
13
- end
14
- end
15
-
16
- describe "#organization_name" do
17
- it "should parse the organizationName element" do
18
- expect(subject.organization_name).to be == 'GitHub, Inc.'
19
- end
20
- end
21
-
22
- describe "#business_category" do
23
- it "should parse the businessCategory element" do
24
- expect(subject.business_category).to be == 'Private Organization'
25
- end
26
- end
27
-
28
- describe "#serial_number" do
29
- it "should parse the serialNumber element" do
30
- expect(subject.serial_number).to be == 5157550
31
- end
32
- end
33
-
34
- describe "#common_name" do
35
- it "should parse the commonName element" do
36
- expect(subject.common_name.name).to be == 'github.com'
37
- end
38
- end
39
-
40
- describe "#state_or_province_name" do
41
- it "should parse the stateOrProvinceName element" do
42
- expect(subject.state_or_province_name).to be == 'California'
43
- end
44
- end
45
-
46
- describe "#country_name" do
47
- it "should parse the countryName element" do
48
- expect(subject.country_name).to be == 'US'
49
- end
50
- end
51
-
52
- describe "#street_address" do
53
- it "should parse the streetAddress element" do
54
- expect(subject.street_address).to be == '548 4th Street'
55
- end
56
- end
57
-
58
- describe "#locality_name" do
59
- it "should parse the localityName element" do
60
- expect(subject.locality_name).to be == 'San Francisco'
61
- end
62
- end
63
-
64
- describe "#postal_code" do
65
- it "should parse the postalCode element" do
66
- expect(subject.postal_code).to be == '94107'
67
- end
68
- end
69
- end