From b0162305007ba9239170fd2e1fc2b2f190e5d9ec Mon Sep 17 00:00:00 2001 From: Sonny Bakker Date: Sat, 17 Oct 2020 17:08:23 +0200 Subject: [PATCH] Initial API view tests --- src/newsreader/news/collection/endpoints.py | 6 +- .../tests/endpoints/rule/list/tests.py | 232 ++++++++++++------ 2 files changed, 156 insertions(+), 82 deletions(-) diff --git a/src/newsreader/news/collection/endpoints.py b/src/newsreader/news/collection/endpoints.py index 7f2ede0..7b43465 100644 --- a/src/newsreader/news/collection/endpoints.py +++ b/src/newsreader/news/collection/endpoints.py @@ -1,4 +1,4 @@ -from rest_framework import status +from rest_framework import filters, status from rest_framework.generics import ( GenericAPIView, ListAPIView, @@ -19,10 +19,12 @@ class ListRuleView(ListAPIView): queryset = CollectionRule.objects.all() serializer_class = RuleSerializer pagination_class = ResultSetPagination + filter_backends = [filters.SearchFilter] + search_fields = ["name", "screen_name", "url"] def get_queryset(self): user = self.request.user - return self.queryset.filter(user=user).order_by("-created") + return self.queryset.filter(user=user).order_by("name", "screen_name") class DetailRuleView(RetrieveUpdateDestroyAPIView): diff --git a/src/newsreader/news/collection/tests/endpoints/rule/list/tests.py b/src/newsreader/news/collection/tests/endpoints/rule/list/tests.py index 44e3eaa..e5ff2fb 100644 --- a/src/newsreader/news/collection/tests/endpoints/rule/list/tests.py +++ b/src/newsreader/news/collection/tests/endpoints/rule/list/tests.py @@ -1,6 +1,8 @@ import json from datetime import date, datetime, time +from unittest import skip +from urllib.parse import urlencode from django.test import TestCase from django.urls import reverse @@ -8,7 +10,11 @@ from django.urls import reverse import pytz from newsreader.accounts.tests.factories import UserFactory -from newsreader.news.collection.tests.factories import FeedFactory +from newsreader.news.collection.tests.factories import ( + FeedFactory, + SubredditFactory, + TwitterTimelineFactory, +) from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory @@ -23,44 +29,29 @@ class RuleListViewTestCase(TestCase): response = self.client.get(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) self.assertTrue("results" in data) self.assertTrue("count" in data) - self.assertEquals(data["count"], 3) + self.assertEqual(data["count"], 3) def test_ordering(self): - rules = [ - FeedFactory( - created=datetime.combine( - date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc - ), - user=self.user, - ), - FeedFactory( - created=datetime.combine( - date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc - ), - user=self.user, - ), - FeedFactory( - created=datetime.combine( - date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc - ), - user=self.user, - ), - ] + rules = { + "foo": FeedFactory(name="foo", user=self.user), + "bar": FeedFactory(name="bar", user=self.user), + "dar": FeedFactory(name="dar", user=self.user), + } response = self.client.get(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) self.assertTrue("results" in data) self.assertTrue("count" in data) - self.assertEquals(data["count"], 3) + self.assertEqual(data["count"], 3) - self.assertEquals(data["results"][0]["id"], rules[1].pk) - self.assertEquals(data["results"][1]["id"], rules[2].pk) - self.assertEquals(data["results"][2]["id"], rules[0].pk) + self.assertEqual(data["results"][0]["id"], rules["bar"].pk) + self.assertEqual(data["results"][1]["id"], rules["dar"].pk) + self.assertEqual(data["results"][2]["id"], rules["foo"].pk) def test_pagination_count(self): FeedFactory.create_batch(size=80, user=self.user) @@ -70,20 +61,20 @@ class RuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 200) - self.assertEquals(data["count"], 80) - self.assertEquals(len(data["results"]), 30) + self.assertEqual(response.status_code, 200) + self.assertEqual(data["count"], 80) + self.assertEqual(len(data["results"]), 30) def test_empty(self): response = self.client.get(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) self.assertTrue("results" in data) self.assertTrue("count" in data) - self.assertEquals(data["count"], 0) - self.assertEquals(len(data["results"]), 0) + self.assertEqual(data["count"], 0) + self.assertEqual(len(data["results"]), 0) def test_post(self): category = CategoryFactory(user=self.user) @@ -97,29 +88,29 @@ class RuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "POST" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "POST" not allowed.') def test_patch(self): response = self.client.patch(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "PATCH" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "PATCH" not allowed.') def test_put(self): response = self.client.put(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "PUT" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "PUT" not allowed.') def test_delete(self): response = self.client.delete(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "DELETE" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "DELETE" not allowed.') def test_rules_with_unauthenticated_user(self): self.client.logout() @@ -128,7 +119,7 @@ class RuleListViewTestCase(TestCase): response = self.client.get(reverse("api:news:collection:rules-list")) - self.assertEquals(response.status_code, 403) + self.assertEqual(response.status_code, 403) def test_rules_with_unauthorized_user(self): other_user = UserFactory() @@ -137,10 +128,91 @@ class RuleListViewTestCase(TestCase): response = self.client.get(reverse("api:news:collection:rules-list")) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) - self.assertEquals(data["count"], 0) - self.assertEquals(len(data["results"]), 0) + self.assertEqual(data["count"], 0) + self.assertEqual(len(data["results"]), 0) + + +class RuleListViewSearchTestCase(TestCase): + def setUp(self): + self.user = UserFactory(password="test") + self.client.force_login(self.user) + + def test_feed_rules(self): + rules = { + "foo": FeedFactory(name="foo", user=self.user), + "BarFoo": FeedFactory(name="BarFoo", user=self.user), + "FooBar": FeedFactory(name="FooBar", user=self.user), + "boo": FeedFactory(name="boo", user=self.user), + "Boobar": FeedFactory(name="Boobar", user=self.user), + } + + params = urlencode({"search": "foo"}) + url = reverse("api:news:collection:rules-list") + + response = self.client.get(f"{url}?{params}") + response_data = response.json() + + self.assertEqual(response_data["count"], 3) + self.assertEqual(response_data["results"][0]["id"], rules["BarFoo"].pk) + self.assertEqual(response_data["results"][1]["id"], rules["foo"].pk) + self.assertEqual(response_data["results"][2]["id"], rules["FooBar"].pk) + + def test_twitter_profiles(self): + rules = { + "foo": TwitterTimelineFactory( + name="foo", screen_name="foo", user=self.user + ), + "BarFoo": TwitterTimelineFactory( + name="BarFoo", screen_name="foodiddy", user=self.user + ), + "BarFoo dup": TwitterTimelineFactory( + name="BarFoo", screen_name="foodadda", user=self.user + ), + "something else": TwitterTimelineFactory( + name="something else", screen_name="foo", user=self.user + ), + "not found": TwitterTimelineFactory( + name="no result", screen_name="boo", user=self.user + ), + } + + params = urlencode({"search": "foo"}) + url = reverse("api:news:collection:rules-list") + + response = self.client.get(f"{url}?{params}") + response_data = response.json() + + self.assertEqual(response_data["count"], 4) + self.assertEqual(response_data["results"][0]["id"], rules["BarFoo dup"].pk) + self.assertEqual(response_data["results"][1]["id"], rules["BarFoo"].pk) + self.assertEqual(response_data["results"][2]["id"], rules["foo"].pk) + self.assertEqual(response_data["results"][3]["id"], rules["something else"].pk) + + def test_subreddits(self): + rules = { + "foo": SubredditFactory(name="foo", user=self.user), + "BarFoo": SubredditFactory(name="BarFoo", user=self.user), + "FooBar": SubredditFactory(name="FooBar", user=self.user), + "boo": SubredditFactory(name="boo", user=self.user), + "Boobar": SubredditFactory(name="Boobar", user=self.user), + } + + params = urlencode({"search": "foo"}) + url = reverse("api:news:collection:rules-list") + + response = self.client.get(f"{url}?{params}") + response_data = response.json() + + self.assertEqual(response_data["count"], 3) + self.assertEqual(response_data["results"][0]["id"], rules["BarFoo"].pk) + self.assertEqual(response_data["results"][1]["id"], rules["foo"].pk) + self.assertEqual(response_data["results"][2]["id"], rules["FooBar"].pk) + + @skip("TODO") + def test_ratelimitting(self): + pass class NestedRuleListViewTestCase(TestCase): @@ -157,11 +229,11 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) self.assertTrue("results" in data) self.assertTrue("count" in data) - self.assertEquals(data["count"], 5) + self.assertEqual(data["count"], 5) def test_pagination(self): rule = FeedFactory.create(user=self.user) @@ -178,11 +250,11 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 200) - self.assertEquals(data["count"], 80) - self.assertEquals(len(data["results"]), 30) + self.assertEqual(response.status_code, 200) + self.assertEqual(data["count"], 80) + self.assertEqual(len(data["results"]), 30) - self.assertEquals( + self.assertEqual( [post["id"] for post in data["results"]], [post.id for post in posts[:30]] ) @@ -194,16 +266,16 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 200) - self.assertEquals(data["count"], 0) - self.assertEquals(len(data["results"]), 0) + self.assertEqual(response.status_code, 200) + self.assertEqual(data["count"], 0) + self.assertEqual(len(data["results"]), 0) def test_not_known(self): response = self.client.get( reverse("api:news:collection:rules-nested-posts", kwargs={"pk": 0}) ) - self.assertEquals(response.status_code, 404) + self.assertEqual(response.status_code, 404) def test_post(self): rule = FeedFactory.create(user=self.user) @@ -215,8 +287,8 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "POST" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "POST" not allowed.') def test_patch(self): rule = FeedFactory.create(user=self.user) @@ -228,8 +300,8 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "PATCH" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "PATCH" not allowed.') def test_put(self): rule = FeedFactory.create(user=self.user) @@ -241,8 +313,8 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "PUT" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "PUT" not allowed.') def test_delete(self): rule = FeedFactory.create(user=self.user) @@ -254,8 +326,8 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 405) - self.assertEquals(data["detail"], 'Method "DELETE" not allowed.') + self.assertEqual(response.status_code, 405) + self.assertEqual(data["detail"], 'Method "DELETE" not allowed.') def test_rule_with_unauthenticated_user(self): self.client.logout() @@ -266,7 +338,7 @@ class NestedRuleListViewTestCase(TestCase): reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}) ) - self.assertEquals(response.status_code, 403) + self.assertEqual(response.status_code, 403) def test_rule_with_unauthorized_user(self): other_user = UserFactory() @@ -276,7 +348,7 @@ class NestedRuleListViewTestCase(TestCase): reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk}) ) - self.assertEquals(response.status_code, 403) + self.assertEqual(response.status_code, 403) def test_posts_ordering(self): rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user)) @@ -310,14 +382,14 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) self.assertTrue("results" in data) self.assertTrue("count" in data) - self.assertEquals(data["count"], 3) + self.assertEqual(data["count"], 3) - self.assertEquals(data["results"][0]["id"], posts[1].pk) - self.assertEquals(data["results"][1]["id"], posts[2].pk) - self.assertEquals(data["results"][2]["id"], posts[0].pk) + self.assertEqual(data["results"][0]["id"], posts[1].pk) + self.assertEqual(data["results"][1]["id"], posts[2].pk) + self.assertEqual(data["results"][2]["id"], posts[0].pk) def test_only_posts_from_rule_are_returned(self): rule = FeedFactory.create(user=self.user) @@ -331,14 +403,14 @@ class NestedRuleListViewTestCase(TestCase): ) data = response.json() - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) self.assertTrue("results" in data) self.assertTrue("count" in data) - self.assertEquals(data["count"], 5) + self.assertEqual(data["count"], 5) for post in data["results"]: - self.assertEquals(post["rule"], rule.pk) + self.assertEqual(post["rule"], rule.pk) def test_unread_posts(self): rule = FeedFactory.create(user=self.user) @@ -354,11 +426,11 @@ class NestedRuleListViewTestCase(TestCase): data = response.json() posts = data["results"] - self.assertEquals(response.status_code, 200) - self.assertEquals(data["count"], 10) + self.assertEqual(response.status_code, 200) + self.assertEqual(data["count"], 10) for post in posts: - self.assertEquals(post["read"], False) + self.assertEqual(post["read"], False) def test_read_posts(self): rule = FeedFactory.create(user=self.user) @@ -374,8 +446,8 @@ class NestedRuleListViewTestCase(TestCase): data = response.json() posts = data["results"] - self.assertEquals(response.status_code, 200) - self.assertEquals(data["count"], 10) + self.assertEqual(response.status_code, 200) + self.assertEqual(data["count"], 10) for post in posts: - self.assertEquals(post["read"], True) + self.assertEqual(post["read"], True)