# Copyright:: Copyright (c) 2007 Amazon Technologies, Inc.
# License::   Apache License, Version 2.0

require 'test/unit/testcase'
require 'mturk'
require 'amazon/webservices/mturk/question_generator'
require 'amazon/webservices/util/soap_transport'
require 'amazon/webservices/util/rest_transport'

# Allow user to skip these tests by setting the DISABLE_MTURK_SANDBOX_TEST environment variable
if ENV['DISABLE_MTURK_SANDBOX_TEST'].nil?

class TestMechanicalTurkRequester < Test::Unit::TestCase
  include Amazon::WebServices

  def setup
    # Setting up the default requester interface.  
    #   This will default to running against Sandbox, but we'll the host explicitly for safety. 
    #   Access Key ID and Secret Access Key will be loaded from user preference file
    #     If not found, the user will be interatively queried for their authentication information.
    @@mturk ||= MechanicalTurkRequester.new( :Host => :Sandbox )

    # utilize the SOAP transport, if we can
    @@mturk_soap ||= MechanicalTurkRequester.new( :Host => :Sandbox, :Transport => :SOAP ) if Util::SOAPTransport.canSOAP?
    # utilize the REST transport with default HTTP method
    @@mturk_rest ||= MechanicalTurkRequester.new( :Host => :Sandbox, :Transport => :REST )
    # utilize the REST transport via Get
    @@mturk_rest_get ||= MechanicalTurkRequester.new( :Host => :Sandbox, :Transport => :REST, :RestStyle => :Get )
    # utilize the REST transport via Post, if we can
    @@mturk_rest_post ||= MechanicalTurkRequester.new( :Host => :Sandbox, :Transport => :REST, :RestStyle => :Post ) if Util::RESTTransport.canPost?
  end

  def testAvailableFunds
    funds = @@mturk.availableFunds
    assert_equal 10000.0, funds, "Sandbox should always show 10k available funds"
  end

  def testCreateHIT
    question = MTurk::QuestionGenerator.build { |q| q.ask 'Have you tried Ruby?' }
    result = @@mturk.createHIT :Title => 'Ruby SDK Test Hit',
                              :Description => 'Autogenerated hit from mturk test cases',
                              :Keywords => 'Ruby, test, SDK',
                              :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                              :Question => question
    assert_not_nil( result[:HITId] )
    @@mturk.forceExpireHIT( :HITId => result[:HITId] )
    @@mturk.disposeHIT( :HITId => result[:HITId] )
  end

  def testCreateHITFailure
    begin
      @@mturk.createHIT :Title => 'Ruby SDK Test Hit',
                        :Description => 'Autogenerated hit from mturk test cases',
                        :Keywords => 'Ruby, test, SDK',
                        :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                        :Question => "Invalid Question"
      fail "Mechanical Turk should have thrown an exception"
    rescue => e
      raise e unless e.is_a?( Util::ValidationException )
      assert_equal "AWS.MechanicalTurk.XMLParseError", e.message
    end
  end
  
if Util::SOAPTransport.canSOAP?

  def testSOAPCreateHIT
    question = MTurk::QuestionGenerator.build { |q| q.ask 'Have you tried Ruby?' }
    result = @@mturk_soap.createHIT :Title => 'Ruby SDK Test Hit',
                              :Description => 'Autogenerated hit from mturk test cases',
                              :Keywords => 'Ruby, test, SDK',
                              :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                              :Question => question
    assert_not_nil( result[:HITId] )
    @@mturk_soap.forceExpireHIT( :HITId => result[:HITId] )
    @@mturk_soap.disposeHIT( :HITId => result[:HITId] )
  end

  def testSOAPCreateHITFailure
    begin
      @@mturk_soap.createHIT :Title => 'Ruby SDK Test Hit',
                             :Description => 'Autogenerated hit from mturk test cases',
                             :Keywords => 'Ruby, test, SDK',
                             :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                             :Question => "Invalid Question"
      fail "Mechanical Turk should have thrown an exception"
    rescue => e
      raise e unless e.is_a?( Util::ValidationException )
      assert_equal "AWS.MechanicalTurk.XMLParseError", e.message
    end
  end

