I have an app that can send/cancel/accept/delete
friend requests and I am trying to test it, however when I'm accepting a friend request and adding users to each others friends lists I am getting a Failed lookup for key [user] in <User: test>
exception.
In my test I create a friend request object and send an accept get
request to the view which should add each one of the users to each one of their friends lists and delete the friend_request
.
Debugging shows that the error happens after this line in the view: user1.friends.add(user2)
, so essentially user2
is being added to user1
friends list but adding user1
to user2
friends list throws the exception that was mentioned above.
models.py
class User(AbstractBaseUser, PermissionsMixin):
name = models.CharField('Full Name', max_length=35, unique=True,
null=False,
blank=False)
friends = models.ManyToManyField("User", blank=True)
def __str__(self):
return self.name
class FriendRequest(models.Model)
to_user = models.ForeignKey(User, related_name='to_user',
on_delete=models.CASCADE)
from_user = models.ForeignKey(User, related_name='from_user',
on_delete=models.CASCADE)
views.py
from django.db import transaction
def accept_friend_request(request, pk):
try:
with transaction.atomic():
from_user = User.objects.get(pk=pk)
f_request = FriendRequest.objects.filter(
from_user=from_user,
to_user=request.user
).first()
user1 = f_request.to_user
user2 = from_user
user1.friends.add(user2)
print(user1.friends.all())
user2.friends.add(user1)
print(user2.friends.all())
f_request.delete()
return redirect(request.get_full_path())
except Exception as ex:
print(ex)
return HttpResponse('User does not exist')
Here I am using the transaction.atomic()
to prevent the exception from breaking the unittest transaction.
tests.py
def setUp(self):
self.client = Client()
self.user = User.objects.create_user(email='[email protected]',
name='test',
password='test')
self.user1 = User.objects.create_user(email='[email protected]',
name='test1',
password='test1')
self.client.force_login(self.user)
def test_accept_friend_request(self):
friend_request = FriendRequest.objects.create(from_user=self.user1,
to_user=self.user)
self.client.get(reverse('accept_friend_request',
kwargs={'pk': self.user1.pk}), follow=True)
self.assertIn(self.user, self.user1.friends.all())
self.assertIn(self.user1, self.user.friends.all())
Here is the result of running the test: (You can also see the result of the first print statement and the exception being printed)
Ran 1 test in 1.266s
FAILED (failures=1)
Destroying test database for alias 'default'...
System check identified no issues (0 silenced).
<QuerySet [<User: test1>]>
Failed lookup for key [user] in <User: test>
UPDATE
changing Exception to IntegrityError resulted in the following error:
raise VariableLookupError(django_elasticsearch_dsl.exceptions.VariableLookupError:
Failed lookup for key [user] in <User: test>
looks like elasticsearch-dsl has something to do with the exception here.
UPDATE
When debugging exception message changes to
Failed lookup for key [name] in <FriendRequest: FriendRequest object (1)>
So I finally managed to make it run correctly by changing the redirect to request.META.get('HTTP_REFERER', '/')
, looks like it had problems with redirect looping.