def test_rate_limit_user_update(self): """Should raise Ratelimited if token attempts to update same newsletters quickly""" request = self.factory.post('/') data = {'token': '*****@*****.**', 'newsletters': 'foo,bar'} with patch('news.views.newsletter_slugs') as newsletter_slugs: newsletter_slugs.return_value = ['foo', 'bar'] update_user_task(request, SET, data, sync=False) response = update_user_task(request, SET, data, sync=False) self.assert_response_ok(response) with self.assertRaises(Ratelimited): update_user_task(request, SET, data, sync=False)
def test_rate_limit(self): """Should raise Ratelimited if email attempts to sign up for same newsletter quickly""" request = self.factory.post('/') data = {'email': '*****@*****.**', 'newsletters': 'foo,bar'} with patch( 'news.views.newsletter_and_group_slugs') as newsletter_slugs: newsletter_slugs.return_value = ['foo', 'bar'] update_user_task(request, SUBSCRIBE, data, sync=False) response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) with self.assertRaises(Ratelimited): update_user_task(request, SUBSCRIBE, data, sync=False)
def test_update_user_task_helper_create(self, uu_mock, look_for_user): """ Should create a user and tell the task about it if email not known. """ # Pretend we are unable to find the user in ET look_for_user.return_value = None # Pass in a new email req = self.rf.post('/testing/', {'email': '*****@*****.**'}) resp = views.update_user_task(req, tasks.SUBSCRIBE) # Should work self.assertEqual(200, resp.status_code) # There should be a new subscriber for this email sub = models.Subscriber.objects.get(email='*****@*****.**') resp_data = json.loads(resp.content) # The call should have returned the subscriber's new token self.assertDictEqual(resp_data, { 'status': 'ok', 'token': sub.token, 'created': True, }) # We should have called update_user with the email, token, # created=False, type=SUBSCRIBE, optin=True uu_mock.assert_called_with({'email': [sub.email]}, sub.email, sub.token, True, tasks.SUBSCRIBE, True)
def test_update_user_task_helper_create(self, uu_mock, look_for_user): """ Should create a user and tell the task about it if email not known. """ # Pretend we are unable to find the user in ET look_for_user.return_value = None # Pass in a new email req = self.rf.post('/testing/', {'email': '*****@*****.**'}) resp = views.update_user_task(req, tasks.SUBSCRIBE) # Should work self.assertEqual(200, resp.status_code) # There should be a new subscriber for this email sub = models.Subscriber.objects.get(email='*****@*****.**') resp_data = json.loads(resp.content) # The call should have returned the subscriber's new token self.assertDictEqual(resp_data, { 'status': 'ok', 'token': sub.token, 'created': True, }) # We should have called update_user with the email, token, # created=False, type=SUBSCRIBE, optin=True uu_mock.assert_called_with({'email': sub.email}, sub.email, sub.token, True, tasks.SUBSCRIBE, True)
def test_missing_email(self): """ If the email is missing, return a 400 error. """ request = self.factory.post('/') response = update_user_task(request, SUBSCRIBE) self.assert_response_error(response, 400, errors.BASKET_USAGE_ERROR)
def test_invalid_accept_lang(self): """If accept_lang param is provided but invalid, return a 400.""" request = self.factory.post('/') data = {'email': '*****@*****.**', 'accept_lang': 'the dude minds, man'} response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_error(response, 400, errors.BASKET_INVALID_LANGUAGE) self.assertFalse(self.update_user.delay.called)
def test_invalid_newsletter(self): """If an invalid newsletter is given, return a 400 error.""" request = self.factory.post('/') with patch('news.views.newsletter_slugs') as newsletter_slugs: newsletter_slugs.return_value = ['foo', 'baz'] response = update_user_task(request, SUBSCRIBE, {'newsletters': 'foo,bar'}) self.assert_response_error(response, 400, errors.BASKET_INVALID_NEWSLETTER)
def test_success_with_valid_lang(self): """If the specified language is valid, return an OK response.""" request = self.factory.post('/') data = {'email': '*****@*****.**', 'lang': 'pt-BR'} with patch('news.views.language_code_is_valid') as mock_language_code_is_valid: mock_language_code_is_valid.return_value = True response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response)
def test_invalid_lang(self): """If the given lang is invalid, return a 400 error.""" request = self.factory.post('/') with patch('news.views.language_code_is_valid') as mock_language_code_is_valid: mock_language_code_is_valid.return_value = False response = update_user_task(request, SUBSCRIBE, {'lang': 'pt-BR'}) self.assert_response_error(response, 400, errors.BASKET_INVALID_LANGUAGE) mock_language_code_is_valid.assert_called_with('pt-BR')
def test_success_with_valid_lang(self): """If the specified language is valid, return an OK response.""" request = self.factory.post('/') data = {'email': '*****@*****.**', 'lang': 'pt-BR'} with patch('news.views.language_code_is_valid' ) as mock_language_code_is_valid: mock_language_code_is_valid.return_value = True response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response)
def test_success_with_valid_newsletters(self): """ If the specified newsletters are valid, return an OK response. """ request = self.factory.post('/') data = {'email': '*****@*****.**', 'newsletters': 'foo,bar'} with patch('news.views.newsletter_and_group_slugs') as newsletter_slugs: newsletter_slugs.return_value = ['foo', 'bar'] response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response)
def test_accept_lang(self, get_best_language_mock): """If accept_lang param is provided, should set the lang in data.""" get_best_language_mock.return_value = 'pt' request = self.factory.post('/') data = {'email': '*****@*****.**', 'accept_lang': 'pt-pt,fr;q=0.8'} after_data = {'email': '*****@*****.**', 'lang': 'pt'} response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) self.update_user.delay.assert_called_with(after_data, '*****@*****.**', None, SUBSCRIBE, True, start_time=ANY)
def test_set_private_newsletter_ssl_required(self, mock_private, mock_slugs): """ If subscribing to a private newsletter and the request isn't HTTPS, return a 401. """ mock_private.return_value = ['private'] mock_slugs.return_value = ['private', 'other'] data = {'newsletters': 'private', 'email': '*****@*****.**'} request = self.factory.post('/', data) request.is_secure = lambda: False response = update_user_task(request, SET, data) self.assert_response_error(response, 401, errors.BASKET_SSL_REQUIRED)
def test_private_newsletter_success(self, mock_api_key, mock_private, mock_group_slugs, mock_slugs): """ If subscribing to a private newsletter and the request has an invalid API key, return a 401. """ mock_private.return_value = ['private'] mock_slugs.return_value = ['private', 'other'] mock_group_slugs.return_value = ['private', 'other'] data = {'newsletters': 'private', 'email': '*****@*****.**'} request = self.factory.post('/', data) request.is_secure = lambda: True mock_api_key.return_value = True response = update_user_task(request, SUBSCRIBE, data) self.assert_response_ok(response) mock_api_key.assert_called_with(request) response = update_user_task(request, SET, data) self.assert_response_ok(response) mock_api_key.assert_called_with(request)
def test_success_with_request_data(self): """ If no data is provided, fall back to using the POST data from the request. """ data = {'email': '*****@*****.**'} request = self.factory.post('/', data) response = update_user_task(request, SUBSCRIBE, sync=False) self.assert_response_ok(response) self.update_user.delay.assert_called_with(data, '*****@*****.**', None, SUBSCRIBE, True, start_time=ANY)
def test_accept_lang(self, get_best_language_mock): """If accept_lang param is provided, should set the lang in data.""" get_best_language_mock.return_value = 'pt' request = self.factory.post('/') data = {'email': '*****@*****.**', 'accept_lang': 'pt-pt,fr;q=0.8'} after_data = {'email': '*****@*****.**', 'lang': 'pt'} response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) self.upsert_user.delay.assert_called_with(SUBSCRIBE, after_data, start_time=ANY)
def test_success_with_valid_newsletters(self): """ If the specified newsletters are valid, return an OK response. """ request = self.factory.post('/') data = {'email': '*****@*****.**', 'newsletters': 'foo,bar'} with patch( 'news.views.newsletter_and_group_slugs') as newsletter_slugs: newsletter_slugs.return_value = ['foo', 'bar'] response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response)
def test_success_with_request_data(self): """ If no data is provided, fall back to using the POST data from the request. """ data = {'email': '*****@*****.**'} request = self.factory.post('/', data) response = update_user_task(request, SUBSCRIBE, sync=False) self.assert_response_ok(response) self.upsert_user.delay.assert_called_with(SUBSCRIBE, data, start_time=ANY)
def test_success_with_unsubscribe_private_newsletter(self, mock_private, mock_slugs): """ Should be able to unsubscribe from a private newsletter regardless. """ mock_private.return_value = ['private'] mock_slugs.return_value = ['private', 'other'] request = self.factory.post('/') data = {'token': 'mytoken', 'newsletters': 'private'} response = update_user_task(request, UNSUBSCRIBE, data) self.assert_response_ok(response) self.update_user.delay.assert_called_with(data, None, 'mytoken', UNSUBSCRIBE, True, start_time=ANY)
def test_success_no_sync(self): """ If sync is False, do not generate a token via get_or_create_user_data and return an OK response without a token. """ request = self.factory.post('/') data = {'email': '*****@*****.**', 'first_name': 'The', 'last_name': 'Dude'} response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) self.update_user.delay.assert_called_with(data, '*****@*****.**', None, SUBSCRIBE, True, start_time=ANY) self.assertFalse(self.get_or_create_user_data.called)
def test_success_with_unsubscribe_private_newsletter( self, mock_private, mock_slugs): """ Should be able to unsubscribe from a private newsletter regardless. """ mock_private.return_value = ['private'] mock_slugs.return_value = ['private', 'other'] request = self.factory.post('/') data = {'token': 'mytoken', 'newsletters': 'private'} response = update_user_task(request, UNSUBSCRIBE, data) self.assert_response_ok(response) self.upsert_user.delay.assert_called_with(UNSUBSCRIBE, data, start_time=ANY)
def test_success_with_sync(self, gud_mock): """ If sync is True look up the user with get_or_create_user_data and return an OK response with the token and created from the fetched subscriber. """ request = self.factory.post('/') data = {'email': '*****@*****.**'} gud_mock.return_value = {'token': 'mytoken', 'email': '*****@*****.**'} self.upsert_contact.return_value = 'mytoken', True response = update_user_task(request, SUBSCRIBE, data, sync=True) self.assert_response_ok(response, token='mytoken', created=True) self.upsert_contact.assert_called_with(SUBSCRIBE, data, gud_mock.return_value)
def test_set_private_newsletter_invalid_api_key(self, mock_api_key, mock_private, mock_slugs): """ If subscribing to a private newsletter and the request has an invalid API key, return a 401. """ mock_private.return_value = ['private'] mock_slugs.return_value = ['private', 'other'] data = {'newsletters': 'private', 'email': '*****@*****.**'} request = self.factory.post('/', data) request.is_secure = lambda: True mock_api_key.return_value = False response = update_user_task(request, SET, data) self.assert_response_error(response, 401, errors.BASKET_AUTH_ERROR) mock_api_key.assert_called_with(request)
def test_success_with_sync(self): """ If sync is True look up the user with get_or_create_user_data and return an OK response with the token and created from the fetched subscriber. """ request = self.factory.post('/') data = {'email': '*****@*****.**'} self.get_or_create_user_data.return_value = {'token': 'mytoken', 'email': '*****@*****.**'}, True response = update_user_task(request, SUBSCRIBE, data, sync=True) self.assert_response_ok(response, token='mytoken', created=True) self.update_user.delay.assert_called_with(data, '*****@*****.**', 'mytoken', SUBSCRIBE, True, start_time=ANY)
def test_lang_overrides_accept_lang(self, get_best_language_mock): """ If lang is provided it was from the user, and accept_lang isn't as reliable, so we should prefer lang. """ get_best_language_mock.return_value = 'pt-BR' request = self.factory.post('/') data = {'email': '*****@*****.**', 'lang': 'de', 'accept_lang': 'pt-BR'} response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) # basically asserts that the data['lang'] value wasn't changed. self.upsert_user.delay.assert_called_with(SUBSCRIBE, data, start_time=ANY)
def test_lang_overrides_accept_lang(self, get_best_language_mock): """ If lang is provided it was from the user, and accept_lang isn't as reliable, so we should prefer lang. """ get_best_language_mock.return_value = 'pt-BR' request = self.factory.post('/') data = {'email': '*****@*****.**', 'lang': 'de', 'accept_lang': 'pt-BR'} response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) # basically asserts that the data['lang'] value wasn't changed. self.update_user.delay.assert_called_with(data, '*****@*****.**', None, SUBSCRIBE, True, start_time=ANY)
def test_update_user_task_helper_error(self, uu_mock): """ Should not call the task if no email or token provided. """ # Pretend there was no email given - bad request req = self.rf.post('/testing/', {'stuff': 'whanot'}) resp = views.update_user_task(req, tasks.SUBSCRIBE) # We don't try to call update_user self.assertFalse(uu_mock.called) # We respond with a 400 self.assertEqual(resp.status_code, 400) errors = json.loads(resp.content) # The response also says there was an error self.assertEqual(errors['status'], 'error') # and has a useful error description self.assertEqual(errors['desc'], MSG_EMAIL_OR_TOKEN_REQUIRED)
def test_success_no_sync(self): """ If sync is False, do not generate a token via get_or_create_user_data and return an OK response without a token. """ request = self.factory.post('/') data = { 'email': '*****@*****.**', 'first_name': 'The', 'last_name': 'Dude' } response = update_user_task(request, SUBSCRIBE, data, sync=False) self.assert_response_ok(response) self.upsert_user.delay.assert_called_with(SUBSCRIBE, data, start_time=ANY) self.assertFalse(self.upsert_contact.called)
def test_update_user_task_helper(self, uu_mock): """ `update_user` should always get an email and token. """ # Fake an incoming request which we've already looked up and # found a corresponding subscriber for req = self.rf.post('/testing/', {'stuff': 'whanot'}) req.subscriber = self.sub # Call update_user to subscribe resp = views.update_user_task(req, tasks.SUBSCRIBE) resp_data = json.loads(resp.content) # We should get back 'ok' status and the token from that # subscriber. self.assertDictEqual(resp_data, { 'status': 'ok', 'token': self.sub.token, 'created': False, }) # We should have called update_user with the email, token, # created=False, type=SUBSCRIBE, optin=True uu_mock.assert_called_with({'stuff': ['whanot']}, self.sub.email, self.sub.token, False, tasks.SUBSCRIBE, True)
def test_update_user_task_helper(self, uu_mock): """ `update_user` should always get an email and token. """ # Fake an incoming request which we've already looked up and # found a corresponding subscriber for req = self.rf.post('/testing/', {'stuff': 'whanot'}) req.subscriber = self.sub # Call update_user to subscribe resp = views.update_user_task(req, tasks.SUBSCRIBE) resp_data = json.loads(resp.content) # We should get back 'ok' status and the token from that # subscriber. self.assertDictEqual(resp_data, { 'status': 'ok', 'token': self.sub.token, 'created': False, }) # We should have called update_user with the email, token, # created=False, type=SUBSCRIBE, optin=True uu_mock.assert_called_with({'stuff': 'whanot'}, self.sub.email, self.sub.token, False, tasks.SUBSCRIBE, True)
def test_update_user_task_helper_no_sub(self, uu_mock): """ Should find sub from submitted email when not provided. """ # Request, pretend we were untable to find a subscriber # so we don't set req.subscriber req = self.rf.post('/testing/', {'email': self.sub.email}) # See what update_user does resp = views.update_user_task(req, tasks.SUBSCRIBE) # Should be okay self.assertEqual(200, resp.status_code) resp_data = json.loads(resp.content) # Should have found the token for the given email self.assertDictEqual(resp_data, { 'status': 'ok', 'token': self.sub.token, 'created': False, }) # We should have called update_user with the email, token, # created=False, type=SUBSCRIBE, optin=True uu_mock.assert_called_with({'email': [self.sub.email]}, self.sub.email, self.sub.token, False, tasks.SUBSCRIBE, True)
def test_update_user_task_helper_no_sub(self, uu_mock): """ Should find sub from submitted email when not provided. """ # Request, pretend we were untable to find a subscriber # so we don't set req.subscriber req = self.rf.post('/testing/', {'email': self.sub.email}) # See what update_user does resp = views.update_user_task(req, tasks.SUBSCRIBE) # Should be okay self.assertEqual(200, resp.status_code) resp_data = json.loads(resp.content) # Should have found the token for the given email self.assertDictEqual(resp_data, { 'status': 'ok', 'token': self.sub.token, 'created': False, }) # We should have called update_user with the email, token, # created=False, type=SUBSCRIBE, optin=True uu_mock.assert_called_with({'email': self.sub.email}, self.sub.email, self.sub.token, False, tasks.SUBSCRIBE, True)