2016-03-23 17 views
2

ログインしていないときにユーザが/amosにアクセスしようとすると、/accounts/login/?next=/amos/にリダイレクトされるはずのビューがあります。これをテストするために、 :Djangoのテストクライアントが正しくエンコードされていないURLを返します

import urllib 

# I actually define this function elsewhere, I placed it here for brevity's sake 
def url_with_querystring(path, **kwargs): 
    return path + '?' + urllib.urlencode(kwargs) 

def setUp(self): 
    self.client = Client() 

def test_call_view_denies_anonymous(self): 
    target_url = reverse('amos_index') 
    redirect_url = url_with_querystring(reverse('login'), next='/amos/') 
    response = self.client.get(target_url, follow=True) 
    self.assertRedirects(response, redirect_url) 
    response = self.client.post(target_url, follow=True) 
    self.assertRedirects(response, redirect_url) 

self.assertRedirects(response, redirect_url)でエラーが発生します。具体的には、このエラーが発生します。

AssertionError: Response redirected to '/accounts/login/?next=/amos/', expected '/accounts/login/?next=%2Famos%2F' 

明らかに、エラーが/%2Fに等しくないから来ています。 responseによって返されたリダイレクトURLは生の文字列であるように見えますが、自己定義関数は適切にURLでエンコードされた文字列を返します。この場合、私は何をすべきですか? URLをエンコードしないといいですか、これはdjango.test.clientの問題ですか?

EDIT:DjangoProjectウェブサイトで以前に募集したbugを読んだことがあります。私が理解したことから、これは意図された行動であると思われますか?つまり、Djangoの内部システムでは、URLはエンコードされません。より経験豊富な人からいくつかの洞察をしたいと思います、ありがとう!

答えて

2

login_requiredのようなデコレータで使用されるDjangoのredirect_to_loginメソッドを見ると、スラッシュを安全な文字として扱い、それらをエンコードしていないことがわかります。

login_url_parts[4] = querystring.urlencode(safe='/') 

あなたのテストでは、この動作を模倣することができます。しかし、私はそれが単に文字列をurlencodeしない方が簡単だろうと思います。テストする重要なことは、匿名ユーザーがリダイレクトされることです。 DjangoでURLが適切にエンコードされていることを確認するためのテストが既に行われているはずですので、これを繰り返すことで多くのことを確かめることはできません。

redirect_url = reverse('login') + '?next=/amos/' 
+0

よろしくお願いします。これをクリアしてくれてありがとう! –

+0

これを繰り返すと、EDIT: 'redirect_to_login'メソッドは、スラッシュ(*)を除くすべての*を適切にURLエンコードします。(私は、これを繰り返すために、私は' url_with_querystring() '関数の動作を模倣します。それを '!'でテストしました)。なぜこれが当てはまるのか知っていますか@Alasdair? –

+0

URLエンコードされたクライアントではありません。ビュー上で使用しているデコレータによって呼び出されるのは 'redirect_to_login'メソッドです。 – Alasdair

関連する問題