def test_case_insensitive(self): """Matching is not case sensitive""" self.assertTrue(language_code_is_valid('az-BY')) self.assertTrue(language_code_is_valid('aZ')) self.assertTrue(language_code_is_valid('QW'))
def test_exact_3_letter(self): """3-letter code is valid. There are a few of these.""" self.assertTrue(language_code_is_valid('azq'))
def test_exact_5_letter(self): """5-letter code that's in the list is valid""" self.assertTrue(language_code_is_valid('az-BY'))
def test_none(self): """None is a TypeError""" with self.assertRaises(TypeError): language_code_is_valid(None)
def test_zero(self): """0 is a TypeError""" with self.assertRaises(TypeError): language_code_is_valid(0)
def get_involved(request): data = request.POST.dict() if 'email' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'email is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) if email_is_blocked(data['email']): # don't let on there's a problem return HttpResponseJSON({'status': 'ok'}) if 'interest_id' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'interest_id is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) try: Interest.objects.get(interest_id=data['interest_id']) except Interest.DoesNotExist: return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid interest_id', 'code': errors.BASKET_USAGE_ERROR, }, 401) if 'lang' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'lang is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) if not language_code_is_valid(data['lang']): return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid language', 'code': errors.BASKET_INVALID_LANGUAGE, }, 400) if 'name' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'name is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) if 'country' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'country is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) try: validate_email(data.get('email')) except EmailValidationError as e: return invalid_email_response(e) update_get_involved.delay( data['interest_id'], data['lang'], data['name'], data['email'], data['country'], data.get('format', 'H'), data.get('subscribe', False), data.get('message', None), data.get('source_url', None), ) return HttpResponseJSON({'status': 'ok'})
def update_user_task(request, api_call_type, data=None, optin=False, sync=False): """Call the update_user task async with the right parameters. If sync==True, be sure to include the token in the response. Otherwise, basket can just do everything in the background. """ data = data or request.POST.dict() newsletters = parse_newsletters_csv(data.get('newsletters')) if newsletters: if api_call_type == SUBSCRIBE: all_newsletters = newsletter_and_group_slugs() + get_transactional_message_ids() else: all_newsletters = newsletter_slugs() private_newsletters = newsletter_private_slugs() for nl in newsletters: if nl not in all_newsletters: return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid newsletter', 'code': errors.BASKET_INVALID_NEWSLETTER, }, 400) if api_call_type != UNSUBSCRIBE and nl in private_newsletters: if not request.is_secure(): return HttpResponseJSON({ 'status': 'error', 'desc': 'private newsletter subscription requires SSL', 'code': errors.BASKET_SSL_REQUIRED, }, 401) if not has_valid_api_key(request): return HttpResponseJSON({ 'status': 'error', 'desc': 'private newsletter subscription requires a valid API key', 'code': errors.BASKET_AUTH_ERROR, }, 401) if 'lang' in data: if not language_code_is_valid(data['lang']): data['lang'] = 'en' elif 'accept_lang' in data: lang = get_best_language(get_accept_languages(data['accept_lang'])) if lang: data['lang'] = lang del data['accept_lang'] else: data['lang'] = 'en' email = data.get('email') token = data.get('token') if not (email or token): return HttpResponseJSON({ 'status': 'error', 'desc': MSG_EMAIL_OR_TOKEN_REQUIRED, 'code': errors.BASKET_USAGE_ERROR, }, 400) if optin: data['optin'] = True if api_call_type == SUBSCRIBE and email and data.get('newsletters'): # only rate limit here so we don't rate limit errors. if is_ratelimited(request, group='news.views.update_user_task.subscribe', key=lambda x, y: '%s-%s' % (data['newsletters'], email), rate=EMAIL_SUBSCRIBE_RATE_LIMIT, increment=True): raise Ratelimited() if api_call_type == SET and token and data.get('newsletters'): # only rate limit here so we don't rate limit errors. if is_ratelimited(request, group='news.views.update_user_task.set', key=lambda x, y: '%s-%s' % (data['newsletters'], token), rate=EMAIL_SUBSCRIBE_RATE_LIMIT, increment=True): raise Ratelimited() if sync: statsd.incr('news.views.subscribe.sync') if settings.MAINTENANCE_MODE and not settings.MAINTENANCE_READ_ONLY: # save what we can upsert_user.delay(api_call_type, data, start_time=time()) # have to error since we can't return a token return HttpResponseJSON({ 'status': 'error', 'desc': 'sync is not available in maintenance mode', 'code': errors.BASKET_NETWORK_FAILURE, }, 400) try: user_data = get_user_data(email=email, token=token) except NewsletterException as e: return newsletter_exception_response(e) if not user_data: if not email: # must have email to create a user return HttpResponseJSON({ 'status': 'error', 'desc': MSG_EMAIL_OR_TOKEN_REQUIRED, 'code': errors.BASKET_USAGE_ERROR, }, 400) token, created = upsert_contact(api_call_type, data, user_data) return HttpResponseJSON({ 'status': 'ok', 'token': token, 'created': created, }) else: upsert_user.delay(api_call_type, data, start_time=time()) return HttpResponseJSON({ 'status': 'ok', })
def test_wrong_length(self): """A code that's not a valid length is not valid.""" self.assertFalse(language_code_is_valid('az-')) self.assertFalse(language_code_is_valid('a')) self.assertFalse(language_code_is_valid('azqr')) self.assertFalse(language_code_is_valid('az-BY2'))
def test_empty_string(self): """Empty string is accepted as a language code""" self.assertTrue(language_code_is_valid(''))
def test_wrong_format(self): """A code that's not a valid format is not valid.""" self.assertFalse(language_code_is_valid('a2')) self.assertFalse(language_code_is_valid('asdfj')) self.assertFalse(language_code_is_valid('az_BY'))
def update_user_task(request, api_call_type, data=None, optin=True, sync=False): """Call the update_user task async with the right parameters. If sync==True, be sure to include the token in the response. Otherwise, basket can just do everything in the background. """ data = data or request.POST.dict() newsletters = data.get('newsletters', None) if newsletters: newsletters = [x.strip() for x in newsletters.split(',')] if api_call_type == SUBSCRIBE: all_newsletters = newsletter_and_group_slugs() else: all_newsletters = newsletter_slugs() private_newsletters = newsletter_private_slugs() for nl in newsletters: if nl not in all_newsletters: return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid newsletter', 'code': errors.BASKET_INVALID_NEWSLETTER, }, 400) if api_call_type != UNSUBSCRIBE and nl in private_newsletters: if not request.is_secure(): return HttpResponseJSON({ 'status': 'error', 'desc': 'private newsletter subscription requires SSL', 'code': errors.BASKET_SSL_REQUIRED, }, 401) if not has_valid_api_key(request): return HttpResponseJSON({ 'status': 'error', 'desc': 'private newsletter subscription requires a valid API key', 'code': errors.BASKET_AUTH_ERROR, }, 401) if 'lang' in data: if not language_code_is_valid(data['lang']): return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid language', 'code': errors.BASKET_INVALID_LANGUAGE, }, 400) elif 'accept_lang' in data: lang = get_best_language(get_accept_languages(data['accept_lang'])) if lang: data['lang'] = lang del data['accept_lang'] else: return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid language', 'code': errors.BASKET_INVALID_LANGUAGE, }, 400) email = data.get('email') token = data.get('token') if not (email or token): return HttpResponseJSON({ 'status': 'error', 'desc': MSG_EMAIL_OR_TOKEN_REQUIRED, 'code': errors.BASKET_USAGE_ERROR, }, 400) if sync: try: user_data, created = get_or_create_user_data(email=email, token=token) except NewsletterException as e: return newsletter_exception_response(e) update_user.delay(data, user_data['email'], user_data['token'], api_call_type, optin, start_time=time()) return HttpResponseJSON({ 'status': 'ok', 'token': user_data['token'], 'created': created, }) else: update_user.delay(data, email, token, api_call_type, optin, start_time=time()) return HttpResponseJSON({ 'status': 'ok', })
def get_involved(request): data = request.POST.dict() if 'email' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'email is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) if email_is_blocked(data['email']): # don't let on there's a problem return HttpResponseJSON({'status': 'ok'}) if 'interest_id' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'interest_id is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) try: Interest.objects.get(interest_id=data['interest_id']) except Interest.DoesNotExist: return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid interest_id', 'code': errors.BASKET_USAGE_ERROR, }, 401) if 'lang' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'lang is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) if not language_code_is_valid(data['lang']): return HttpResponseJSON({ 'status': 'error', 'desc': 'invalid language', 'code': errors.BASKET_INVALID_LANGUAGE, }, 400) if 'name' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'name is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) if 'country' not in data: return HttpResponseJSON({ 'status': 'error', 'desc': 'country is required', 'code': errors.BASKET_USAGE_ERROR, }, 401) email = process_email(data.get('email')) if not email: return invalid_email_response() update_get_involved.delay( data['interest_id'], data['lang'], data['name'], email, data['country'], data.get('format', 'H'), data.get('subscribe', False), data.get('message', None), data.get('source_url', None), ) return HttpResponseJSON({'status': 'ok'})