繁体   English   中英

Devise、cucumber 和水豚未对 JSON 请求进行身份验证

[英]Devise, cucumber, and capybara not authenticating on JSON request

我正在使用带导轨的 backbone.js。 我的 controller 接受并返回 JSON。 在添加 devise 身份验证之前,我的所有测试都运行良好。 我无法让 cucumber 保持身份验证。

我已经尝试了所有提到的:

  • devise 维基
  • 这里- 标准登录(转到页面,填写表格,单击按钮),设置 cookie 并在过滤器之前有一个特殊应用程序,执行后者但在机架中(甚至无法运行)
  • 使用此 set_cookie 方法执行上述 cookie/before_filter

一切都无济于事。 登录返回正常(200),但是当我发送请求时,我得到 401 响应。

这是我的 controller 代码:

class ContactsController < ApplicationController
  before_filter :authenticate_user!

  ### backbone
  def index
    render :json => current_user.person.contacts
  end

  def show
    render :json =>  current_user.person.contacts.find(params[:id])
  end

  def create
    contact = current_user.person.contacts.create! params
    render :json => contact
  end

  def update
    contact =  current_user.person.contacts.find(params[:id])
    contact.update_attributes! params
    render :json => contact
  end

 def destroy
    contact =  current_user.person.contacts.find(params[:id]) 
    contact.destroy
    render :json => contact  #TODO: change to render nothing
  end

这是一个 cucumber 功能:

Scenario: View contacts
Given I am logged in as "testy@testing.com"
And I send and accept JSON
And the following contacts:
  |name|
  |name 1|
  |name 2|
  |name 3|
  |name 4|
When I send a GET request for "/contacts"
Then the response should be "200"
And the JSON response should be an array with 4 "name" elements
And I should get the following contacts:
  |name|
  |name 1|
  |name 2|
  |name 3|
  |name 4|

JSON 方法直接使用 Rack。 我怀疑这是我的问题所在,但我不知道如何克服它。

这是cuke JSON步骤:

World(Rack::Test::Methods)

Given /^I send and accept JSON$/ do
  header 'Accept', 'application/json'
  header 'Content-Type', 'application/json'
end

When /^I send a GET request for "([^\"]*)"$/ do |path|
  get path
end

When /^I send a POST request to "([^\"]*)" with the following:$/ do |path, table|
  params = table.hashes.flatten[0].to_json
  post path, params
end

When /^I send a PUT request to "([^\"]*)" with the following:$/ do |path, table|
  params = table.hashes.flatten[0].to_json
  put path, params
end

When /^I send a DELETE request to "([^\"]*)"$/ do |path|
  delete path
end

Then /^the response should be "([^\"]*)"$/ do |status|
  last_response.status.should == status.to_i
end

Then /^the JSON response should have 1 "([^\"]*)" element$/ do |name|
  page = JSON.parse(last_response.body)
  page[name].should be
end

Then /^the JSON response should be an array with (\d+) "([^\"]*)" elements$/ do |number_of_children, name|
  page = JSON.parse(last_response.body)
  page.map { |d| d[name] }.length.should == number_of_children.to_i
end

Your Cuke looks like a RSpec test really... Since you're not actually rendering anything except direct output from the controller, I usually skip the heavier Cuke tests for more nimble RSpec tests. Cuke 用于集成,通常测试 controller 并查看一系列推动业务成果的场景。

关键问题可能在于:

Given I am logged in as "testy@testing.com"

我不确定那是做什么的。 如果它只是显示一个登录表单并且什么都不做,你会得到一个 200。如果你想解决这个问题,请逐步完成登录步骤,并确保在你点击帖子时你有一个 user_session/接电话。

user_signed_in?.should be_true
current_user.should_not be_nil
user_session.should_not be_nil

如果您只想简单地测试单个 controller 操作的直接结果,请尝试使用 RSpec。

这是我在 RSpec 中的 controller 的示例规格:(我能找到的最小的带有身份验证的)

require "spec_helper"

describe GuestsController do
  include Devise::TestHelpers

  let(:user) { Factory(:user) }

  context "#create" do
    it "should create an anonymous user" do
      User.should_receive(:anonymous!).and_return(user)

      post :create

      response.should redirect_to(meals_path)
    end

    it "should not create a user" do
      User.should_not_receive(:anonymous!)

      sign_in user
      post :create

      response.should redirect_to(meals_path)
    end
  end
end

如果您不想调用 sign_in,您甚至可以取消身份验证

before do
  request.env['warden'] = mock(Warden, authenticate: mock_user,
                                       authenticate!: mock_user)
end

祝你好运。 debugger是你的朋友!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM