Permalink
Browse files

Complete rewrite of the error handling and added new API methods

  • Loading branch information...
1 parent 93fb3d9 commit 2e5fa6e45460b0dd6f0b39062588d25093057289 Henry Maddocks committed Apr 6, 2012
Showing with 244 additions and 97 deletions.
  1. +106 −74 lib/ponoko/ponoko.rb
  2. +10 −2 test/ponoko_test.rb
  3. +21 −1 test/test_nodes.rb
  4. +107 −20 test/test_products.rb
View
@@ -8,14 +8,19 @@ class << self; attr_accessor :api end
class Sandbox
def self.step_order order
- resp = Ponoko::api.step_order order.key
- order.update resp['order'] # FIXME fetch
+ order.with_handle_error { Ponoko::api.step_order order.key }
+ end
+
+ def self.request_log entries
+ Ponoko::api.request_log entries
end
- end
+ end
+
class Base
attr_accessor :ref, :key
attr_accessor :created_at, :updated_at
+ attr_reader :error
def initialize params = {}
update params
@@ -49,14 +54,36 @@ def self.get! key = nil
end
def update!
- resp = Base::with_handle_error { Ponoko::api.send "get_#{self.class.ponoko_objects}", key }
- update resp[self.class.ponoko_object] # FIXME fetch
+ with_handle_error { Ponoko::api.send "get_#{self.class.ponoko_objects}", key }
end
def self.with_handle_error
+ resp = yield.tap {|resp| throw :error, Error.new(resp['error']) if resp['error'] }
+
+ rescue JSON::ParserError
+ fail PonokoAPIError, "Ponoko returned an invalid response; '#{resp}'" # FIXME resp will always be nil
+ end
+
+ def with_handle_error
+# @error = nil;
resp = yield
- fail PonokoAPIError, resp['error']['message'] if resp['error']
- resp
+
+ if resp.is_a? Hash
+ if resp['error']
+ @error = Error.new(resp['error'])
+ else
+ data = resp[self.class.ponoko_object]
+ if data.nil?
+ return resp
+ else
+ update data
+ end
+ end
+ self
+ else
+ resp
+ end
+
rescue JSON::ParserError
fail PonokoAPIError, "Ponoko returned an invalid response; '#{resp}'"
end
@@ -69,24 +96,19 @@ class Product < Base
attr_writer :locked, :total_make_cost
def send!
- fail Ponoko::PonokoAPIError, "Product must have a design." if @designs.empty?
- resp = Base::with_handle_error { Ponoko::api.post_product self.to_params }
-
- update resp['product'] # FIXME fetch
- self
+ with_handle_error { Ponoko::api.post_product self.to_params }
end
def initialize params = {}
@designs = []
@design_images = []
@hardware = []
@assembly_instructions = []
- super params
+ super
end
- def delete
- Ponoko::api.delete_product self.key
- resp = Base::with_handle_error { Ponoko::api.post_product self.to_params }
+ def delete!
+ with_handle_error { Ponoko::api.delete_product self.key }
nil
end
@@ -108,7 +130,7 @@ def designs= designs
def hardware= hw
@hardware.clear
hw.each do |h|
- add_hardware Hardware.new(h), 1
+ @hardware << Hardware.new(h)
end
end
@@ -118,61 +140,54 @@ def add_designs *designs # quantity?
end
end
- def add_design!
-# resp = Ponoko::api.post_design self.key, design
- resp = Base::with_handle_error { Ponoko::api.post_design self.key, design }
- update resp['product'] # FIXME fetch
- end
-
- def add_design_image file, default = false
-# resp = Ponoko::api.post_design_image self.key, {'uploaded_data' => file, 'default' => default}
- resp = Base::with_handle_error { Ponoko::api.post_design_image self.key, {'uploaded_data' => file, 'default' => default} }
- update resp['product'] # FIXME fetch
+ def add_design! design
+ if key.nil? # product hasn't been 'saved' to Ponoko yet.
+ add_designs design
+ else
+ with_handle_error { Ponoko::api.post_design self.key, design.to_params }
+ end
end
+ # Adding supplementary objects to products always posts to the server
def add_design_image! file, default = false
-# resp = Ponoko::api.post_design_image self.key, {'uploaded_data' => file, 'default' => default}
- resp = Base::with_handle_error { Ponoko::api.post_design_image self.key, {'uploaded_data' => file, 'default' => default} }
- update resp['product'] # FIXME fetch
+ if key.nil? # product hasn't been 'saved' to Ponoko yet.
+ fail Ponoko::PonokoAPIError, "Design Images can only be added to Products on the server."
+ else
+ with_handle_error { Ponoko::api.post_design_image self.key, {'uploaded_data' => file, 'default' => default} }
+ end
end
def get_design_image_file! filename
- Ponoko::api.get_design_image self.key, {'filename' => filename}
+ with_handle_error { Ponoko::api.get_design_image self.key, {'filename' => filename} }
end
- def add_assembly_instructions file_or_url
- resp = if file_or_url.is_a? File
- Ponoko::api.post_assembly_instructions self.key, {'uploaded_data' => file_or_url}
+ def add_assembly_instructions! file_or_url
+ if key.nil? # product hasn't been 'saved' to Ponoko yet.
+ fail Ponoko::PonokoAPIError, "Assembly Instructions can only be added to Products on the server."
else
- Ponoko::api.post_assembly_instructions self.key, {'file_url' => file_or_url}
+ if file_or_url.is_a? File
+ with_handle_error { Ponoko::api.post_assembly_instructions_file self.key, {'uploaded_data' => file_or_url} }
+ else
+ with_handle_error { Ponoko::api.post_assembly_instructions_url self.key, {'file_url' => file_or_url} }
+ end
end
-
- update resp['product'] # FIXME fetch
- end
-
- def add_assembly_instructions! file_or_url
- resp = Ponoko::api.post_assembly_instructions self.key, {'uploaded_data' => file_or_url}
- update resp['product'] # FIXME fetch
end
def get_assembly_instructions_file! filename
- Ponoko::api.get_assembly_instructions self.key, {'filename' => filename}
+ with_handle_error { Ponoko::api.get_assembly_instructions self.key, {'filename' => filename} }
end
- def add_hardware hardware_or_sku, quantity
- if hardware_or_sku.is_a? String # FIXME!
- resp = Ponoko::api.post_hardware self.key, {'sku' => sku, 'quantity' => quantity}
- update resp['product'] # FIXME fetch
+ def add_hardware! hardware_or_sku, quantity = nil
+ if key.nil? # product hasn't been 'saved' to Ponoko yet.
+ fail Ponoko::PonokoAPIError, "Hardware can only be added to Products on the server."
else
- hardware << hardware_or_sku
+ if hardware_or_sku.is_a? String # FIXME! respond_to? :to_params
+ with_handle_error { Ponoko::api.post_hardware self.key, {'sku' => hardware_or_sku, 'quantity' => quantity} }
+ else
+ hardware_or_sku.quantity = quantity unless quatity.nil?
+ with_handle_error { Ponoko::api.post_hardware self.key, hardware_or_sku.to_params }
+ end
end
-
- self
- end
-
- def add_hardware! sku, quantity
- resp = Ponoko::api.post_hardware self.key, {'sku' => sku, 'quantity' => quantity}
- update resp['product'] # FIXME fetch
end
def to_params
@@ -195,8 +210,7 @@ def total_cost
end
class Design < Base
- attr_accessor :material_key, :design_file, :filename, :size, :quantity
- attr_accessor :content_type
+ attr_accessor :material_key, :design_file, :filename, :size, :quantity, :content_type
attr_reader :material
attr_writer :make_cost
@@ -217,14 +231,15 @@ def total_cost
end
def to_params
+ fail Ponoko::PonokoAPIError, "Design must have a Design File." if design_file.nil?
fail Ponoko::PonokoAPIError, "Design must have a Material." if material.nil?
- {'file_name' => File.basename(design_file), 'uploaded_data' => design_file, 'ref' => ref, 'material_key' => material.to_params}
+ {'file_name' => File.basename(design_file.path), 'uploaded_data' => design_file, 'ref' => ref, 'material_key' => material.to_params}
end
end
class Material < Base
- attr_accessor :type, :weight, :color, :thickness, :name, :width, :material_type, :dimensions
- attr_accessor :length, :kind
+ attr_accessor :kind, :name, :color, :thickness, :size
+ attr_accessor :type, :length, :width, :weight, :material_type, :dimensions
attr_accessor :updated_at
def to_params
@@ -237,6 +252,10 @@ class Third_Party_Item < Base
class Hardware < Third_Party_Item
attr_accessor :sku, :name, :weight, :price, :url, :quantity
+
+ def to_params
+ {'sku' => sku, 'quantity' => quantity}
+ end
end
class Address < Hash; end
@@ -256,12 +275,11 @@ def initialize params = {}
end
def send!
- fail Ponoko::PonokoAPIError, "Order must have a Shipping Option Code" if shipping_option_code.nil?
+ fail Ponoko::PonokoAPIError, "Order must have a Delivery Address" if delivery_address.nil?
fail Ponoko::PonokoAPIError, "Order must have Products" if products.empty?
-
- resp = Ponoko::api.post_order self.to_params
- update resp['order'] # FIXME fetch
- self
+ fail Ponoko::PonokoAPIError, "Order must have a Shipping Option Code" if shipping_option_code.nil?
+
+ with_handle_error { Ponoko::api.post_order self.to_params }
end
def add_product product, quantity = 1
@@ -289,8 +307,7 @@ def shipped?
end
def status!
- resp = Ponoko::api.get_order_status key
- update resp['order'] # FIXME fetch
+ with_handle_error { Ponoko::api.get_order_status key }
status
end
@@ -300,14 +317,12 @@ def status
end
def shipping_options!
- resp = Ponoko::api.get_shipping_options self.to_params
+ fail Ponoko::PonokoAPIError, "Order must have a Delivery Address" if delivery_address.nil?
+ resp = with_handle_error { Ponoko::api.get_shipping_options self.to_params }
resp['shipping_options']['options'] # FIXME fetch
end
def to_params
- fail Ponoko::PonokoAPIError, "Order must have a Delivery Address" if delivery_address.nil?
- fail Ponoko::PonokoAPIError, "Order must have Products" if products.empty?
-
params = {}
products = @products.collect do |p|
{'key' => p['product'].key, 'quantity' => p['quantity']}
@@ -369,13 +384,30 @@ def [] key
@catalogue[key]
end
-# def (()) key
-# end
-
def count
@materials.length
end
end
+ class Error < Base
+ attr_accessor :message, :errors
+
+ def errors= errors
+ @errors = []
+ errors.each do |e|
+ case e['type']
+ when 'design_processing'
+ @errors << DesignError.new(e)
+ else
+ @errors << Error.new(e)
+ end
+ end
+ end
+ end
+
+ class DesignError < Base
+ attr_accessor :error_code, :name
+ end
+
end # module Ponoko
View
@@ -33,7 +33,7 @@ def hr label
pp node
mc = node.material_catalogue
-pp mc
+# pp mc
hr "Products"
@@ -60,7 +60,15 @@ def hr label
new_product.send!
pp new_product
-# exit
+# new_product.add_design_image! File.new(File.dirname(__FILE__) + "/Fixtures/lamp-1_product_page.jpg")
+new_product.add_assembly_instructions! 'http://www.instructables.com/id/3D-print-your-minecraft-avatar/'
+new_product.add_hardware! 'COM-00680', 2
+
+pp new_product
+
+new_product.delete
+
+exit
hr "Orders"
orders = Ponoko::Order.get!
View
@@ -35,6 +35,15 @@ def test_get_a_node
assert_equal "Ponoko - United States", node.name
end
+ def test_get_node_404
+ @test_api.expect(:send, make_resp(:ponoko_404), ['get_nodes', 'bogus_key'])
+
+ node = Ponoko::Node.get! "bogus_key"
+
+ assert_equal 'error', resp.keys.first
+ @test_auth.verify
+ end
+
def test_get_material_catalogue
@test_api.expect(:send,
make_resp(:node_200),
@@ -152,13 +161,24 @@ def test_dont_refresh_new_material_catalogue
catalogue = node.material_catalogue! # nothing raised by bad expect
end
+
+ def test_get_material_cataloge_fail
+ @test_api.expect(:send, make_resp(:ponoko_404), ["get_material_catalogue", "bogus_key"])
+
+ resp = @ponoko.get_material_catalogue 'bogus_key'
+ assert_equal 'error', resp.keys.first
+ @test_auth.verify
+ end
+
def test_handle_unknown_field
@test_api.expect(:send,
make_resp(:node_unknown_field),
['get_nodes', '2413'])
- node = Ponoko::Node.get! "2413"
+ node = Ponoko::Node.new "key" => "2413"
+
+ catalogue = node.material_catalogue
@test_api.verify
assert_equal "Ponoko - United States", node.name
Oops, something went wrong.

0 comments on commit 2e5fa6e

Please sign in to comment.