मैंने वेब को खराब कर दिया है, लेकिन, हां, मुझे बस सामग्री प्रकार को सही तरीके से भेजने के लिए रुपेक नहीं मिल रहा है, इसलिए मैं अपने JSON API का परीक्षण कर सकता हूं। मैं टेम्पलेट्स, रेल 3.0.11, और रूबी 1.9.2-पी 180 के लिए आरएबीएल मणि का उपयोग कर रहा हूं।रुपयेपेक का उपयोग करके, मैं रेल नियंत्रक 3.0.11 में अपने नियंत्रक के JSON प्रारूप का परीक्षण कैसे करूं?
मेरे कर्ल उत्पादन है, जो ठीक काम करता है (एक 401 होना चाहिए, मुझे पता है):
mrsnuggles:tmp gaahrdner$ curl -i -H "Accept: application/json" -X POST -d @bleh http://localhost:3000/applications
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache
X-Ua-Compatible: IE=Edge
X-Runtime: 0.561638
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-02-18)
Date: Tue, 06 Mar 2012 01:10:51 GMT
Content-Length: 74
Connection: Keep-Alive
Set-Cookie: _session_id=8e8b73b5a6e5c95447aab13dafd59993; path=/; HttpOnly
{"status":"error","message":"You are not authorized to access this page."}
नमूना अपने परीक्षण मामलों में से एक से:
describe ApplicationsController do
render_views
disconnect_sunspot
let(:application) { Factory.create(:application) }
subject { application }
context "JSON" do
describe "creating a new application" do
context "when not authorized" do
before do
json = { :application => { :name => "foo", :description => "bar" } }
request.env['CONTENT_TYPE'] = 'application/json'
request.env['RAW_POST_DATA'] = json
post :create
end
it "should not allow creation of an application" do
Application.count.should == 0
end
it "should respond with a 403" do
response.status.should eq(403)
end
it "should have a status and message key in the hash" do
JSON.parse(response.body)["status"] == "error"
JSON.parse(response.body)["message"] =~ /authorized/
end
end
context "authorized" do
end
end
end
end
इन परीक्षणों हालांकि पारित कभी नहीं, मैं हमेशा रीडायरेक्ट हो जाते हैं और मेरी सामग्री-प्रकार हमेशा text/html
है, भले ही मैं अपने पहले ब्लॉक में टाइप कैसे निर्दिष्ट करता हूं:
# nope
before do
post :create, {}, { :format => :json }
end
# nada
before do
post :create, :format => Mime::JSON
end
# nuh uh
before do
request.env['ACCEPT'] = 'application/json'
post :create, { :foo => :bar }
end
यहाँ rspec उत्पादन होता है:
Failures:
1) ApplicationsController JSON creating a new application when not authorized should respond with a 403
Failure/Error: response.status.should eq(403)
expected 403
got 302
(compared using ==)
# ./spec/controllers/applications_controller_spec.rb:31:in `block (5 levels) in <top (required)>'
2) ApplicationsController JSON creating a new application when not authorized should have a status and message key in the hash
Failure/Error: JSON.parse(response.body)["status"] == "errors"
JSON::ParserError:
756: unexpected token at '<html><body>You are being <a href="http://test.host/">redirected</a>.</body></html>'
# ./spec/controllers/applications_controller_spec.rb:35:in `block (5 levels) in <top (required)>'
आप मैं, HTML स्वरूप के लिए 302 रीडायरेक्ट हो रही है, भले ही मैं 'आवेदन/json' निर्दिष्ट करने के लिए कोशिश कर रहा हूँ देख सकते हैं।
यहाँ मेरी application_controller.rb
है, rescue_from बिट के साथ:
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, :with => :not_found
protect_from_forgery
helper_method :current_user
helper_method :remove_dns_record
rescue_from CanCan::AccessDenied do |exception|
flash[:alert] = exception.message
respond_to do |format|
h = { :status => "error", :message => exception.message }
format.html { redirect_to root_url }
format.json { render :json => h, :status => :forbidden }
format.xml { render :xml => h, :status => :forbidden }
end
end
private
def not_found(exception)
respond_to do |format|
h = { :status => "error", :message => exception.message }
format.html { render :file => "#{RAILS_ROOT}/public/404.html", :status => :not_found }
format.json { render :json => h, :status => :not_found }
format.xml { render :xml => h, :status => :not_found }
end
end
end
और यह भी applications_controller.rb
, विशेष रूप से 'बनाने' कार्रवाई है जो कि मैं क्या परीक्षण करने के लिए कोशिश कर रहा हूँ। इस समय यह काफी बदसूरत है क्योंकि मैं state_machine
का उपयोग कर रहा हूं और हटाई गई विधि को ओवरराइड कर रहा हूं।
def create
# this needs to be cleaned up and use accepts_attributes_for
@application = Application.new(params[:application])
@environments = params[:application][:environment_ids]
@application.environment_ids<<@environments unless @environments.blank?
if params[:site_bindings] == "new"
@site = Site.new(:name => params[:application][:name])
@environments.each do |e|
@site.siteenvs << Siteenv.new(:environment_id => e)
end
end
if @site
@application.sites << @site
end
if @application.save
if @site
@site.siteenvs.each do |se|
appenv = @application.appenvs.select {|e| e.environment_id == se.environment_id }
se.appenv = appenv.first
se.save
end
end
flash[:success] = "New application created."
respond_with(@application, :location => @application)
else
render 'new'
end
# super stinky :(
@application.change_servers_on_appenvs(params[:servers]) unless params[:servers].blank?
@application.save
end
मैं स्रोत कोड यहाँ देखा है: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/responder.rb, और यह इसे सही ढंग से है कि इसी तरह के मुद्दों और संभावित समाधानों है लगता ढेर अतिप्रवाह पर सवालों की एक संख्या के रूप में जवाब देना चाहिए, साथ ही लगता है, लेकिन कोई भी काम मेरे लिए।
मैं क्या गलत कर रहा हूं?
मेरे पास आर्थर वापस आने के लिए धन्यवाद। मैंने आपके द्वारा किए गए परिवर्तन किए हैं, लेकिन मुझे अभी भी वही परिणाम मिल रहे हैं, जहां परीक्षण को HTML '1 पर रीडायरेक्ट किया जा रहा है) अनुप्रयोग नियंत्रक JSON एक नया एप्लिकेशन बनाते समय अधिकृत नहीं होने पर किसी अनुप्रयोग के निर्माण की अनुमति नहीं देनी चाहिए ' ' विफलता/त्रुटि: JSON.parse (response.body) ["status"] == "त्रुटियां" ' ' JSON :: पार्सर त्रुटि: ' ' 756: अप्रत्याशित टोकन '
पर आप redirected हैं। '' ' # ./spec/controllers/applications_controller_spec।आरबी: 25: ब्लॉक (5 स्तर) में <शीर्ष (आवश्यक)> ' – gaahrdnerमें बस आपके नियंत्रक कोड की समीक्षा की गई थी! और मैंने थोड़ा सा परीक्षण बदल दिया! कोशिश करके देखो! –
दुर्भाग्य से यह या तो काम नहीं करेगा, http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-post के अनुसार। 'सामग्री-प्रकार 'या' स्वीकार करें 'हेडर निर्दिष्ट किए बिना, रेल केवल' टेक्स्ट/html' पर डिफ़ॉल्ट हो जाएंगे। इस कर्ल कथन के समान: 'curl -i -X POST-d '{: application => {: name =>" foo ",: description =>" bar "}}' http: // localhost: 3000/application' – gaahrdner