diff --git a/src/newsreader/accounts/templates/accounts/views/integrations.html b/src/newsreader/accounts/templates/accounts/views/integrations.html
index 8bb0b2e..4429f02 100644
--- a/src/newsreader/accounts/templates/accounts/views/integrations.html
+++ b/src/newsreader/accounts/templates/accounts/views/integrations.html
@@ -44,8 +44,8 @@
Twitter
- {% if twitter_request_url %}
-
{% else %}
diff --git a/src/newsreader/accounts/tests/test_integrations.py b/src/newsreader/accounts/tests/test_integrations.py
index 4bac037..5c65caf 100644
--- a/src/newsreader/accounts/tests/test_integrations.py
+++ b/src/newsreader/accounts/tests/test_integrations.py
@@ -1,4 +1,4 @@
-from unittest.mock import patch
+from unittest.mock import Mock, patch
from urllib.parse import urlencode
from uuid import uuid4
@@ -13,6 +13,7 @@ from newsreader.news.collection.exceptions import (
StreamException,
StreamTooManyException,
)
+from newsreader.news.collection.twitter import TWITTER_AUTH_URL
class IntegrationsViewTestCase(TestCase):
@@ -326,3 +327,60 @@ class TwitterRevokeRedirectView(TestCase):
self.assertEquals(self.user.twitter_oauth_token, "jadajadajada")
self.assertEquals(self.user.twitter_oauth_token_secret, "jadajadajada")
+
+
+class TwitterAuthRedirectViewTestCase(TestCase):
+ def setUp(self):
+ self.user = UserFactory(email="test@test.nl", password="test")
+ self.client.force_login(self.user)
+
+ self.patch = patch("newsreader.accounts.views.integrations.post")
+ self.mocked_post = self.patch.start()
+
+ def tearDown(self):
+ cache.clear()
+
+ def test_simple(self):
+ self.mocked_post.return_value = Mock(
+ text="oauth_token=foo&oauth_token_secret=bar"
+ )
+
+ response = self.client.get(reverse("accounts:twitter-auth"))
+
+ self.assertRedirects(
+ response,
+ f"{TWITTER_AUTH_URL}/?oauth_token=foo",
+ fetch_redirect_response=False,
+ )
+
+ cached_token = cache.get(f"twitter-{self.user.email}-token")
+ cached_secret = cache.get(f"twitter-{self.user.email}-secret")
+
+ self.assertEquals(cached_token, "foo")
+ self.assertEquals(cached_secret, "bar")
+
+ def test_stream_exception(self):
+ self.mocked_post.side_effect = StreamException
+
+ response = self.client.get(reverse("accounts:twitter-auth"))
+
+ self.assertRedirects(response, reverse("accounts:integrations"))
+
+ cached_token = cache.get(f"twitter-{self.user.email}-token")
+ cached_secret = cache.get(f"twitter-{self.user.email}-secret")
+
+ self.assertIsNone(cached_token)
+ self.assertIsNone(cached_secret)
+
+ def test_unexpected_contents(self):
+ self.mocked_post.return_value = Mock(text="foo=bar&oauth_token_secret=bar")
+
+ response = self.client.get(reverse("accounts:twitter-auth"))
+
+ self.assertRedirects(response, reverse("accounts:integrations"))
+
+ cached_token = cache.get(f"twitter-{self.user.email}-token")
+ cached_secret = cache.get(f"twitter-{self.user.email}-secret")
+
+ self.assertIsNone(cached_token)
+ self.assertIsNone(cached_secret)
diff --git a/src/newsreader/accounts/urls.py b/src/newsreader/accounts/urls.py
index 9f0f2e3..841e40a 100644
--- a/src/newsreader/accounts/urls.py
+++ b/src/newsreader/accounts/urls.py
@@ -88,9 +88,9 @@ urlpatterns = [
name="reddit-revoke",
),
path(
- "settings/integrations/twitter/request/",
+ "settings/integrations/twitter/auth/",
login_required(TwitterAuthRedirectView.as_view()),
- name="twitter-request",
+ name="twitter-auth",
),
path(
"settings/integrations/twitter/callback/",
diff --git a/src/newsreader/accounts/views/integrations.py b/src/newsreader/accounts/views/integrations.py
index 2ff8c00..a146bda 100644
--- a/src/newsreader/accounts/views/integrations.py
+++ b/src/newsreader/accounts/views/integrations.py
@@ -75,7 +75,7 @@ class IntegrationsView(TemplateView):
twitter_revoke_url = reverse_lazy("accounts:twitter-revoke")
return {
- "twitter_request_url": reverse_lazy("accounts:twitter-request"),
+ "twitter_auth_url": reverse_lazy("accounts:twitter-auth"),
"twitter_revoke_url": twitter_revoke_url,
}
@@ -206,7 +206,6 @@ class TwitterRevokeRedirectView(RedirectView):
return super().get(request, *args, **kwargs)
-# TODO write tests
class TwitterAuthRedirectView(RedirectView):
url = reverse_lazy("accounts:integrations")
@@ -226,8 +225,15 @@ class TwitterAuthRedirectView(RedirectView):
return super().get(request, *args, **kwargs)
params = parse_qs(response.text)
- request_oauth_token = params.get("oauth_token")[0]
- request_oauth_secret = params.get("oauth_token_secret")[0]
+
+ try:
+ request_oauth_token = params["oauth_token"][0]
+ request_oauth_secret = params["oauth_token_secret"][0]
+ except KeyError:
+ logger.exception("No credentials found in response")
+
+ messages.error(request, _("Unable to retrieve initial Twitter token"))
+ return super().get(request, *args, **kwargs)
cache.set_many(
{