amazon_sdb 0.5.5

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.
@@ -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