File: header_parse_test.rb

package info (click to toggle)
ruby-simple-oauth 0.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 372 kB
  • sloc: ruby: 1,722; makefile: 4; sh: 4
file content (232 lines) | stat: -rw-r--r-- 8,455 bytes parent folder | download
1
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
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
require "test_helper"

module SimpleOAuth
  # Tests for parsing OAuth Authorization headers per RFC 5849 Section 3.5.1.
  class HeaderParseBasicTest < Minitest::Test
    include TestHelpers

    cover "SimpleOAuth::Header*"

    def test_parse_returns_a_hash
      header = SimpleOAuth::Header.new(:get, "https://photos.example.net/photos", {})

      assert_kind_of Hash, SimpleOAuth::Header.parse(header)
    end

    def test_parse_includes_options_used_to_build_header
      header = SimpleOAuth::Header.new(:get, "https://photos.example.net/photos", {})
      parsed_options = SimpleOAuth::Header.parse(header)

      assert_equal header.options, parsed_options.except(:signature)
    end

    def test_parse_header_options_does_not_include_signature
      header = SimpleOAuth::Header.new(:get, "https://photos.example.net/photos", {})

      refute header.options.key?(:signature)
    end

    def test_parse_includes_signature_in_parsed_options
      header = SimpleOAuth::Header.new(:get, "https://photos.example.net/photos", {})

      assert SimpleOAuth::Header.parse(header).key?(:signature)
    end

    def test_parse_has_non_nil_signature
      header = SimpleOAuth::Header.new(:get, "https://photos.example.net/photos", {})

      refute_nil SimpleOAuth::Header.parse(header)[:signature]
    end

    def test_parse_handles_empty_value
      parsed = SimpleOAuth::Header.parse('OAuth oauth_callback=""')

      assert_equal "", parsed[:callback]
    end

    def test_parse_strips_oauth_prefix_from_keys
      parsed = SimpleOAuth::Header.parse('OAuth oauth_consumer_key="dpf43f3p2l4k3l03"')

      assert parsed.key?(:consumer_key)
      refute parsed.key?(:oauth_consumer_key)
    end

    def test_parse_silently_ignores_params_without_oauth_prefix
      parsed = SimpleOAuth::Header.parse('OAuth consumer_key="dpf43f3p2l4k3l03"')

      assert_empty parsed
    end
  end

  class HeaderParseWhitespaceTest < Minitest::Test
    include TestHelpers

    cover "SimpleOAuth::Header*"

    def test_parse_handles_spaces_after_commas
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="wIjqoS", ' \
               'oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D", oauth_signature_method="HMAC-SHA1", ' \
               'oauth_timestamp="137131200", oauth_token="hh5s93j4hdidpola", oauth_version="1.0"'

      assert_equal 7, SimpleOAuth::Header.parse(header).keys.size
    end

    def test_parse_handles_multiple_spaces_after_commas
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="wIjqoS",  ' \
               'oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D",  oauth_signature_method="HMAC-SHA1", ' \
               'oauth_timestamp="137131200", oauth_token="hh5s93j4hdidpola", oauth_version="1.0"'

      assert_equal 7, SimpleOAuth::Header.parse(header).keys.size
    end

    def test_parse_handles_no_spaces_after_commas
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03",oauth_nonce="wIjqoS",' \
               'oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D",oauth_signature_method="HMAC-SHA1",' \
               'oauth_timestamp="137131200",oauth_token="hh5s93j4hdidpola",oauth_version="1.0"'

      assert_equal 7, SimpleOAuth::Header.parse(header).keys.size
    end

    def test_parse_handles_trailing_whitespace
      parsed = SimpleOAuth::Header.parse('OAuth oauth_consumer_key="dpf43f3p2l4k3l03",   ')

      assert_equal RFC5849::CONSUMER_KEY, parsed[:consumer_key]
    end

    def test_parse_handles_multiple_spaces_after_oauth_scheme
      parsed = SimpleOAuth::Header.parse('OAuth   oauth_consumer_key="dpf43f3p2l4k3l03"')

      assert_equal RFC5849::CONSUMER_KEY, parsed[:consumer_key]
    end
  end

  class HeaderParseFilteringTest < Minitest::Test
    include TestHelpers

    cover "SimpleOAuth::Header*"

    def test_parse_ignores_unrecognized_oauth_keys_count
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_invalid_key="bad", oauth_signature="sig"'
      parsed = SimpleOAuth::Header.parse(header)

      assert_equal 2, parsed.keys.size
    end

    def test_parse_ignores_unrecognized_oauth_keys_values
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_invalid_key="bad", oauth_signature="sig"'
      parsed = SimpleOAuth::Header.parse(header)

      assert_equal RFC5849::CONSUMER_KEY, parsed[:consumer_key]
      assert_equal "sig", parsed[:signature]
    end

    def test_parse_ignores_unrecognized_oauth_keys_exclusion
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_invalid_key="bad", oauth_signature="sig"'
      parsed = SimpleOAuth::Header.parse(header)

      refute parsed.key?(:invalid_key)
    end

    def test_parse_ignores_non_oauth_prefixed_keys
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", custom_key="ignored", oauth_signature="sig"'
      parsed = SimpleOAuth::Header.parse(header)

      assert_equal 2, parsed.keys.size
      refute parsed.key?(:custom_key)
    end

    def test_parse_handles_unescaped_comma_in_value
      parsed = SimpleOAuth::Header.parse('OAuth oauth_consumer_key="key,with,commas", oauth_signature="sig"')

      assert_equal "key,with,commas", parsed[:consumer_key]
      assert_equal "sig", parsed[:signature]
    end
  end

  class HeaderParseErrorTest < Minitest::Test
    include TestHelpers

    cover "SimpleOAuth::Header*"

    def test_parse_raises_on_malformed_pair_position
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", malformed_without_quotes, oauth_token="token"'

      error = assert_raises(SimpleOAuth::ParseError) { SimpleOAuth::Header.parse(header) }

      assert_match(/Could not parse parameter at position 45/, error.message)
    end

    def test_parse_raises_on_malformed_pair_content
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", malformed_without_quotes, oauth_token="token"'

      error = assert_raises(SimpleOAuth::ParseError) { SimpleOAuth::Header.parse(header) }

      assert_match(/malformed_without_quotes/, error.message)
    end

    def test_parse_raises_on_malformed_pair_inspect_format
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", malformed_without_quotes, oauth_token="token"'

      error = assert_raises(SimpleOAuth::ParseError) { SimpleOAuth::Header.parse(header) }

      # Verify .inspect is used (shows escaped quotes)
      assert_match(/\\"token\\"/, error.message)
    end

    def test_parse_raises_on_missing_opening_quote_position
      error = assert_raises(SimpleOAuth::ParseError) do
        SimpleOAuth::Header.parse("OAuth oauth_consumer_key=dpf43f3p2l4k3l03")
      end

      assert_match(/Could not parse parameter at position 6/, error.message)
    end

    def test_parse_raises_on_missing_opening_quote_inspect_format
      error = assert_raises(SimpleOAuth::ParseError) do
        SimpleOAuth::Header.parse("OAuth oauth_consumer_key=dpf43f3p2l4k3l03")
      end

      assert_match(/"oauth_consumer_key=dpf43f3p2l4k3l03"/, error.message)
    end

    def test_parse_raises_on_missing_comma_position
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03" oauth_signature="sig"'

      error = assert_raises(SimpleOAuth::ParseError) { SimpleOAuth::Header.parse(header) }

      assert_match(/Expected comma after 'oauth_consumer_key' parameter at position 44/, error.message)
    end

    def test_parse_raises_on_missing_comma_content
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03" oauth_signature="sig"'

      error = assert_raises(SimpleOAuth::ParseError) { SimpleOAuth::Header.parse(header) }

      assert_match(/oauth_signature/, error.message)
    end

    def test_parse_raises_on_missing_comma_inspect_format
      header = 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03" oauth_signature="sig"'

      error = assert_raises(SimpleOAuth::ParseError) { SimpleOAuth::Header.parse(header) }

      assert_match(/\\"sig\\"/, error.message)
    end

    def test_parse_raises_on_missing_oauth_prefix
      error = assert_raises(SimpleOAuth::ParseError) do
        SimpleOAuth::Header.parse('oauth_consumer_key="dpf43f3p2l4k3l03"')
      end

      assert_match(/Authorization header must start with 'OAuth '/, error.message)
    end

    def test_parse_raises_on_invalid_scheme
      error = assert_raises(SimpleOAuth::ParseError) do
        SimpleOAuth::Header.parse("Bearer token123")
      end

      assert_match(/Authorization header must start with 'OAuth '/, error.message)
    end
  end
end