【问题标题】:confirmation link in Rails test environment renders: Forbidden You don't have permission to access /users/confirmation on this serverRails 测试环境中的确认链接呈现: Forbidden You don't have permission to access /users/confirmation on this server
【发布时间】:2018-11-03 22:40:23
【问题描述】:

我有一个使用devise :confirmableUser 类,它在创建用户时触发包含确认链接的电子邮件发送。这在developmentproduction 中完美运行,但在test 环境(Minitest / Capybara)中失败。具体来说,点击确认链接会生成**Forbidden** You don't have permission to access /users/confirmation on this server

截图:

Forbidden You don't have permission to access /users/confirmation on this server

奇怪的是,当我从 rails console 创建用户时,就像我在集成测试中所做的那样,它可以工作。那么,为什么在test 环境下会失败呢?

测试:

u = FactoryBot.create(:user)
email = ActionMailer::Base.deliveries.last
plain_part = email.multipart? ? (email.text_part ? email.text_part.body.decoded : nil) : email.body.decoded
confirmation_link = plain_part[/<a href="(http:\/\/.*)">Confirm my account<\/a>/,1]
puts "--- #{confirmation_link} ---" # visual check of extracted URL
visit confirmation_link # Forbidden You don't have permission...
save_and_open_screenshot # saves to tmp/capybara/capybara-*.png

在控制台:

require 'factory_bot'
# factory creation code omitted from here
u = FactoryBot.create(:user)
# produces and renders link

这种确认链接在除test之外的所有环境中都是这样的:

http://localhost:3000/users/confirmation?confirmation_token=TxYdRmVzcuPE7PAx7yJh

...在test 中,它们看起来像这样:

http://localhost/users/confirmation?confirmation_token=NqyaVL5EKEnz46zMzDQs

test 中未指定端口。)

我在这些集成测试中使用Rails 5.2.0 和Capybara 驱动程序selenium_chrome_headless

【问题讨论】:

  • 您使用的是什么版本的 Rails,以及您在 Capybara 中使用的驱动程序?另外 - 确认链接将指向端口 3000 - 您实际上是在端口 3000 上运行您的测试服务器吗?通常是开发服务器
  • 哇!非常感谢。你的想法是对的……它与端口有关!通过将Capybara.server_port = '3000' 添加到test/test_helper.rb,并通过confirmation_link.gsub!(/localhost/,"localhost:#{Capybara.server_port}") 修改(在集成测试中)电子邮件生成的URL,它立即起作用。后者感觉不是一个长期的解决方案,因为猴子补丁似乎很脆弱,但它确实证实了这个问题。理想情况下,生成的 URL 将使用提供的端口号。也许您可以在这方面提出建议?无论哪种方式,请提供答案,我会接受!
  • ...或者也许有一种不同且更好的方法来执行此操作...例如以某种方式获取生成的 URL 以包含当前端口号(因为我看到它随着每次测试运行而变化。 .. 例如Listening on tcp://127.0.0.1:60770Listening on tcp://127.0.0.1:60127Listening on tcp://127.0.0.1:58623)。

标签: ruby-on-rails capybara factory-bot minitest


【解决方案1】:

这是因为电子邮件中生成的 URL 没有指向 Capybara 服务器。有几种方法可以解决这个问题。两个最简单的解决方案是

  1. 修复 Capybara 运行其测试服务器的端口并设置电子邮件生成参数

    Capybara.server_port = 1111 # any fixed port number
    
    # in config/environments/test.rb
    config.action_mailer.default_url_options = {:host => 'localhost', port: '1111'} # match whatever server host and port Capybara is running on
    
  2. 继续允许 Capybara 在随机端口上运行,配置 url 生成不包含端口,并将 Capybara 设置为在未明确指定其他端口时始终包含服务器端口

    Capybara.always_include_port = true
    
    # in config/environments/test.rb
    config.action_mailer.default_url_options = {:host => 'localhost'} # match the host Capybara is running the test server on
    

【讨论】:

  • 谢谢你!直到现在,我才从这项任务中脱轨。我尝试了上面的选项 1,但它不起作用;另外,您不是要使用引号(Capybara.server_port = '1111' )吗?我尝试了带引号和不带引号,均无济于事。选项 2 确实有效 - 所以谢谢你。但是知道为什么选项 1 不起作用吗?并且:设置Capybara.server_port = '3000' 有什么问题(即使用与开发相同的端口)......可能会出现什么问题/症状?
  • @user664833 不知道为什么选项 1 不适合您 - 检查电子邮件中生成的 url 并查看它们是否正确。至于 3000 端口——如果您将 Capybara 设置为在 3000 端口上运行测试,那么您将无法在测试运行时继续在您的开发实例上进行开发。
  • 我终于让选项 1 起作用了。我最终从之前的调试中找到了一条旧线(在获得您的帮助之前),而那条旧线只是在洗牌中迷路了,碰巧在这里挡住了路。无论如何,既然我得到了选项 1 的工作,我可以确认 server_port 是否有引号并不重要。可以写成Capybara.server_port = '1111'Capybara.server_port = 1111
猜你喜欢
  • 2017-12-25
  • 2011-06-15
  • 2014-03-29
  • 2016-04-15
  • 2014-06-04
  • 1970-01-01
  • 2014-05-19
  • 2019-02-20
  • 1970-01-01
相关资源
最近更新 更多