amazon_sdb 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,208 @@
1
+ require 'test_sdb_harness'
2
+
3
+ QUERY_RESPONSE = <<-EOF
4
+ <QueryResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07">
5
+ <QueryResult>
6
+ <ItemName>item1</ItemName>
7
+ <ItemName>item2</ItemName>
8
+ <ItemName>item3</ItemName>
9
+ </QueryResult>
10
+ <ResponseMetadata>
11
+ <RequestId>c74ef8c8-77ff-4d5e-b60b-097c77c1c266</RequestId>
12
+ <BoxUsage>0.0000219907</BoxUsage>
13
+ </ResponseMetadata>
14
+ </QueryResponse>
15
+ EOF
16
+
17
+ GET_ATTRIBUTES_RESPONSE = <<-EOF
18
+ <GetAttributesResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07">
19
+ <GetAttributesResult>
20
+ <Attribute><Name>Color</Name><Value>Blue</Value></Attribute>
21
+ <Attribute><Name>Size</Name><Value>Med</Value></Attribute>
22
+ <Attribute><Name>Price</Name><Value>14</Value></Attribute>
23
+ </GetAttributesResult>
24
+ <ResponseMetadata>
25
+ <RequestId>b1e8f1f7-42e9-494c-ad09-2674e557526d</RequestId>
26
+ <BoxUsage>0.0000219907/<BoxUsage>
27
+ </ResponseMetadata>
28
+ </GetAttributesResponse>
29
+ EOF
30
+
31
+ class TestAmazonDomain < Test::Unit::TestCase
32
+ def setup
33
+ @domain = Amazon::SDB::Domain.new 'API_KEY', 'SECRET_KEY', 'testdb'
34
+ @attr_hash = {"foo" => "bar", "baz" => "quux"}
35
+ end
36
+
37
+ def test_no_such_domain_error
38
+ # @domain.responses << error_response('NoSuchDomain', 'No such domain found')
39
+
40
+ # assert_raise(DomainNotFoundError) { @domain.get_attributes() }
41
+ end
42
+
43
+ def test_put_attributes
44
+ @domain.responses << generic_response('PutAttributes')
45
+
46
+ m = Amazon::SDB::Multimap.new(@attr_hash)
47
+ @domain.put_attributes 'item_key', m
48
+
49
+ assert_equal 1, @domain.uris.length
50
+ assert_in_url_query({'Action' => 'PutAttributes', 'DomainName' => @domain.name, 'ItemName' => 'item_key'}, @domain.uris.first)
51
+ assert_attr_pairs_in_query @attr_hash, @domain.uris.first
52
+ end
53
+
54
+ def test_put_attributes_hash
55
+ @domain.responses << generic_response('PutAttributes')
56
+
57
+ @domain.put_attributes 'item_key', @attr_hash
58
+
59
+ assert_equal 1, @domain.uris.length
60
+ assert_in_url_query({'Action' => 'PutAttributes', 'DomainName' => @domain.name, 'ItemName' => 'item_key'}, @domain.uris.first)
61
+ assert_attr_pairs_in_query @attr_hash, @domain.uris.first
62
+ end
63
+
64
+ def test_put_attributes_replace_by_name
65
+ @domain.responses << generic_response('PutAttributes')
66
+
67
+ @domain.put_attributes 'item_key', @attr_hash, :replace => :baz
68
+ end
69
+
70
+ def test_put_attributes_replace_all
71
+ @domain.responses << generic_response('PutAttributes')
72
+
73
+ m = Amazon::SDB::Multimap.new @attr_hash
74
+
75
+ @domain.put_attributes 'item_key', m, :replace => :all
76
+
77
+ assert_in_url_query({'Attribute.0.Replace' => 'true', 'Attribute.1.Replace' => 'true'}, @domain.uris.first)
78
+ end
79
+
80
+ def test_get_attributes
81
+ @domain.responses << GET_ATTRIBUTES_RESPONSE
82
+
83
+ item = @domain.get_attributes('key')
84
+
85
+ assert_equal 1, @domain.uris.size
86
+
87
+ assert_in_url_query({'Action' => 'GetAttributes', 'DomainName' => @domain.name, 'ItemName' => 'key'}, @domain.uris.first)
88
+ assert_instance_of(Amazon::SDB::Item, item)
89
+ assert_equal 'Blue', item['Color']
90
+ end
91
+
92
+ def test_get_attributes_not_found
93
+ @domain.responses << <<-EOF
94
+ <GetAttributesResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07">
95
+ <GetAttributesResult>
96
+ </GetAttributesResult>
97
+ <ResponseMetadata>
98
+ <RequestId>b1e8f1f7-42e9-494c-ad09-2674e557526d</RequestId>
99
+ <BoxUsage>0.0000219907/<BoxUsage>
100
+ </ResponseMetadata>
101
+ </GetAttributesResponse>
102
+ EOF
103
+
104
+ assert_raise(Amazon::SDB::RecordNotFoundError) { @domain.get_attributes('key') }
105
+ assert_equal 1, @domain.uris.size
106
+ end
107
+
108
+ def test_get_attributes_specific
109
+ @domain.responses << GET_ATTRIBUTES_RESPONSE
110
+
111
+ item = @domain.get_attributes 'key', 'attr1', :attr2
112
+
113
+ assert_in_url_query({'AttributeName' => ['attr1','attr2']}, @domain.uris.first)
114
+ end
115
+
116
+ def test_delete_attributes_all
117
+ @domain.responses << generic_response('DeleteAttributes')
118
+
119
+ @domain.delete_attributes 'key'
120
+
121
+ assert_equal 1, @domain.uris.length
122
+ assert_in_url_query({'Action' => 'DeleteAttributes', 'DomainName' => @domain.name, 'ItemName' => 'key'}, @domain.uris.first)
123
+ end
124
+
125
+ def test_delete_attributes_name
126
+ @domain.responses << generic_response('DeleteAttributes')
127
+
128
+ @domain.delete_attributes 'key', 'foo'
129
+
130
+ assert_equal 1, @domain.uris.length
131
+ assert_in_url_query({'Action' => 'DeleteAttributes', 'DomainName' => @domain.name, 'ItemName' => 'key'}, @domain.uris.first)
132
+ assert_in_url_query({'Attribute.0.Name' => 'foo'}, @domain.uris.first)
133
+ end
134
+
135
+ def test_delete_attributes_name_value
136
+ @domain.responses << generic_response('DeleteAttributes')
137
+
138
+ @domain.delete_attributes 'key', {'foo' => 'bar'}
139
+
140
+ assert_equal 1, @domain.uris.length
141
+ assert_in_url_query({'Action' => 'DeleteAttributes', 'DomainName' => @domain.name, 'ItemName' => 'key'}, @domain.uris.first)
142
+ assert_in_url_query({'Attribute.0.Name' => 'foo', 'Attribute.0.Value' => 'bar'}, @domain.uris.first)
143
+ end
144
+
145
+ def test_query_all
146
+ @domain.responses << QUERY_RESPONSE
147
+
148
+ results = @domain.query
149
+
150
+ assert_equal 1, @domain.uris.length
151
+ assert_in_url_query({'Action' => 'Query', 'DomainName' => @domain.name}, @domain.uris.first)
152
+ assert_not_in_url_query('QueryExpression', @domain.uris.first)
153
+
154
+ assert_instance_of(Amazon::SDB::ResultSet, results)
155
+
156
+ assert_equal 3, results.items.size
157
+ assert_equal ['item1', 'item2', 'item3'], results.keys
158
+ end
159
+
160
+ def test_query_max_results
161
+ @domain.responses << QUERY_RESPONSE
162
+
163
+ @domain.query :max_results => 3
164
+ assert_equal 1, @domain.uris.length
165
+ assert_in_url_query({'MaxNumberOfItems' => '3'}, @domain.uris.first)
166
+ end
167
+
168
+ def test_query_next_token
169
+ @domain.responses << QUERY_RESPONSE
170
+
171
+ @domain.query :next_token => 'FOOBAR'
172
+ assert_equal 1, @domain.uris.length
173
+ assert_in_url_query({'NextToken' => 'FOOBAR'}, @domain.uris.first)
174
+ end
175
+
176
+ def test_query_expr
177
+ @domain.responses << QUERY_RESPONSE
178
+
179
+ @domain.query :expr => "['last_name' = 'Harris']"
180
+
181
+ assert_equal 1, @domain.uris.length
182
+ assert_in_url_query({'QueryExpression' => "['last_name' = 'Harris']"}, @domain.uris.first)
183
+ end
184
+
185
+ def test_list_items_load
186
+ @domain.responses << <<-EOF
187
+ <QueryResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07">
188
+ <QueryResult>
189
+ <ItemName>item1</ItemName>
190
+ </QueryResult>
191
+ <ResponseMetadata>
192
+ <RequestId>c74ef8c8-77ff-4d5e-b60b-097c77c1c266</RequestId>
193
+ <BoxUsage>0.0000219907</BoxUsage>
194
+ </ResponseMetadata>
195
+ </QueryResponse>
196
+ EOF
197
+
198
+ @domain.responses << GET_ATTRIBUTES_RESPONSE
199
+
200
+ results = @domain.query :load_attrs => true
201
+
202
+ assert_equal 2, @domain.uris.length
203
+ assert_in_url_query({'Action' => 'GetAttributes', 'DomainName' => @domain.name, 'ItemName' => 'item1'}, @domain.uris.last)
204
+
205
+ assert_equal 1, results.items.size
206
+ assert_equal 'Blue', results.items.first["Color"]
207
+ end
208
+ end
@@ -0,0 +1,177 @@
1
+ require "test_sdb_harness"
2
+
3
+ class TestMultimap < Test::Unit::TestCase
4
+ include Amazon::SDB
5
+
6
+ def setup
7
+ @m = Multimap.new
8
+ end
9
+
10
+ def test_init_nil
11
+ assert_equal 0, @m.size
12
+ @m.each_pair do |k, v|
13
+ flunk 'Shouldn''t be anything in the multimap'
14
+ end
15
+ end
16
+
17
+ def test_init_array
18
+ m = Multimap.new [['a', 1], ['b', 2], ['a', 3]]
19
+ assert_equal 3, m.size
20
+ assert_equal [1, 3], m.get('a')
21
+ assert_equal 2, m.get('b')
22
+ end
23
+
24
+ def test_init_array_bad
25
+ assert_raise(ArgumentError) { m = Multimap.new [:a, :b, :c] }
26
+ end
27
+
28
+ def test_init_hash
29
+ m = Multimap.new({:a => 'a', :b => 'b'})
30
+ assert_equal 2, m.size
31
+ assert_equal 'a', m.get(:a)
32
+ assert_equal 'b', m.get(:b)
33
+ end
34
+
35
+ def test_init_null_value
36
+ m = Multimap.new({:a => nil, :b => 'b'})
37
+ assert_nil(m.get(:a))
38
+ assert_equal 'b', m.get(:b)
39
+ end
40
+
41
+ def test_init_null_put
42
+ m = Multimap.new({:a => nil})
43
+ assert_equal 1, m.size
44
+
45
+ m.put(:a, 1)
46
+ assert_equal 1, m.size
47
+ end
48
+
49
+ def test_indifferent_access
50
+ m = Multimap.new({:a => 1})
51
+ assert_equal 1, m["a"]
52
+ end
53
+
54
+ def test_indifferent_both
55
+ m = Multimap.new({:a => 1, "a" => 2})
56
+ assert_equal 2, m.size
57
+ assert_equal [2, 1], m[:a]
58
+ end
59
+
60
+ def test_put
61
+ @m["a"] = 23
62
+ assert_equal(23, @m.get("a"))
63
+ end
64
+
65
+ def test_put_append
66
+ @m.put("a", 2)
67
+ @m.put("a", 4)
68
+ assert_equal 2, @m.size
69
+ end
70
+
71
+ def test_put_replace
72
+ @m.put("a", 2)
73
+ @m.put("a", 4, :replace => true)
74
+ assert_equal 1, @m.size
75
+ assert_equal 4, @m["a"]
76
+ end
77
+
78
+ def test_bracket_read
79
+ m = Multimap.new({:a => 5})
80
+ assert_equal 5, m[:a]
81
+ assert_nil m["b"]
82
+ end
83
+
84
+ def test_bracket_write
85
+ @m[:a] = 1
86
+ @m[:a] = 3
87
+ assert_equal(1, @m.size)
88
+ assert_equal(3, @m[:a])
89
+ end
90
+
91
+ def test_delete_key
92
+ # m = Multimap.new([[:a, 1][:a, 2][:a, 3]])
93
+ # assert_equal 3, m.size
94
+ # m.delete
95
+ end
96
+
97
+ def test_fixnum_padding
98
+ @m['Num'] = 12
99
+ Amazon::SDB::Base.number_padding = 6
100
+
101
+ assert_equal '000012', @m.to_sdb['Attribute.0.Value']
102
+ end
103
+
104
+ def test_numeric
105
+ @m['Num'] = Amazon::SDB::Multimap.numeric(12.34, 10, 4)
106
+ assert_equal '00012.3400', @m['Num']
107
+ end
108
+
109
+ def test_to_sdb_replace_all
110
+ @m[:a] = "foo"
111
+ @m[:b] = "bar"
112
+
113
+ out = @m.to_sdb({:replace => :all})
114
+ assert out.key?('Attribute.0.Replace')
115
+ assert out.key?('Attribute.1.Replace')
116
+ end
117
+
118
+ def test_to_sdb_replace_by_name
119
+ @m[:a] = "foo"
120
+
121
+ out = @m.to_sdb({:replace => 'a'})
122
+ assert out.key?('Attribute.0.Replace')
123
+ end
124
+
125
+ def test_delete_pair
126
+
127
+ end
128
+
129
+ def test_char_escape
130
+ @m["a\'b"] = "c\\d"
131
+
132
+ out = @m.to_sdb
133
+
134
+ assert_equal 'a\\\'b', out["Attribute.0.Name"]
135
+ assert_equal 'c\\\\d', out["Attribute.0.Value"]
136
+ end
137
+
138
+ def test_method_missing_get
139
+ @m["foo"] = "bar"
140
+
141
+ assert_equal "bar", @m.foo
142
+ assert_raise(NoMethodError) { @m.baz }
143
+ end
144
+
145
+ def test_method_missing_get_before_cast
146
+ @m.from_sdb([["foo","0000000000000000023"]])
147
+
148
+ assert_equal 23, @m.foo
149
+ assert_equal "0000000000000000023", @m.foo_before_cast
150
+ end
151
+
152
+ def test_coerce_int
153
+ m = Multimap.new
154
+ m.from_sdb([["a", "00000000023"],["b", "1992"]])
155
+
156
+ assert_equal 23, m["a"]
157
+ assert_equal "00000000023", m.get("a", :before_cast => true)
158
+ assert_equal "1992", m["b"]
159
+ end
160
+
161
+ def test_coerce_float
162
+ m = Multimap.new
163
+ m.from_sdb([["a", "0000000000034.3400000000"]])
164
+
165
+ assert_in_delta(34.34, m["a"], 2 ** -20)
166
+ assert_equal "0000000000034.3400000000", m.get("a", :before_cast => true)
167
+ end
168
+
169
+ def test_coerce_datetime
170
+ now = Time.now
171
+
172
+ m = Multimap.new
173
+ m.from_sdb([["a", now.iso8601]])
174
+ assert_equal now.to_s, m["a"].to_s
175
+ assert_instance_of(Time, m["a"])
176
+ end
177
+ end
@@ -0,0 +1,124 @@
1
+ require "test/unit"
2
+ require 'cgi'
3
+ require "amazon_sdb"
4
+
5
+ # little mock override of open for base (technique from Eric Hodel)
6
+ class Amazon::SDB::Base
7
+ attr_accessor :uris, :responses
8
+
9
+ def initialize(aws_access_key, aws_secret_key)
10
+ @access_key = aws_access_key
11
+ @secret_key = aws_secret_key
12
+ @responses = []
13
+ @uris = []
14
+ end
15
+
16
+ def open(uri)
17
+ @uris << uri
18
+
19
+ if @responses.size == 0
20
+ fail "Unexpected HTTP request #{uri}"
21
+ end
22
+
23
+ yield StringIO.new(@responses.shift)
24
+ end
25
+ end
26
+
27
+ class Test::Unit::TestCase
28
+ def error_response(code, msg)
29
+ "<Response>
30
+ <Errors>
31
+ <Error>
32
+ <Code>#{code}</Code>
33
+ <Message>#{msg}</Message>
34
+ <BoxUsage>0.0000219907</BoxUsage>
35
+ </Error>
36
+ </Errors>
37
+ <RequestID>
38
+ 1e6265c5-f1f2-4a4b-afef-1448cac0f065
39
+ </RequestID>
40
+ </Response>"
41
+ end
42
+
43
+ def generic_response(method)
44
+ "<#{method}Response xmlns=\"http://sdb.amazonaws.com/doc/2007-11-07\">
45
+ <ResponseMetadata>
46
+ <RequestId>490206ce-8292-456c-a00f-61b335eb202b</RequestId>
47
+ <BoxUsage>0.0000219907</BoxUsage>
48
+ </ResponseMetadata>
49
+ </#{method}Response>"
50
+ end
51
+
52
+ def assert_in_url_query(hash, uri)
53
+ query_str = uri.gsub(/^.+\?/, '')
54
+ query_hash = CGI.parse query_str
55
+
56
+ hash.each_pair do |key, value|
57
+ case value
58
+ when Array
59
+ assert_equal value, query_hash[key], "Query #{query_str} includes #{key}=#{query_hash[key]}, expected #{value.inspect}"
60
+ else
61
+ assert_equal [value], query_hash[key], "Query #{query_str} includes #{key}=#{query_hash[key]}, expected #{value}"
62
+ end
63
+ end
64
+ end
65
+
66
+ def assert_url_path(path, uri)
67
+ test_path = uri.dup
68
+ test_path.gsub!(/^http:\/\/[^\/]+\//, '/')
69
+ test_path.gsub!(/\?.+$/, '')
70
+
71
+ assert_equal path, test_path
72
+ end
73
+
74
+
75
+ def assert_attr_pairs_in_query(attr_hash, uri)
76
+ attr_hash.each_pair do |k, v|
77
+ assert_attr_pair_in_query k, v, uri
78
+ end
79
+ end
80
+
81
+ def assert_attr_pair_in_query(key, value, uri)
82
+ query_str = uri.gsub(/^.+\?/, '')
83
+ query_hash = CGI.parse query_str
84
+
85
+ key_found = false
86
+ value_found = false
87
+
88
+ query_hash.each_pair do |cgi_key, cgi_value|
89
+ if cgi_key =~ /Attribute\.\d+\.Name/
90
+ key_found ||= cgi_value.any? {|k| k == key}
91
+ elsif cgi_key =~ /Attribute\.\d+\.Value/
92
+ value_found ||= cgi_value.any? {|k| k == value}
93
+ end
94
+
95
+ return if key_found and value_found
96
+ end
97
+
98
+ if key_found and not value_found
99
+ fail "Key '#{key}' found but not with value '#{value}' found in #{query_str}"
100
+ elsif value_found and not key_found
101
+ fail "Key '#{key}' not found but value '#{value}' found in #{query_str}"
102
+ else
103
+ fail "Neither key '#{key}' or value '#{value}' found in #{query_str}"
104
+ end
105
+ end
106
+
107
+ def assert_not_in_url_query(args, uri)
108
+ arg_array = case args
109
+ when String
110
+ args.to_a
111
+ when Array
112
+ args
113
+ else
114
+ raise ArgumentError, "Should be a string or array"
115
+ end
116
+
117
+ query_str = uri.gsub /^.+\?/, ''
118
+ query_hash = CGI.parse query_str
119
+
120
+ arg_array.each do |key|
121
+ assert_equal [], query_hash[key], "The key #{key} should not be in the URL argument string"
122
+ end
123
+ end
124
+ end