end # if Util::SOAPTransport.canSOAP?

  def testRESTCreateHIT
    question = MTurk::QuestionGenerator.build { |q| q.ask 'Have you tried Ruby?' }
    result = @@mturk_rest.createHIT :Title => 'Ruby SDK Test Hit',
                              :Description => 'Autogenerated hit from mturk test cases',
                              :Keywords => 'Ruby, test, SDK',
                              :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                              :Question => question
    assert_not_nil( result[:HITId] )
    @@mturk_rest.forceExpireHIT( :HITId => result[:HITId] )
    @@mturk_rest.disposeHIT( :HITId => result[:HITId] )
  end

  def testRESTCreateHITFailure
    begin
      @@mturk_rest.createHIT :Title => 'Ruby SDK Test Hit',
                             :Description => 'Autogenerated hit from mturk test cases',
                             :Keywords => 'Ruby, test, SDK',
                             :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                             :Question => "Invalid Question"
      fail "Mechanical Turk should have thrown an exception"
    rescue => e
      raise e unless e.is_a?( Util::ValidationException )
      assert_equal "AWS.MechanicalTurk.XMLParseError", e.message
    end
  end

  def testGetRESTCreateHIT
    question = MTurk::QuestionGenerator.build { |q| q.ask 'Have you tried Ruby?' }
    result = @@mturk_rest_get.createHIT :Title => 'Ruby SDK Test Hit',
                                  :Description => 'Autogenerated hit from mturk test cases',
                                  :Keywords => 'Ruby, test, SDK',
                                  :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                                  :Question => question
    assert_not_nil( result[:HITId] )
    @@mturk_rest_get.forceExpireHIT( :HITId => result[:HITId] )
    @@mturk_rest_get.disposeHIT( :HITId => result[:HITId] )
  end

  def testGetRESTCreateHITFailure
    begin
      @@mturk_rest_get.createHIT :Title => 'Ruby SDK Test Hit',
                                 :Description => 'Autogenerated hit from mturk test cases',
                                 :Keywords => 'Ruby, test, SDK',
                                 :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                                 :Question => "Invalid Question"
        fail "Mechanical Turk should have thrown an exception"
    rescue => e
      raise e unless e.is_a?( Util::ValidationException )
      assert_equal "AWS.MechanicalTurk.XMLParseError", e.message
    end
  end

if Util::RESTTransport.canPost?

  def testPostRESTCreateHIT
    question = MTurk::QuestionGenerator.build { |q| q.ask 'Have you tried Ruby?' }
    result = @@mturk_rest_post.createHIT :Title => 'Ruby SDK Test Hit',
                              :Description => 'Autogenerated hit from mturk test cases',
                              :Keywords => 'Ruby, test, SDK',
                              :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                              :Question => question
    assert_not_nil( result[:HITId] )
    @@mturk_rest_post.forceExpireHIT( :HITId => result[:HITId] )
    @@mturk_rest_post.disposeHIT( :HITId => result[:HITId] )
  end

  def testPostRESTCreateHITFailure
    begin
      @@mturk_rest_post.createHIT :Title => 'Ruby SDK Test Hit',
                                  :Description => 'Autogenerated hit from mturk test cases',
                                  :Keywords => 'Ruby, test, SDK',
                                  :Reward => { :Amount => 23.44, :CurrencyCode => 'USD' },
                                  :Question => "Invalid Question"
      fail "Mechanical Turk should have thrown an exception"
    rescue => e
      raise e unless e.is_a?( Util::ValidationException )
      assert_equal "AWS.MechanicalTurk.XMLParseError", e.message
    end
  end

end # if Util::RESTTransport.canPost?

end

end # if not DISABLE_MTURK_SANDBOX_TEST
