Reputation: 99
I have a test case which first creates a user and then try's to authenticate the created user with Django authenticate() method but looks like password is not getting hashed and therefore it fails to retrieve the token... ill share any code related to this section that i think had to do something with the process.
Custom user model manager:
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
""" Creates and saves a new user """
if not email:
raise ValueError("Users must have an email address.")
user = self.model(
email=self.normalize_email(email),
**extra_fields
)
# Set password this way makes a hashed password
user.set_password(password)
user.save(using=self._db)
return user
app/settings.py:
AUTH_USER_MODEL = "core.User" # 'User' is the name of custom user class
user/serializers.py:
class UserSerializer(serializers.ModelSerializer):
""" Serializer for the users object """
class Meta:
model = get_user_model()
fields = ["email", "password", "name"]
extra_kwargs = {
"password": {
"write_only": True,
"min_length": 5,
}
}
def create(self, validated_data):
""" Create a new user with encrypted password and return it """
user = get_user_model().objects.create(
email=validated_data["email"],
name=validated_data["name"]
)
user.set_password(validated_data["password"])
print(f"from serializer: {user.password}")
user.save()
return user
and at last my test case, user/tests/test_user.py:
#...
def test_create_token_for_user(self):
""" Test that a token is created for the user """
payload = {
"email": "[email protected]",
"password": "testpass"
}
user = get_user_model().objects.create(**payload)
print(user.password) # returns 'testpass' in plain text...
res = self.client.post(TOKEN_URL, payload)
self.assertIn("token", res.data)
self.assertEqual(res.status_code, status.HTTP_200_OK)
Upvotes: 1
Views: 967
Reputation: 476503
You should use create_user
in the test, so:
def test_create_token_for_user(self):
payload = {
'email': '[email protected]',
'password': 'testpass'
}
# use create_user ↓
user = get_user_model().objects.create_user(**payload)
print(user.password)
res = self.client.post(TOKEN_URL, payload)
self.assertIn('token', res.data)
self.assertEqual(res.status_code, status.HTTP_200_OK)
In the serializer you can also work with .create_user()
:
class UserSerializer(serializers.ModelSerializer):
# …
def create(self, validated_data):
user = get_user_model().objects.create_user(
email=validated_data['email'],
name=validated_data['name'],
password=validated_data['password']
)
return user
Upvotes: 2