· 10 years ago · Mar 05, 2016, 05:21 AM
1import json
2from importlib import import_module
3
4from django.conf import settings
5from django.test import TestCase
6from django.core.urlresolvers import reverse
7
8import mock
9from nose.tools import ok_, eq_
10
11from airmozilla.authentication.browserid_mock import mock_browserid
12from airmozilla.base import mozillians
13from airmozilla.base.tests.testbase import Response
14from airmozilla.main.models import UserProfile
15
16from airmozilla.base.tests.test_mozillians import (
17 VOUCHED_FOR_USERS,
18 NOT_VOUCHED_FOR_USERS,
19)
20
21
22class TestViews(TestCase):
23
24 def setUp(self):
25 super(TestViews, self).setUp()
26
27 engine = import_module(settings.SESSION_ENGINE)
28 store = engine.SessionStore()
29 store.save() # we need to make load() work, or the cookie is worthless
30 self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key
31
32 def shortDescription(self):
33 # Stop nose using the test docstring and instead the test method name.
34 pass
35
36 def get_messages(self):
37 return self.client.session['_messages']
38
39 def _login_attempt(self, email, assertion='fakeassertion123', next=None):
40 if not next:
41 next = '/'
42 with mock_browserid(email):
43 post_data = {
44 'assertion': assertion,
45 'next': next
46 }
47 return self.client.post(
48 '/browserid/login/',
49 post_data
50 )
51
52 def test_invalid(self):
53 """Bad BrowserID form (i.e. no assertion) -> failure."""
54 response = self._login_attempt(None, None)
55 eq_(response['content-type'], 'application/json')
56 redirect = json.loads(response.content)['redirect']
57 eq_(redirect, settings.LOGIN_REDIRECT_URL_FAILURE)
58 # self.assertRedirects(
59 # response,
60 # settings.LOGIN_REDIRECT_URL_FAILURE + '?bid_login_failed=1'
61 # )
62
63 def test_bad_verification(self):
64 """Bad verification -> failure."""
65 response = self._login_attempt(None)
66 eq_(response['content-type'], 'application/json')
67 redirect = json.loads(response.content)['redirect']
68 eq_(redirect, settings.LOGIN_REDIRECT_URL_FAILURE)
69 # self.assertRedirects(
70 # response,
71 # settings.LOGIN_REDIRECT_URL_FAILURE + '?bid_login_failed=1'
72 # )
73
74 @mock.patch('requests.get')
75 def test_nonmozilla(self, rget):
76 """Non-Mozilla email -> failure."""
77 def mocked_get(url, **options):
78 if 'tmickel' in url:
79 return Response(NOT_VOUCHED_FOR_USERS)
80 if 'peterbe' in url:
81 return Response(VOUCHED_FOR_USERS)
82 raise NotImplementedError(url)
83 rget.side_effect = mocked_get
84
85 response = self._login_attempt('tmickel@mit.edu')
86 eq_(response['content-type'], 'application/json')
87 redirect = json.loads(response.content)['redirect']
88 eq_(redirect, settings.LOGIN_REDIRECT_URL_FAILURE)
89 # self.assertRedirects(
90 # response,
91 # settings.LOGIN_REDIRECT_URL_FAILURE + '?bid_login_failed=1'
92 # )
93
94 # now with a non-mozillian that is vouched for
95 response = self._login_attempt('peterbe@gmail.com')
96 eq_(response['content-type'], 'application/json')
97 redirect = json.loads(response.content)['redirect']
98 eq_(redirect, settings.LOGIN_REDIRECT_URL)
99 # self.assertRedirects(response,
100 # settings.LOGIN_REDIRECT_URL)
101
102 @mock.patch('requests.get')
103 def test_nonmozilla_vouched_for_second_time(self, rget):
104 assert not UserProfile.objects.all()
105
106 def mocked_get(url, **options):
107 return Response(VOUCHED_FOR_USERS)
108
109 rget.side_effect = mocked_get
110
111 # now with a non-mozillian that is vouched for
112 response = self._login_attempt('peterbe@gmail.com')
113 eq_(response['content-type'], 'application/json')
114 redirect = json.loads(response.content)['redirect']
115 eq_(redirect, settings.LOGIN_REDIRECT_URL)
116 # self.assertRedirects(response,
117 # settings.LOGIN_REDIRECT_URL)
118
119 # should be logged in
120 response = self.client.get('/')
121 eq_(response.status_code, 200)
122 ok_('Sign in' not in response.content)
123 ok_('Sign out' in response.content)
124
125 profile, = UserProfile.objects.all()
126 ok_(profile.contributor)
127
128 # sign out
129 response = self.client.get(reverse('browserid.logout'))
130 eq_(response.status_code, 405)
131 response = self.client.post(reverse('browserid.logout'))
132 eq_(response.status_code, 200)
133 eq_(response['content-type'], 'application/json')
134 redirect = json.loads(response.content)['redirect']
135 eq_(redirect, settings.LOGIN_REDIRECT_URL)
136
137 # should be logged out
138 response = self.client.get('/')
139 eq_(response.status_code, 200)
140 ok_('Sign in' in response.content)
141 ok_('Sign out' not in response.content)
142
143 # sign in again
144 response = self._login_attempt('peterbe@gmail.com')
145 eq_(response['content-type'], 'application/json')
146 redirect = json.loads(response.content)['redirect']
147 eq_(redirect, settings.LOGIN_REDIRECT_URL)
148 # self.assertRedirects(response,
149 # settings.LOGIN_REDIRECT_URL)
150 # should not have created another one
151 eq_(UserProfile.objects.all().count(), 1)
152
153 # sign out again
154 response = self.client.post(reverse('browserid.logout'))
155 eq_(response.status_code, 200)
156 eq_(response['content-type'], 'application/json')
157 redirect = json.loads(response.content)['redirect']
158 eq_(redirect, settings.LOGIN_REDIRECT_URL)
159
160 # pretend this is lost
161 profile.contributor = False
162 profile.save()
163 response = self._login_attempt('peterbe@gmail.com')
164 eq_(response['content-type'], 'application/json')
165 redirect = json.loads(response.content)['redirect']
166 eq_(redirect, settings.LOGIN_REDIRECT_URL)
167
168 # self.assertRedirects(response,
169 # settings.LOGIN_REDIRECT_URL)
170 # should not have created another one
171 eq_(UserProfile.objects.filter(contributor=True).count(), 1)
172
173 def test_mozilla(self):
174 """Mozilla email -> success."""
175 # Try the first allowed domain
176 response = self._login_attempt('tmickel@' + settings.ALLOWED_BID[0])
177 eq_(response['content-type'], 'application/json')
178 redirect = json.loads(response.content)['redirect']
179 eq_(redirect, settings.LOGIN_REDIRECT_URL)
180
181 @mock.patch('requests.get')
182 def test_was_contributor_now_mozilla_bid(self, rget):
183 """Suppose a user *was* a contributor but now her domain name
184 is one of the allowed ones, it should undo that contributor status
185 """
186 assert not UserProfile.objects.all()
187
188 def mocked_get(url, **options):
189 return Response(VOUCHED_FOR_USERS)
190
191 rget.side_effect = mocked_get
192 response = self._login_attempt('peterbe@gmail.com')
193 eq_(response['content-type'], 'application/json')
194 redirect = json.loads(response.content)['redirect']
195 eq_(redirect, settings.LOGIN_REDIRECT_URL)
196
197 response = self.client.get('/')
198 eq_(response.status_code, 200)
199 ok_('Sign in' not in response.content)
200 ok_('Sign out' in response.content)
201
202 profile = UserProfile.objects.get(user__email='peterbe@gmail.com')
203 ok_(profile.contributor)
204
205 self.client.logout()
206 response = self.client.get('/')
207 eq_(response.status_code, 200)
208 ok_('Sign in' in response.content)
209 ok_('Sign out' not in response.content)
210
211 with self.settings(ALLOWED_BID=settings.ALLOWED_BID + ('gmail.com',)):
212 response = self._login_attempt('peterbe@gmail.com')
213 eq_(response['content-type'], 'application/json')
214 redirect = json.loads(response.content)['redirect']
215 eq_(redirect, settings.LOGIN_REDIRECT_URL)
216
217 profile = UserProfile.objects.get(user__email='peterbe@gmail.com')
218 ok_(not profile.contributor) # fixed!
219
220 @mock.patch('airmozilla.authentication.views.logger')
221 @mock.patch('requests.get')
222 def test_nonmozilla_mozillians_unhappy(self, rget, rlogger):
223 assert not UserProfile.objects.all()
224
225 def mocked_get(url, **options):
226 raise mozillians.BadStatusCodeError('crap!')
227
228 rget.side_effect = mocked_get
229
230 # now with a non-mozillian that is vouched for
231 response = self._login_attempt('peterbe@gmail.com')
232 eq_(response['content-type'], 'application/json')
233 redirect = json.loads(response.content)['redirect']
234 eq_(redirect, settings.LOGIN_REDIRECT_URL_FAILURE)
235 # self.assertRedirects(
236 # response,
237 # settings.LOGIN_REDIRECT_URL_FAILURE + '?bid_login_failed=1'
238 # )
239 eq_(rlogger.error.call_count, 1)