Ruby:HTTParty:无法正确格式化 XML POST 数据?

发布于 2024-11-18 16:37:12 字数 2366 浏览 1 评论 0原文

注意:“对象”是一个占位符,因为我认为我不应该说明控制器具体做什么。

因此,我有多种方法来调用我的应用程序 API,以下在命令行中工作:

curl -H 'Content-Type: application/xml' -d '<object><name>Test API object</name><password>password</password><description>This is a test object</description></object>' "http://acme.example.dev/objects.xml?api_key=1234"

上面的命令在开发日志中生成以下请求:

Processing ObjectsController#create to xml (for 127.0.0.1 at 2011-07-07 09:17:51) [POST]
  Parameters: {"format"=>"xml", "action"=>"create", "api_key"=>"1234", "controller"=>"objects", 
  "object"=>{"name"=>"Test API object", "description"=>"This is a test object", "password"=>"[FILTERED]"}}

现在,我正在尝试使用 API 为操作编写测试,以确保API 和控制器都可以工作。 这是我当前的(损坏的)httparty 命令:

  response = post("create", :api_key => SharedTest.user_api_key, :xml => data, :format => "xml")

该命令在测试日志中生成以下请求:

Processing ObjectsController#create to xml (for 0.0.0.0 at 2011-07-07 09:37:35) [POST]
  Parameters: {
        "xml"=>"<object><name><![CDATA[first post]]></name>
                    <description><![CDATA[Things are not as they used to be]]></description>
                    <password><![CDATA[WHEE]]></password>
                </object>", 
                "format"=>"xml", 
                "api_key"=>"the_hatter_wants_to_have_tea1", 
                "action"=>"create", 
                "controller"=>"objects

因此,如您所见,命令行命令实际上从 xml 生成对象哈希,而 httparty 命令最终保留在 xml 中,这会给 create 方法带来问题,因为它需要哈希值。

有什么想法/适当的文档吗? 当前文档说该帖子需要一个网址和“选项”,然后从未说明可用的选项


**编辑
根据@Casper的建议,我的方法现在看起来像这样:

def post_through_api_to_url(url, data, api_key = SharedTest.user_api_key)

  response = post("create", {
    :query => {
      :api_key => api_key
    },
    :headers => {
      "Content-Type" => "application/xml"
    },
    :body => data
  })
  ap @request.env["REQUEST_URI"]
  assert_response :success

  return response
end

不幸的是,assert_response失败,因为通过api密钥的身份验证失败。 查看 request_uri 的最前面,api_key 没有正确设置...它显示:

api_key%5D=the_hatter_wants_to_have_tea1"

但它应该等于,没有 %5D (右方括号)

NOTE: "object" is a placeholder work, as I don't think I should be saying what the controller does specifically.

so, I have multiple ways of calling my apps API, the following works in the command line:

curl -H 'Content-Type: application/xml' -d '<object><name>Test API object</name><password>password</password><description>This is a test object</description></object>' "http://acme.example.dev/objects.xml?api_key=1234"

the above command generates the following request in the devlog:

Processing ObjectsController#create to xml (for 127.0.0.1 at 2011-07-07 09:17:51) [POST]
  Parameters: {"format"=>"xml", "action"=>"create", "api_key"=>"1234", "controller"=>"objects", 
  "object"=>{"name"=>"Test API object", "description"=>"This is a test object", "password"=>"[FILTERED]"}}

Now, I'm trying to write tests for the actions using the API, to make sure the API works, as well as the controllers.
Here is my current (broken) httparty command:

  response = post("create", :api_key => SharedTest.user_api_key, :xml => data, :format => "xml")

this command generates the following request in the testlog:

Processing ObjectsController#create to xml (for 0.0.0.0 at 2011-07-07 09:37:35) [POST]
  Parameters: {
        "xml"=>"<object><name><![CDATA[first post]]></name>
                    <description><![CDATA[Things are not as they used to be]]></description>
                    <password><![CDATA[WHEE]]></password>
                </object>", 
                "format"=>"xml", 
                "api_key"=>"the_hatter_wants_to_have_tea1", 
                "action"=>"create", 
                "controller"=>"objects

So, as you can see, the command line command actually generates the object hash from the xml, whereas the httparty command ends up staying in xml, which causes problems for the create method, as it needs a hash.

Any ideas / proper documentation?
Current documentation says that post takes an url, and "options" and then never says what options are available


**EDIT:
as per @Casper's suggestion, my method now looks like this:

def post_through_api_to_url(url, data, api_key = SharedTest.user_api_key)

  response = post("create", {
    :query => {
      :api_key => api_key
    },
    :headers => {
      "Content-Type" => "application/xml"
    },
    :body => data
  })
  ap @request.env["REQUEST_URI"]
  assert_response :success

  return response
end

unfortunately, the assert_response fails, because the authentication via the api key fails.
looking at the very of of the request_uri, the api_key isn't being set properly... it shows:

api_key%5D=the_hatter_wants_to_have_tea1"

but it should just be equals, without the %5D (right square bracket)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

朕就是辣么酷 2024-11-25 16:37:12

我认为这就是你应该如何使用它:

options = {
  :query => {
    :api_key => 1234
  },

  :headers => {
    "Content-Type" => "application/xml"
  },

  :body => "<xmlcode>goes here</xmlcode>"
}

post("/create", options)

I think this is how you're supposed to use it:

options = {
  :query => {
    :api_key => 1234
  },

  :headers => {
    "Content-Type" => "application/xml"
  },

  :body => "<xmlcode>goes here</xmlcode>"
}

post("/create", options)
离旧人 2024-11-25 16:37:12

请原谅我对此很基本,但如果您只想发送一个变量作为参数,为什么不按照 Casper 的建议去做,而只是这样做:

post("/create?api_key=1234", options)

或者不要测试 HTTParty 在访问 API 方面的特性,也许可以使用以下代码编写测试机架::测试?非常粗略的例子...

require "rack/test"
require "nokogiri"

class ObjectsTest < Test::Unit::TestCase
  include Rack::Test::Methods

  def app
    MyApp.new
  end

  def create_an_object(o)
    authorize "x", "1234" # or however you want to authenticate using query params
    header 'Accept', 'text/xml'
    header 'Content-Type', 'text/xml'
    body o.to_xml
    post "/create"

    xml = Nokogiri::XML(last_response.body)
    assert something_logic_about(xml)
  end

end

Forgive me for being basic about it but if you only want to send one variable as a parameter, why don't you do as Casper suggests, but just do:

post("/create?api_key=1234", options)

Or rather than testing HTTParty's peculiarities in accessing your API, perhaps write your tests using Rack::Test? Very rough example...

require "rack/test"
require "nokogiri"

class ObjectsTest < Test::Unit::TestCase
  include Rack::Test::Methods

  def app
    MyApp.new
  end

  def create_an_object(o)
    authorize "x", "1234" # or however you want to authenticate using query params
    header 'Accept', 'text/xml'
    header 'Content-Type', 'text/xml'
    body o.to_xml
    post "/create"

    xml = Nokogiri::XML(last_response.body)
    assert something_logic_about(xml)
  end

end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文