Rspec 检测设备
Rspec for Detecting devises
这是我的任务
1) 创建新路由localhost:3000/设备
2) 考虑如果这个 url 是从手机或桌面浏览器点击的,那么
3) 跟踪 system/device(iOS、android、网络),从中点击 URL
4) 根据发出请求的设备,我们需要重定向到其他URL(例如,iOS ——> “iOS app store” , android ——> “Android play store”, web ——> “google page”)
5) 找出可用于跟踪发出请求的系统的不同方法是什么,哪种方法最好实施,为什么?
在这里我找到了一个解决方案,但是在rspec中它导致了错误。
这是我的路线
get :devise, to: 'topics#devise'
这是我的控制器
class TopicsController < ApplicationController
def devise
if request.env['HTTP_USER_AGENT'].downcase.match(/mac/i)
redirect_to 'https://itunes.apple.com/us/app/apple-store/id375380948?mt=8'
elsif request.env['HTTP_USER_AGENT'].downcase.match(/windows/i)
redirect_to 'https://www.microsoft.com/en-in/store/apps/windows'
elsif request.env['HTTP_USER_AGENT'].downcase.match(/android/i)
redirect_to 'https://play.google.com/store?hl=en'
else
redirect_to root_path
end
end
end
当我点击 url lvh.me:3000/devise
时,它会重定向到相应的应用商店。
这是我的控制器规格
context 'devise' do
it 'should detect the device' do
get :devise
response.should redirect_to '/https://www.microsoft.com/en-in/store/apps/windows'
end
end
这导致了错误:
Expected response to be a redirect to http://test.host/https://www.microsoft.com/en-in/store/apps/windows but was a redirect to http://test.host/.
Expected "http://test.host/https://www.microsoft.com/en-in/store/apps/windows" to be === "http://test.host/".
如果我做错了,请提出一些建议rspec
如果您的 rails 版本在控制器中不是太旧,您可以使用 request.user_agent
(无论如何它都会查看 env,但这会使代码更清晰)
浏览器在 header User-agent
中传递用户代理(最终进入机架环境),因此您需要在测试中模拟这一点。
为了对此进行测试,我建议使用请求规范而不是控制器规范(在 rails 5 中已弃用):
RSpec.describe 'Topics...', type: :request do
it "redirects for ios" do
get '/your/topcis/path/here', headers: { 'HTTP_USER_AGENT' => 'iPhone' }
expect(response).to redirect_to(/\.apple\.com/)
end
end
(上面使用 rails 5,对于旧的 rails headers 将只是散列,而不是关键字参数)
您也可以使用 case
语句编写您的方法:
def devise
redirect_to case request.user_agent.downcase
when /mac/i then 'https://itunes.apple.com/us/app/apple-store/id375380948?mt=8'
when /windows/i then 'https://www.microsoft.com/en-in/store/apps/windows'
when /android/i then 'https://play.google.com/store?hl=en'
else
root_path
end
end
这是我的任务
1) 创建新路由localhost:3000/设备
2) 考虑如果这个 url 是从手机或桌面浏览器点击的,那么
3) 跟踪 system/device(iOS、android、网络),从中点击 URL
4) 根据发出请求的设备,我们需要重定向到其他URL(例如,iOS ——> “iOS app store” , android ——> “Android play store”, web ——> “google page”)
5) 找出可用于跟踪发出请求的系统的不同方法是什么,哪种方法最好实施,为什么?
在这里我找到了一个解决方案,但是在rspec中它导致了错误。
这是我的路线
get :devise, to: 'topics#devise'
这是我的控制器
class TopicsController < ApplicationController
def devise
if request.env['HTTP_USER_AGENT'].downcase.match(/mac/i)
redirect_to 'https://itunes.apple.com/us/app/apple-store/id375380948?mt=8'
elsif request.env['HTTP_USER_AGENT'].downcase.match(/windows/i)
redirect_to 'https://www.microsoft.com/en-in/store/apps/windows'
elsif request.env['HTTP_USER_AGENT'].downcase.match(/android/i)
redirect_to 'https://play.google.com/store?hl=en'
else
redirect_to root_path
end
end
end
当我点击 url lvh.me:3000/devise
时,它会重定向到相应的应用商店。
这是我的控制器规格
context 'devise' do
it 'should detect the device' do
get :devise
response.should redirect_to '/https://www.microsoft.com/en-in/store/apps/windows'
end
end
这导致了错误:
Expected response to be a redirect to http://test.host/https://www.microsoft.com/en-in/store/apps/windows but was a redirect to http://test.host/.
Expected "http://test.host/https://www.microsoft.com/en-in/store/apps/windows" to be === "http://test.host/".
如果我做错了,请提出一些建议rspec
如果您的 rails 版本在控制器中不是太旧,您可以使用 request.user_agent
(无论如何它都会查看 env,但这会使代码更清晰)
浏览器在 header User-agent
中传递用户代理(最终进入机架环境),因此您需要在测试中模拟这一点。
为了对此进行测试,我建议使用请求规范而不是控制器规范(在 rails 5 中已弃用):
RSpec.describe 'Topics...', type: :request do
it "redirects for ios" do
get '/your/topcis/path/here', headers: { 'HTTP_USER_AGENT' => 'iPhone' }
expect(response).to redirect_to(/\.apple\.com/)
end
end
(上面使用 rails 5,对于旧的 rails headers 将只是散列,而不是关键字参数)
您也可以使用 case
语句编写您的方法:
def devise
redirect_to case request.user_agent.downcase
when /mac/i then 'https://itunes.apple.com/us/app/apple-store/id375380948?mt=8'
when /windows/i then 'https://www.microsoft.com/en-in/store/apps/windows'
when /android/i then 'https://play.google.com/store?hl=en'
else
root_path
end
end