pfaffman
(Jay Pfaffman)
3월 30, 2020, 4:33오후
1
며칠 전부터 실패하기 시작한 스펙이 있습니다. 시간대(timzone) 관련 문제인 것 같습니다. 제 플러그인의 문제라고 생각되지 않지만, 제가 놓치고 있는 것이 있을까요?
require 'rails_helper'
describe TopicDefaultTag::ActionsController do
before do
Jobs.run_immediately!
end
it 'can list' do
sign_in(Fabricate(:user))
get "/topic-default-tag/list.json"
expect(response.status).to eq(200)
end
end
Running Rspec: plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb
Loading plugins while running specs
An error occurred while loading ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb.
Failure/Error: UserOption.create!(user_id: id)
NoMethodError:
undefined method `timezone' for #<UserOption:0x000055dd7af16ca8>
Did you mean? timeout
# ./app/models/user.rb:1343:in `create_user_option'
# (eval):19:in `block (2 levels) in run_file'
# ./spec/rails_helper.rb:79:in `<top (required)>'
# ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb:1:in `require'
# ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb:1:in `<top (required)>'
No examples found.
Finished in 0.00005 seconds (files took 3.52 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples
david
(David Taylor)
3월 30, 2020, 4:35오후
2
user_options 테이블에 timezone 컬럼이 누락된 것 같습니다. 테스트 데이터베이스에서 최근 마이그레이션을 실행해 보셨나요? RAILS_ENV=test bin/rake db:migrate
pfaffman
(Jay Pfaffman)
3월 30, 2020, 4:43오후
3
아니, 아니요! 아니요. 개발 데이터베이스에는 마이그레이션을 실행했지만, 테스트 데이터베이스에는 실행하지 않았습니다. 감사합니다, 데이비드!
지금 무슨 일이 일어나고 있는지 이해가 되지 않지만, 아마도 이 문제만큼 초보적인 수준은 아닐 겁니다.
david
(David Taylor)
3월 30, 2020, 4:47오후
4
마이그레이션이 누락된 경우 메시지가 표시되어야 합니다.
하지만 이는 rails_helper를 사용 중일 때만 작동합니다. 스펙 파일 상단에 require "rails_helper"를 추가해야 할 것 같습니다. 이렇게 하면 현재 보고 계신 다른 문제들도 해결될 수 있습니다.
수정: 음… 수동으로 추가할 필요가 없도록 .rspec 파일에 --require rails_helper를 추가하는 것이 좋을까요
pfaffman
(Jay Pfaffman)
3월 30, 2020, 5:07오후
5
저런 실수를 저지르는 건 제 스타일이긴 하네요! 아쉽지만 require 'rails_helper'는 이미 있습니다.
bundle exec rake autospec 대신 ./bin/rake autospec을 실행한 것이 문제였을 수도 있지만, 트래비스에서는 여전히 실패하고 있습니다. 그리고 제 작은 스펙 하나를 위해 이 스펙이 제가 이해하지 못하는 일들을 잔뜩 하고 있는 것 같지만, 그냥 지켜보겠습니다.
다시 한번 감사합니다.
sign_in 헬퍼 함수에서 문제가 발생하고 있습니다. 도움을 많이 부탁드립니다! :
password_confirmation: honeypot,
challenge: challenge.reverse
}
expect(response.status).to eq(200)
body = response.parsed_body
User.find(body["user_id"])
end
def sign_in(user)
get "/session/#{user.encoded_username}/become"
user
end
def sign_out
delete "/session"
end
def read_secure_session
id = begin
이 테스트에서 사용할 때 current_user가 반환되지 않는 것 같으며, 200 대신 403 오류가 발생합니다.
it "followers" do
get "/u/#{user2[:username]}/follow/followers.json", :params => { :type => 'followers' }
expect(response.status).to eq(200)
expect(response.parsed_body[0]['id']).to eq(user1.id)
expect(response.parsed_body[0]['username']).to eq(user1.username)
end
end
it "updates followers" do
sign_in(user1)
put "/follow/#{user2.username}.json", params: { follow: true }
expect(response.status).to eq(200)
expect(response.parsed_body['following']).to eq(true)
end
end
문제를 분리하기 위해 다음과 같이 테스트를 실행하고 있지만, 어떤 경우에도 작동하지 않습니다:
LOAD_PLUGINS=1 RAILS_ENV=test rspec plugins/discourse-follow/spec/requests/follow_controller_spec.rb:32
해당 컨트롤러에 byebug를 추가하고 current_user를 확인해 보니 nil 값이 반환됩니다(이것이 403 오류의 원인인 것 같습니다!):
class Follow::FollowController < ApplicationController
def index
end
def update
params.require(:username)
params.require(:follow)
raise Discourse::InvalidAccess.new unless current_user
raise Discourse::InvalidParameters.new if current_user.username == params[:username]
if user = User.find_by(username: params[:username])
updater = Follow::Updater.new(current_user, user)
updater.update(params[:follow])
following = user.followers.include?(current_user.id.to_s)
render json: success_json.merge(following: following)
else
Randomized with seed 50945
[5, 14] in /home/merefield/code/discourse-follow/app/controllers/follow/follow_controller.rb
5: def update
6: params.require(:username)
7: params.require(:follow)
8: byebug
9:
=> 10: raise Discourse::InvalidAccess.new unless current_user
11: raise Discourse::InvalidParameters.new if current_user.username == params[:username]
12:
13: if user = User.find_by(username: params[:username])
14: updater = Follow::Updater.new(current_user, user)
(byebug) current_user
nil
pfaffman
(Jay Pfaffman)
8월 23, 2021, 12:22오후
7
그 위에 해당 사용자를 생성하는 이 있나요? (정확한 이름이나 방법을 기억할 정도로 능숙하지는 않아요. 아, fabricator였나? 그 사용자를 fabricate한 건가요?
(혹시 제가 못 본 건지도 모르겠어요. 지금 휴대폰으로 보고 있으니까요)
네, 사용자는 생성되었습니다. 사용자 객체가 인스턴스화되었어요. 문제는 sign_in 메서드 내부이거나 환경 관련 문제일까요? (하지만 그건 제어되어야 하죠)
추가 조사 결과, 다음과 같은 사항을 발견했습니다:
def current_user (discourse/lib/auth/default_current_user_provider.rb at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub )에서
@env.key?(CURRENT_USER_KEY)가 true입니다.
따라서 current_user는 @env[CURRENT_USER_KEY]의 값을 가져옵니다.
그러나 테스트 실행 중 컨트롤러에서 이 줄이 호출될 때 그 값은 nil입니다:
def update
params.require(:username)
params.require(:follow)
raise Discourse::InvalidAccess.new unless current_user
왜 스펙 내에서 사용자를 로그인시킨 후에도 @env[CURRENT_USER_KEY]가 nil일까요?
테스트 실행 중 current_user가 하나의 테스트 내에서 여러 번 호출되는 것을 확인했습니다. 어떤 시점에서는 이 속성에 값이 있지만, 모든 호출에서 그런 것은 아니며, 중요한 순간에는 값이 없습니다.
david
(David Taylor)
8월 24, 2021, 4:02오후
10
현재 current_user 객체에 간섭을 일으킬 수 있는 다른 플러그인이 설치되어 있나요? discourse-follow를 클론했는데, 제 환경에서는 해당 스펙이 정상적으로 통과됩니다:
❯ LOAD_PLUGINS=1 bin/rspec plugins/discourse-follow/spec/requests/follow_controller_spec.rb
Randomized with seed 28704
...
Finished in 0.45075 seconds (files took 3.34 seconds to load)
3 examples, 0 failures
Randomized with seed 28704
아, 확인해 줘서 고마워, 데이비드! 내 개발 환경에 뭔가 특이한 점이 있는 것 같네!
번들된 플러그인과 데이터 탐색기를 제외하고는 다른 플러그인은 설치되어 있지 않지만, 네게는 잘 작동한다고 하니, 새로고장난 도커 개발 인스턴스를 설정해서 거기서 성공적으로 실행할 수 있는지 한번 해볼까 해. 고마워!
네, docker dev에서 작동했어요:
d/rake plugin:spec["discourse-follow"]
감사합니다!!