2016-03-23 25 views
2

Oturum açılmadığında bir kullanıcı /amos erişmeye çalıştığında, /accounts/login/?next=/amos/ yönlendirmesi beklenen bir görünüm var. Bunu sınamak için, aşağıdaki sınamayı kullanıyorum :Django'nun test istemcisi düzgün olmayan bir kodlanmış URL döndürüyor

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) 

Hata, self.assertRedirects(response, redirect_url) ile oluşur. Özellikle, bu hata yükseltir:

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

Açıkçası, hata /%2F eşit olmama geliyor. response tarafından döndürülen yönlendirme URL'si sadece ham bir dize gibi görünürken, kendi tanımladığınız işlev düzgün bir şekilde URL kodlu bir dize döndürür. Bu durumda ne yapmalıyım? URL kodlama yapmamalı mıyım yoksa django.test.client ile ilgili bir sorun mu var?

DÜZGÜN: DjangoProject web sitesinde daha önce yükseltilmiş bir bug okudum. Anladığım kadarıyla, bu amaçlanan davranış gibi görünüyor? Yani, Django'nun iç sistemlerinde, URL'ler kodlanmaz. Daha deneyimli insanlardan biraz anlayış isterim, teşekkürler!

cevap

2

Dinkgo's login_required gibi dekoratörler tarafından kullanılan redirect_to_login yöntemine bakarsanız, eğik çizgileri güvenli bir karakter olarak nitelendirir ve onları kodlamadığını görebilrsiniz.

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

Bu davranışı sınamada taklit edebilirsiniz. Ancak, dize sadece kod yazmak için en kolay olacağını düşünüyorum. Sınamak için önemli olan, anonim kullanıcıların yönlendirilmesidir. Django'da, url'nin uygun şekilde kodlandığından emin olmak için testler yapılmalıdır, dolayısıyla bunu tekrar ederek kazanacak çok şey olduğundan emin değilim.

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

Ooh, güzel yakalama! Bunu benim için açtığın için teşekkürler! 'Url_with_querystring() 'fonksiyonundaki davranışı taklit edeceğimi düşünüyorum (geleceğin kanıtı için) –

+0

Sadece tekrarlamak için, EDIT:' redirect_to_login' metodu düzgün URL her şeyi kodlar * hariç * eğik çizgi (I) '!' ile test etti. Neden böyle olduğunu biliyor musun, @Alasdair? –

+0

Url kodlaması yapan istemci değil - görünümünüzde kullandığınız dekoratör tarafından çağrılan 'redirect_to_login' yöntemidir. – Alasdair