2013-08-16 5 views
3

С помощью следующего теста токен не считается действительным. В моем ручном тесте он работает, поэтому я пропускаю что-то в том, как создается пароль. Думаю.Тестирование Django 1-5 Сброс формы пароля - как сгенерировать токен для теста?

def test_actual_reset_password(self): 
    new_password = "myNewPassword012*" 
    token_generator = PasswordResetTokenGenerator() 
    user = UserFactory.create() 
    token = token_generator.make_token(user=user) 

    response = self.assert_page_loading(path="/forgot-password/reset/{0}/".format(token)) 
    print response 
    # That loads the page with the error message mentioning that the token was already used   

    # So I cannot carry on: 
    form = response.form 
    form['new_password1'] = new_password 
    form['new_password2'] = new_password 

    response = form.submit() 

В исходном коде Джанго, в PasswordResetForm, я нашел этот код; Я не могу видеть, что разница:

def save(self, ..., token_generator=default_token_generator, ...): 
    """ 
    Generates a one-use only link for resetting password and sends to the 
    user. 
    """ 
    ... 
    for user in self.users_cache: 
     ... 
     c = { 
      ... 
      'token': token_generator.make_token(user), 
      ... 
     } 
     ... 
     send_mail(subject, email, from_email, [user.email]) 

ответ

9

Хорошо, я просто искал информацию о том, как это сделать, и ваш вопрос побудил меня, чтобы понять это сам. Я не уверен, если вы все еще работаем над этим, но вот как я получил его на работу:

from django.core import mail 
# First we get the initial password reset form. 
# This is not strictly necessary, but I included it for completeness 
response = self.c.get(reverse('password_reset')) 
self.assertEqual(response.status_code, 200) 
self.assertEqual(response.template_name, 'authentication/password_reset_form.html') 

# Then we post the response with our "email address" 
response = self.c.post(reverse('password_reset'),{'email':'[email protected]'}) 
self.assertEqual(response.status_code, 302) 
# At this point the system will "send" us an email. We can "check" it thusly: 
self.assertEqual(len(mail.outbox), 1) 
self.assertEqual(mail.outbox[0].subject, 'Password reset on example.com') 

# Now, here's the kicker: we get the token and userid from the response 
token = response.context[0]['token'] 
uid = response.context[0]['uid'] 
# Now we can use the token to get the password change form 
response = self.c.get(reverse('password_reset_confirm', kwargs={'token':token,'uidb64':uid})) 
self.assertEqual(response.status_code, 200) 
self.assertEqual(response.template_name, 'authentication/password_reset_confirm.html') 

# Now we post to the same url with our new password: 
response = self.c.post(reverse('password_reset_confirm', 
    kwargs={'token':token,'uidb36':uid}), {'new_password1':'pass','new_password2':'pass'}) 
self.assertEqual(response.status_code, 302) 

И это все! Не так сложно.

+0

на 'self.assertEqual (LEN (mail.outbox), 1)'. Из какого модуля приходит «почта»? –

+0

нашел его 'django.core.mail' –

+1

Это могло измениться в 1.8. Я получаю ключевую ошибку в response.context [0]? ['token'] – vladblindu

0

Это, как я это сделал для функционального теста:

def test_password_reset_from_key(self): 
    from django.contrib.auth.tokens import default_token_generator 
    from django.utils.http import base36_to_int, int_to_base36 
    user = User.objects.all()[:1].get() 
    token = default_token_generator.make_token(user) 

    self.get("/accounts/password/reset/key/%s-%s/" % (int_to_base36(user.id), token)) 
    self.selenium.find_element_by_name("password1").send_keys("password") 
    self.selenium.find_element_by_name("password2").send_keys("password") 
    self.selenium.find_element_by_name("action").submit() 

    alert = self.selenium.find_element_by_css_selector(".alert-success") 
    self.assertIn('Password successfully changed.', alert.text)