play_asia 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.sublime-*
2
+ .idea
3
+ *.gem
4
+ *.rbc
5
+ .bundle
6
+ .config
7
+ coverage
8
+ InstalledFiles
9
+ Gemfile.lock
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+
18
+ # YARD artifacts
19
+ .yardoc
20
+ _yardoc
21
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in play_asia.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 On the Game
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # PlayAsia
2
+
3
+ A thin wrapper around the [Play Asia](http://www.play-asia.com) API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'play_asia'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install play_asia
18
+
19
+ ## Usage
20
+
21
+ api = PlayAsia::Api.new
22
+ key: # your API key,
23
+ user: # your API user,
24
+
25
+ api.listing mask: [:price, :name], type: [:game]
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'test'
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'nokogiri'
2
+
3
+ class PlayAsia::Api
4
+ attr_accessor :endpoint
5
+ attr_accessor :headers
6
+ attr_accessor :http_client
7
+
8
+ def initialize(opts = {})
9
+ @opts = opts
10
+ @endpoint = 'http://www.play-asia.com/__api__.php'
11
+ @http_client = PlayAsia::HttpClient.new
12
+ end
13
+
14
+ def query(opts = {})
15
+ opts = @opts.merge opts
16
+ url = build_url @endpoint, opts
17
+ headers = @headers || {}
18
+
19
+ PlayAsia::Response.new @http_client.request(url, headers).read
20
+ end
21
+
22
+ private
23
+ def build_url(endpoint, opts)
24
+ ensure_required_parameters opts
25
+
26
+ params = opts.map { |k,v| "#{k}=#{v}" }.join '&'
27
+ "#{endpoint}?#{params}"
28
+ end
29
+
30
+ def ensure_required_parameters opts
31
+ raise ArgumentError, 'Missing API key (expected :key)' unless opts[:key]
32
+ raise ArgumentError, 'Missing User ID (expected :user)' unless opts[:user]
33
+ raise ArgumentError, 'Missing Query type (expected :query)' unless opts[:query]
34
+ end
35
+ end
@@ -0,0 +1,347 @@
1
+ class PlayAsia::Api
2
+ def listing(opts = {})
3
+ opts = process_friendly_keys opts.merge({ query: :listing })
4
+ response = query opts
5
+
6
+ raise "Query error: '#{response.error_message}'" if response.error?
7
+
8
+ response
9
+ end
10
+
11
+ private
12
+ MASK = {
13
+ price: 'p',
14
+ barcodes: 'j',
15
+ manufacturer_codes: 'm',
16
+ sale_info: 's',
17
+ release_date: 'r',
18
+ name: 'n',
19
+ image: 'i',
20
+ url: 'l',
21
+ affiliate_url: 'a',
22
+ genre: 'g',
23
+ version: 'v',
24
+ encoding: 'e',
25
+ compatible: 'c'
26
+ }
27
+
28
+ TYPES = {
29
+ accessory: 2,
30
+ cd: 3,
31
+ groceries: 7,
32
+ apparel: 8,
33
+ electronics: 9,
34
+ movie: 4,
35
+ book: 6,
36
+ game: 1,
37
+ toy: 5
38
+ }
39
+
40
+ GENRES = {
41
+ strategy_video_game: 10,
42
+ racing_video_game: 11,
43
+ simulation_video_game: 12,
44
+ tv_series_dvd_vcd: 122,
45
+ enka_dvd_vcd: 123,
46
+ puzzle_video_game: 13,
47
+ music_video_game: 14,
48
+ language_learning_software_video_games: 147,
49
+ slg_video_game: 15,
50
+ documentary_dvd_vcd: 159,
51
+ classics_video_game: 16,
52
+ fantasy_mystery_dvd_vcd: 160,
53
+ musical_dvd_vcd: 161,
54
+ rock_pop_dvd_vcd: 162,
55
+ rap_hip_hop_dvd_vcd: 163,
56
+ western_dvd_vcd: 164,
57
+ oldies_dvd_vcd: 165,
58
+ soul_r_and_b_dvd_vcd: 166,
59
+ family_dvd_vcd: 167,
60
+ opera_dvd_vcd: 168,
61
+ concert_dvd_vcd: 169,
62
+ misc_video_game: 17,
63
+ heavy_metal_dvd_vcd: 170,
64
+ jazz_dvd_vcd: 171,
65
+ classical_dvd_vcd: 172,
66
+ folk_dvd_vcd: 173,
67
+ ballet_dvd_vcd: 178,
68
+ sports_video_dvd_vcd: 179,
69
+ action_video_game: 18,
70
+ gambling_dvd_vcd: 185,
71
+ adventure_video_game: 19,
72
+ augmented_reality_video_game: 192,
73
+ fighting_video_game: 2,
74
+ board_video_game: 20,
75
+ party_video_game: 21,
76
+ comedy_dvd_vcd: 22,
77
+ action_dvd_vcd: 23,
78
+ adult_dvd_vcd: 24,
79
+ crime_dvd_vcd: 25,
80
+ drama_dvd_vcd: 26,
81
+ romance_dvd_vcd: 27,
82
+ martial_arts_dvd_vcd: 28,
83
+ horror_dvd_vcd: 29,
84
+ beat_em_up_video_game: 3,
85
+ thriller_dvd_vcd: 30,
86
+ sci_fi_dvd_vcd: 31,
87
+ gambling_video_game: 32,
88
+ pinball_video_game: 33,
89
+ animation_dvd_vcd: 34,
90
+ ghost_dvd_vcd: 35,
91
+ soundtrack_music_cd: 36,
92
+ j_pop_music_cd: 37,
93
+ cantopop_music_cd: 38,
94
+ j_pop_dvd_vcd: 39,
95
+ shooting_video_game: 4,
96
+ video_game_soundtrack_music_cd: 40,
97
+ video_game_movie_dvd_vcd: 41,
98
+ japanese_movie_dvd_vcd: 42,
99
+ non_japanese_movie_dvd_vcd: 43,
100
+ education_dvd_vcd: 44,
101
+ misc_movie_dvd_vcd: 45,
102
+ karaoke_dvd_vcd: 46,
103
+ k_pop_music_cd: 47,
104
+ electronic_music_cd: 48,
105
+ dance_music_cd: 49,
106
+ gun_shooting_video_game: 5,
107
+ pop_music_cd: 50,
108
+ idol_movie_dvd_vcd: 54,
109
+ enka_music_cd: 55,
110
+ hentai_dvd_vcd: 57,
111
+ platform_video_game: 6,
112
+ rpg_video_game: 7,
113
+ action_adventure_video_game: 8,
114
+ sports_video_game: 9
115
+ }
116
+
117
+ COMPATIBILITIES = {
118
+ am3_advance_media_player: 23,
119
+ atari_jaguar: 20,
120
+ blackberry_bold_9900_9930: 201,
121
+ blackberry_torch_2_9810: 203,
122
+ blackberry_torch_9850_9860: 205,
123
+ dreamcast: 9,
124
+ dsi_ll_xl_japanese_only: 116,
125
+ famicom_disk_system: 87,
126
+ famicom_nes: 18,
127
+ gamecube: 2,
128
+ game_boy: 59,
129
+ game_boy_advance: 8,
130
+ game_boy_advance_sp: 39,
131
+ game_boy_color: 14,
132
+ game_boy_micro: 60,
133
+ game_boy_pocket: 84,
134
+ game_gear: 30,
135
+ gp2x: 61,
136
+ gp2x_caanoo: 112,
137
+ gp2x_f_200: 97,
138
+ gp2x_wiz: 99,
139
+ gp32: 10,
140
+ htchd7: 137,
141
+ htc_7_trophy: 139,
142
+ htc_cha_cha_a810e: 147,
143
+ htc_desire_hd_a9191: 120,
144
+ htc_evo4g: 157,
145
+ htc_evo_3d_x515m: 149,
146
+ htc_g2: 141,
147
+ htc_increadible_s_s710e: 143,
148
+ htc_one_s_z520e: 135,
149
+ htc_radar_c110e: 155,
150
+ htc_raider_4g_x710e: 151,
151
+ htc_rhyme_s510b: 153,
152
+ htc_sensation_xe_z715e: 133,
153
+ htc_sensation_z710e: 145,
154
+ ipad: 111,
155
+ ipad_2: 119,
156
+ ipad_3: 127,
157
+ iphone_3g: 98,
158
+ iphone_3gs: 114,
159
+ iphone_4: 115,
160
+ iphone_4s: 124,
161
+ iphone_5: 125,
162
+ ipod_4g_20gb: 67,
163
+ ipod_4g_40gb: 68,
164
+ ipod_5g_30gb: 63,
165
+ ipod_5g_60gb: 64,
166
+ ipod_classic_160gb: 95,
167
+ ipod_classic_80gb: 94,
168
+ ipod_mini_4gb_6gb: 66,
169
+ ipod_nano: 62,
170
+ ipod_nano_2nd_gen: 86,
171
+ ipod_nano_3rd_gen: 96,
172
+ ipod_nano_5th_gen: 109,
173
+ ipod_nano_6g: 131,
174
+ ipod_photo_30gb: 69,
175
+ ipod_photo_60gb: 70,
176
+ ipod_series: 92,
177
+ ipod_shuffle: 65,
178
+ ipod_touch: 123,
179
+ ipod_touch_4g: 129,
180
+ kindle_fire: 237,
181
+ kinect: 113,
182
+ laseractive: 103,
183
+ laseractive_ld_rom: 105,
184
+ laseractive_mega_ld: 104,
185
+ lcd_game: 72,
186
+ macbook_pro_15_inch_retina: 233,
187
+ macintosh: 21,
188
+ mark_iii: 58,
189
+ mega_cd: 25,
190
+ msx: 90,
191
+ neo_geo: 22,
192
+ neo_geo_cd: 29,
193
+ neo_geo_pocket: 82,
194
+ neo_geo_pocket_color: 16,
195
+ nintendo64: 4,
196
+ nintendo64_dd: 88,
197
+ nintendo_3ds: 110,
198
+ nintendo_3ds_ll_xl: 231,
199
+ nintendo_ds: 32,
200
+ nintendo_dsi: 102,
201
+ nintendo_dsi_ll_xl: 108,
202
+ nintendo_ds_lite: 71,
203
+ nintendo_mini_classics: 75,
204
+ nintendo_wii: 73,
205
+ nokia_603: 221,
206
+ nokia_c7: 211,
207
+ nokia_e6_00: 215,
208
+ nokia_e7_00: 213,
209
+ nokia_lumia_710: 207,
210
+ nokia_lumia_800: 209,
211
+ nokia_n9: 219,
212
+ nokia_x7_00: 217,
213
+ panasonic_q: 12,
214
+ pc_and_mac: 117,
215
+ pc_cd_rom: 74,
216
+ pc_engine_arcade_cd_rom: 79,
217
+ pc_engine_cd_rom: 78,
218
+ pc_engine_hucard: 76,
219
+ pc_engine_supergrafx: 83,
220
+ pc_engine_super_cd_rom: 77,
221
+ pc_engine_turbo_grafx_16: 19,
222
+ pc_fx: 34,
223
+ pico: 100,
224
+ pippin: 89,
225
+ playdia: 101,
226
+ playstation2: 1,
227
+ playstation3: 37,
228
+ playstation3_slim: 107,
229
+ playstation: 3,
230
+ playstation_vita: 121,
231
+ pocket_dream_console: 85,
232
+ pokemon_mini: 26,
233
+ samsung_galaxy_a_advance_i9070: 159,
234
+ samsung_galaxy_mini_2_gt_s6500: 229,
235
+ samsung_galaxy_note_gt_n7000: 179,
236
+ samsung_galaxy_r_gt_i9103: 171,
237
+ samsung_galaxy_sii_lte_sgh_i727: 173,
238
+ samsung_galaxy_sl_i9003: 167,
239
+ samsung_galaxy_s_captivate: 177,
240
+ samsung_galaxy_s_gt_i9000: 225,
241
+ samsung_galaxy_s_iii_gt_i9300: 227,
242
+ samsung_galaxy_s_ii_gt_i9100: 169,
243
+ samsung_galaxy_tab: 118,
244
+ samsung_galaxy_w_i8150: 175,
245
+ samsung_google_nexuss: 163,
246
+ samsung_gt_i9220: 181,
247
+ samsung_gt_i9228: 183,
248
+ samsung_sgh_i717: 185,
249
+ samsung_shv_e160k: 223,
250
+ samsung_shv_e160l: 191,
251
+ samsung_shv_e160s: 189,
252
+ samsung_shv_e169k: 187,
253
+ samsung_wave_iii_s8600: 161,
254
+ samsung_wave_ii_s8530: 165,
255
+ sega_mega_drive_sega_genesis: 24,
256
+ sega_saturn: 11,
257
+ sony_ericsson_xperia_arc: 197,
258
+ sony_ericsson_xperia_arc_s: 199,
259
+ sony_ericsson_xperia_neo: 193,
260
+ sony_ericsson_xperia_play: 195,
261
+ sony_psp: 33,
262
+ sony_psp_go: 106,
263
+ sony_psp_slim_and_lite: 93,
264
+ super_32x: 35,
265
+ super_famicom_snes: 7,
266
+ three_d_o: 36,
267
+ tomy_evio: 27,
268
+ virtual_boy: 31,
269
+ wii_u: 122,
270
+ windows_pc: 13,
271
+ wonderswan: 15,
272
+ wonderswan_color: 80,
273
+ wonderswan_crystal: 81,
274
+ x68000: 91,
275
+ xbox360: 38,
276
+ xbox: 6
277
+ }
278
+
279
+ ENCODINGS = {
280
+ aac: 31,
281
+ audio_cd: 14,
282
+ blu_ray_region_a: 27,
283
+ blu_ray_region_b: 28,
284
+ blu_ray_region_free: 29,
285
+ dvd_region_1: 6,
286
+ dvd_region_2: 7,
287
+ dvd_region_3: 8,
288
+ dvd_region_4: 9,
289
+ dvd_region_5: 10,
290
+ dvd_region_6: 11,
291
+ dvd_region_free: 5,
292
+ hd_dvd_region_2: 24,
293
+ hd_dvd_region_3: 25,
294
+ hd_dvd_region_free: 26,
295
+ no_region_protection: 13,
296
+ ntsc_j: 2,
297
+ ntsc_uc: 3,
298
+ pal: 4,
299
+ record: 30,
300
+ umd_music_region_2: 17,
301
+ umd_music_region_3: 23,
302
+ umd_music_region_free: 22,
303
+ umd_video_region_1: 20,
304
+ umd_video_region_2: 16,
305
+ umd_video_region_2_6: 21,
306
+ umd_video_region_3: 19,
307
+ umd_video_region_free: 18,
308
+ vcd_region_free: 12,
309
+ vhs_region_free: 15
310
+ }
311
+
312
+ VERSIONS = {
313
+ asia: 6,
314
+ european: 5,
315
+ hong_kong: 19,
316
+ japanese: 2,
317
+ korean: 3,
318
+ us: 4
319
+ }
320
+
321
+ def process_friendly_keys opts
322
+ opts[:mask] = map_array_to_string opts[:mask], MASK if opts[:mask]
323
+ opts[:type] = map_array_to_string opts[:type], TYPES, ',' if opts[:type]
324
+ opts[:genre] = map_array_to_string opts[:genre], GENRES, ',' if opts[:genre]
325
+ opts[:compatible] = map_array_to_string opts[:compatible], COMPATIBILITIES, ',' if opts[:compatible]
326
+ opts[:encoding] = map_array_to_string opts[:encoding], ENCODINGS, ',' if opts[:encoding]
327
+ opts[:version] = map_array_to_string opts[:version], VERSIONS, ',' if opts[:version]
328
+
329
+ # map true/false literals to 1/0
330
+ opts.each do |key, value|
331
+ if value == true
332
+ opts[key] = '1'
333
+ elsif value == false
334
+ opts[key] = '0'
335
+ end
336
+ end
337
+
338
+ opts
339
+ end
340
+
341
+ def map_array_to_string(values, map, join_string = nil)
342
+ if values && values.is_a?(Array)
343
+ return values.flatten.map { |k| map[k] || k }.join join_string
344
+ end
345
+ values
346
+ end
347
+ end
@@ -0,0 +1,7 @@
1
+ require 'open-uri'
2
+
3
+ class PlayAsia::HttpClient
4
+ def request(url, options)
5
+ open url, *options
6
+ end
7
+ end
@@ -0,0 +1,70 @@
1
+ class PlayAsia::ResponseError < RuntimeError
2
+ end
3
+
4
+ class PlayAsia::Response
5
+ attr_reader :raw_text, :status, :items, :content
6
+
7
+ def initialize(text)
8
+ @raw_text = text
9
+ @parsed = Nokogiri::XML.parse text
10
+
11
+ parse_content
12
+ end
13
+
14
+ def error?
15
+ status[:error] != '0'
16
+ end
17
+
18
+ def error_message
19
+ status[:errorstring]
20
+ end
21
+
22
+ def start
23
+ status[:start] ? status[:start].to_i : 0
24
+ end
25
+
26
+ def total_items
27
+ status[:total_items] ? status[:total_items].to_i : nil
28
+ end
29
+
30
+ def items_count
31
+ status[:items] ? status[:items].to_i : nil
32
+ end
33
+
34
+ def has_more?
35
+ raise "Unknown total number of items" if total_items.nil?
36
+ start + items.size < total_items
37
+ end
38
+
39
+ def complete?
40
+ !has_more?
41
+ end
42
+
43
+ private
44
+ def parse_content
45
+ @status = parse_status
46
+ @content = @parsed.at 'content'
47
+ @items = parse_items
48
+
49
+ raise PlayAsia::ResponseError, "status/items not found.\n#{status}" unless items_count || error?
50
+ raise PlayAsia::ResponseError, "Unexpected number of items #{@items.size} instead of #{items_count}" if !error? && @items.size < items_count
51
+ end
52
+
53
+ def parse_status
54
+ dumb_xml_to_hash @parsed.at('status')
55
+ end
56
+
57
+ def parse_items
58
+ content.search('item').map do |xml|
59
+ dumb_xml_to_hash xml
60
+ end
61
+ end
62
+
63
+ def dumb_xml_to_hash(xml)
64
+ hash = {}
65
+ xml.search('*').each do |node|
66
+ hash[node.name.downcase.to_sym] = node.text
67
+ end
68
+ hash
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module PlayAsia
2
+ VERSION = '1.0.0'
3
+ end
data/lib/play_asia.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "play_asia/version"
2
+ require "play_asia/response"
3
+ require "play_asia/http_client"
4
+ require "play_asia/api"
5
+ require "play_asia/api_listing"
6
+
7
+ module PlayAsia
8
+ end
data/play_asia.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/play_asia/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ['James Gregory', 'On the Game']
6
+ gem.email = ['james@onthegame.com.au']
7
+ gem.description = 'A thin wrapper around the Play Asia API'
8
+ gem.summary = 'Play Asia API'
9
+ gem.homepage = 'http://www.onthegame.com.au/about/opensource'
10
+
11
+ gem.add_runtime_dependency 'nokogiri'
12
+ gem.add_development_dependency 'minitest-reporters'
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.name = 'play_asia'
18
+ gem.require_paths = ["lib"]
19
+ gem.version = PlayAsia::VERSION
20
+ end
@@ -0,0 +1,25 @@
1
+ class StubbedHttpClient
2
+ attr_reader :last_url, :last_options
3
+
4
+ def initialize response
5
+ @response = response
6
+ end
7
+
8
+ def request url, options
9
+ @last_url = url
10
+ @last_options = options
11
+
12
+ StubFileResponse.new @response
13
+ end
14
+
15
+ private
16
+ class StubFileResponse
17
+ def initialize content
18
+ @content = content
19
+ end
20
+
21
+ def read
22
+ @content
23
+ end
24
+ end
25
+ end
data/test/test_api.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'minitest/autorun'
2
+ require 'play_asia'
3
+ require_relative 'stubs/stubbed_http_client'
4
+
5
+ class ApiTest < MiniTest::Unit::TestCase
6
+ STUBBED_RESPONSE = '<message><status><query>test</query><error>0</error><errorstring /><items>1</items></status><content><item>1</item></content></message>'
7
+
8
+ def setup
9
+ @api = PlayAsia::Api.new
10
+ @http_client = StubbedHttpClient.new STUBBED_RESPONSE
11
+ @api.http_client = @http_client
12
+ end
13
+
14
+ def test_query_defaults_to_using_play_asia_domain
15
+ @api.query key: 'api_key', user: 1, query: 'test'
16
+
17
+ assert @http_client.last_url.start_with? 'http://www.play-asia.com/__api__.php'
18
+ end
19
+
20
+ def test_query_uses_arguments_as_query_string
21
+ @api.query key: 'api_key', user: 1, query: 'test', a: 1, b: 2, c: 3
22
+ url = @http_client.last_url
23
+ query_string = parse_hash_from_query_string url.split('?').last
24
+
25
+ assert_equal query_string['key'], 'api_key'
26
+ assert_equal query_string['user'], '1'
27
+ assert_equal query_string['query'], 'test'
28
+ assert_equal query_string['a'], '1'
29
+ assert_equal query_string['b'], '2'
30
+ assert_equal query_string['c'], '3'
31
+ end
32
+
33
+ def test_query_raises_if_no_key_given
34
+ ex = assert_raises ArgumentError do
35
+ @api.query user: 1, query: 'test'
36
+ end
37
+ assert_equal ex.message, 'Missing API key (expected :key)'
38
+ end
39
+
40
+ def test_query_raises_if_no_user_given
41
+ ex = assert_raises ArgumentError do
42
+ @api.query key: 'api_key', query: 'test'
43
+ end
44
+ assert_equal ex.message, 'Missing User ID (expected :user)'
45
+ end
46
+
47
+ def test_query_raises_if_no_query_name_given
48
+ ex = assert_raises ArgumentError do
49
+ @api.query key: 'api_key', user: 1
50
+ end
51
+ assert_equal ex.message, 'Missing Query type (expected :query)'
52
+ end
53
+
54
+ private
55
+ def parse_hash_from_query_string query_string
56
+ hash = {}
57
+ query_string.split('&').each do |pair|
58
+ key,value = pair.split '='
59
+ hash[key] = value
60
+ end
61
+ hash
62
+ end
63
+ end
@@ -0,0 +1,140 @@
1
+ require 'minitest/autorun'
2
+ require 'play_asia'
3
+ require 'minitest/mock'
4
+ require_relative 'stubs/stubbed_http_client'
5
+
6
+ class ApiListingTest < MiniTest::Unit::TestCase
7
+ OK_RESPONSE = PlayAsia::Response.new '<message><status><query>test</query><error>0</error><errorstring /><items>1</items></status><content><item>1</item></content></message>'
8
+
9
+ def test_should_map_mask_array_to_string
10
+ api = api_with_stubbed_query
11
+ api.listing mask: [:price, :barcodes, :manufacturer_codes, :sale_info, :release_date, :name, :image,
12
+ :url, :affiliate_url, :genre, :version, :encoding, :compatible]
13
+
14
+ assert_equal 'pjmsrnilagvec', api.queried_options[:mask]
15
+ end
16
+
17
+ def test_should_use_string_for_mask_if_given
18
+ api = api_with_stubbed_query
19
+ api.listing mask: 'string'
20
+
21
+ assert_equal 'string', api.queried_options[:mask]
22
+ end
23
+
24
+ def test_should_map_type_array_to_csv_of_integers
25
+ api = api_with_stubbed_query
26
+ api.listing type: [:accessory, :cd, :groceries, :apparel, :electronics, :movie, :book, :game, :toy]
27
+
28
+ assert_equal '2,3,7,8,9,4,6,1,5', api.queried_options[:type]
29
+ end
30
+
31
+ def test_should_use_string_for_type_if_given
32
+ api = api_with_stubbed_query
33
+ api.listing type: 'string'
34
+
35
+ assert_equal 'string', api.queried_options[:type]
36
+ end
37
+
38
+ def test_should_map_genre_array_to_csv_of_integers
39
+ api = api_with_stubbed_query
40
+ api.listing genre: [:strategy_video_game, :racing_video_game, :simulation_video_game, :tv_series_dvd_vcd]
41
+
42
+ assert_equal '10,11,12,122', api.queried_options[:genre]
43
+ end
44
+
45
+ def test_should_use_string_for_genre_if_given
46
+ api = api_with_stubbed_query
47
+ api.listing genre: 'string'
48
+
49
+ assert_equal 'string', api.queried_options[:genre]
50
+ end
51
+
52
+ def test_should_map_compatible_array_to_csv_of_integers
53
+ api = api_with_stubbed_query
54
+ api.listing compatible: [:dreamcast, :ipad]
55
+
56
+ assert_equal '9,111', api.queried_options[:compatible]
57
+ end
58
+
59
+ def test_should_use_string_for_compatible_if_given
60
+ api = api_with_stubbed_query
61
+ api.listing compatibility: 'string'
62
+
63
+ assert_equal 'string', api.queried_options[:compatibility]
64
+ end
65
+
66
+ def test_should_map_encoding_array_to_csv_of_integers
67
+ api = api_with_stubbed_query
68
+ api.listing encoding: [:pal, :aac]
69
+
70
+ assert_equal '4,31', api.queried_options[:encoding]
71
+ end
72
+
73
+ def test_should_use_string_for_encoding_if_given
74
+ api = api_with_stubbed_query
75
+ api.listing encoding: 'string'
76
+
77
+ assert_equal 'string', api.queried_options[:encoding]
78
+ end
79
+
80
+ def test_should_map_version_array_to_csv_of_integers
81
+ api = api_with_stubbed_query
82
+ api.listing version: [:asia, :hong_kong]
83
+
84
+ assert_equal '6,19', api.queried_options[:version]
85
+ end
86
+
87
+ def test_should_use_version_for_encoding_if_given
88
+ api = api_with_stubbed_query
89
+ api.listing version: 'string'
90
+
91
+ assert_equal 'string', api.queried_options[:version]
92
+ end
93
+
94
+ def test_should_map_skip_preowned_boolean_true_to_1
95
+ api = api_with_stubbed_query
96
+ api.listing skip_preowned: true
97
+
98
+ assert_equal '1', api.queried_options[:skip_preowned]
99
+ end
100
+
101
+ def test_should_map_skip_preowned_boolean_false_to_0
102
+ api = api_with_stubbed_query
103
+ api.listing skip_preowned: false
104
+
105
+ assert_equal '0', api.queried_options[:skip_preowned]
106
+ end
107
+
108
+ def test_should_allow_string_for_skip_preowned
109
+ api = api_with_stubbed_query
110
+ api.listing skip_preowned: 'yes'
111
+
112
+ assert_equal 'yes', api.queried_options[:skip_preowned]
113
+ end
114
+
115
+ def test_should_only_use_supplied_parameters_and_query
116
+ api = api_with_stubbed_query
117
+ api.listing type: [:game], mask: [:name]
118
+
119
+ refute_nil api.queried_options[:type]
120
+ refute_nil api.queried_options[:mask]
121
+ assert_equal [:type, :mask, :query], api.queried_options.keys
122
+ end
123
+
124
+ private
125
+ def api_with_stubbed_query
126
+ api = PlayAsia::Api.new
127
+
128
+ # overwrite the query method so we can grab the options passed to it
129
+ class << api
130
+ attr_reader :queried_options
131
+
132
+ def query(opts = {})
133
+ @queried_options = opts
134
+ OK_RESPONSE
135
+ end
136
+ end
137
+
138
+ api
139
+ end
140
+ end
@@ -0,0 +1,120 @@
1
+ require 'minitest/autorun'
2
+ require 'play_asia'
3
+
4
+ class ResponseTest < MiniTest::Unit::TestCase
5
+ def test_should_have_error_when_error_in_status
6
+ assert error_response.error?
7
+ end
8
+
9
+ def test_should_have_error_message_when_errorstring_in_status
10
+ error_message = 'I am an error!'
11
+
12
+ assert_equal error_message, error_response_with_errorstring(error_message).error_message
13
+ end
14
+
15
+ def test_have_more_should_be_true_if_number_of_items_is_less_than_total_items
16
+ assert ok_response_with_paged_items.has_more?
17
+ refute ok_response_with_paged_items.complete?
18
+ end
19
+
20
+ def test_have_more_should_be_false_if_number_of_items_is_greater_or_equal_to_total_items
21
+ refute ok_response_with_all_items.has_more?
22
+ assert ok_response_with_all_items.complete?
23
+ end
24
+
25
+ def test_have_more_should_be_true_if_number_of_items_is_less_than_total_items_with_start_offset
26
+ assert ok_response_with_paged_items_page_two.has_more?
27
+ refute ok_response_with_paged_items_page_two.complete?
28
+ end
29
+
30
+ def test_have_more_should_be_false_if_number_of_items_is_greater_or_equal_to_total_items_with_start_offset
31
+ refute ok_response_with_paged_items_page_three.has_more?
32
+ assert ok_response_with_paged_items_page_three.complete?
33
+ end
34
+
35
+ private
36
+ def error_response
37
+ PlayAsia::Response.new '<message><status><error>1</error></status><content /></message>'
38
+ end
39
+
40
+ def error_response_with_errorstring(error_string)
41
+ PlayAsia::Response.new "<message><status><error>1</error><errorstring>#{error_string}</errorstring></status><content /></message>"
42
+ end
43
+
44
+ def ok_response_with_paged_items
45
+ PlayAsia::Response.new <<RESPONSE
46
+ <message>
47
+ <status>
48
+ <error>0</error>
49
+ <errorstring />
50
+ <total_items>3</total_items>
51
+ <items>1</items>
52
+ </status>
53
+ <content>
54
+ <item>
55
+ <name>one</name>
56
+ </item>
57
+ </content>
58
+ </message>
59
+ RESPONSE
60
+ end
61
+
62
+ def ok_response_with_paged_items_page_two
63
+ PlayAsia::Response.new <<RESPONSE
64
+ <message>
65
+ <status>
66
+ <error>0</error>
67
+ <errorstring />
68
+ <start>1</start>
69
+ <total_items>3</total_items>
70
+ <items>1</items>
71
+ </status>
72
+ <content>
73
+ <item>
74
+ <name>two</name>
75
+ </item>
76
+ </content>
77
+ </message>
78
+ RESPONSE
79
+ end
80
+
81
+ def ok_response_with_paged_items_page_three
82
+ PlayAsia::Response.new <<RESPONSE
83
+ <message>
84
+ <status>
85
+ <error>0</error>
86
+ <errorstring />
87
+ <start>2</start>
88
+ <total_items>3</total_items>
89
+ <items>1</items>
90
+ </status>
91
+ <content>
92
+ <item>
93
+ <name>three</name>
94
+ </item>
95
+ </content>
96
+ </message>
97
+ RESPONSE
98
+ end
99
+
100
+ def ok_response_with_all_items
101
+ PlayAsia::Response.new <<RESPONSE
102
+ <message>
103
+ <status>
104
+ <error>0</error>
105
+ <errorstring />
106
+ <total_items>2</total_items>
107
+ <items>2</items>
108
+ </status>
109
+ <content>
110
+ <item>
111
+ <name>one</name>
112
+ </item>
113
+ <item>
114
+ <name>two</name>
115
+ </item>
116
+ </content>
117
+ </message>
118
+ RESPONSE
119
+ end
120
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: play_asia
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Gregory
9
+ - On the Game
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-02-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: minitest-reporters
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ description: A thin wrapper around the Play Asia API
48
+ email:
49
+ - james@onthegame.com.au
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE
57
+ - README.md
58
+ - Rakefile
59
+ - lib/play_asia.rb
60
+ - lib/play_asia/api.rb
61
+ - lib/play_asia/api_listing.rb
62
+ - lib/play_asia/http_client.rb
63
+ - lib/play_asia/response.rb
64
+ - lib/play_asia/version.rb
65
+ - play_asia.gemspec
66
+ - test/stubs/stubbed_http_client.rb
67
+ - test/test_api.rb
68
+ - test/test_api_listing.rb
69
+ - test/test_response.rb
70
+ homepage: http://www.onthegame.com.au/about/opensource
71
+ licenses: []
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.24
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Play Asia API
94
+ test_files:
95
+ - test/stubs/stubbed_http_client.rb
96
+ - test/test_api.rb
97
+ - test/test_api_listing.rb
98
+ - test/test_response.rb