def test_delete_user_profile(self): """ Delete a user and confirm profile gets deleted. """ # Create a user. response = utils.create_user(self) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(SpaProfile.objects.count(), 1) # Log in and delete user. response = utils.user_login(self) content = json.loads(response.content) token = content['token'] response = utils.delete_user(self, token=token) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(SpaProfile.objects.count(), 0) # Create three users. response = utils.create_user(self) self.assertEqual(response.status_code, status.HTTP_201_CREATED) response = utils.create_user(self, email='*****@*****.**') self.assertEqual(response.status_code, status.HTTP_201_CREATED) response = utils.create_user(self, email='*****@*****.**') self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(SpaProfile.objects.count(), 3) # Log in and delete only one of the users. response = utils.user_login(self) content = json.loads(response.content) token = content['token'] response = utils.delete_user(self, token=token) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(SpaProfile.objects.count(), 2)
def test_totp_delete_multiuser(self): """ Test whether TOTP device deletion works with multiple users. """ # Create user, log in, create TOTP device, log in: User 1 utils.create_user(self) self.assertEqual(SpaUser.objects.count(), 1) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] create_totp(self, token=token) self.assertEqual(TOTPDevice.objects.count(), 1) totp_token_1 = totp_login(self, SpaUser.objects.get()) # Create user, log in, create TOTP device, log in: User 2 utils.create_user(self, email='*****@*****.**') self.assertEqual(SpaUser.objects.count(), 2) response = utils.user_login(self, email='*****@*****.**') content = json.loads(response.content) token = content['token'] create_totp(self, token=token) self.assertEqual(TOTPDevice.objects.count(), 2) totp_token_2 = totp_login(self, SpaUser.objects.get(email='*****@*****.**')) # Create user, log in, create TOTP device, log in: User 3 utils.create_user(self, email='*****@*****.**') self.assertEqual(SpaUser.objects.count(), 3) response = utils.user_login(self, email='*****@*****.**') content = json.loads(response.content) token = content['token'] create_totp(self, token=token) self.assertEqual(TOTPDevice.objects.count(), 3) totp_token_3 = totp_login(self, SpaUser.objects.get(email='*****@*****.**')) # Delete TOTP device for User #2 response = totp_delete(self, token=totp_token_2) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(TOTPDevice.objects.count(), 2) # Confirm device is enabled for User #1 and #3 only response = totp_enabled(self, totp_token_1) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content, True) response = totp_enabled(self, totp_token_2) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) response = totp_enabled(self, totp_token_3) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content, True)
def test_totp_password_change(self): """ Test whether TOTP device survives password change. """ # Create user and log in. utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Create TOTP device and log in with it. create_totp(self, token=token) totp_token = totp_login(self, SpaUser.objects.get()) self.assertEqual(TOTPDevice.objects.count(), 1) # Logged in, so should be enabled response = totp_enabled(self, token) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(json.loads(response.content), True) # Change password. response = utils.change_password(self, token=totp_token) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) # Old tokens are no longer valid. response = utils.view_user(self, token) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) response = utils.view_user(self, totp_token) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # TOTP device still exists self.assertEqual(TOTPDevice.objects.count(), 1) # Can't log in with old password response = utils.user_login(self) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Log in with new password, can't access user page. response = utils.user_login(self, password='******') content = json.loads(response.content) token = content['token'] response = utils.view_user(self, token) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) # Verify TOTP. totp_token = totp_login(self, SpaUser.objects.get()) response = totp_enabled(self, token) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(json.loads(response.content), True) response = utils.view_user(self, totp_token) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_create_static(self): """ Create a static device. """ # Create user and log in. utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Confirm we can't create a static device with an invalid token. response = create_static(self, token='no-such') self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # Confirm we can't create a static device without first creating a TOTP device. # @TODO -- this is not actually required ...?? # IsOtpVerified returns True if there's no TOTP device #response = create_static(self, token=token) #self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) # Create and Validate TOTP - this generates a new token. response = create_totp(self, token=token) self.assertEqual(response.status_code, status.HTTP_201_CREATED) token = totp_login(self, SpaUser.objects.get()) # Confirm we can create a static device with a valid token. response = create_static(self, token=token) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(StaticDevice.objects.count(), 1) tokens = json.loads(response.content) self.assertEqual(len(tokens), 6) for token in tokens: self.assertEqual(len(token), 8)
def test_view_empty_profile(self): """ View an empty profile """ # Create user. utils.create_user(self) # Confirm we can't view user profile before logging in. response = view_profile(self) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # Log in. response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # View the user profile. response = view_profile(self, token=token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['first_name'], None) self.assertEqual(content['last_name'], None) self.assertEqual(content['date_of_birth'], None) self.assertEqual(content['phone_number'], '') self.assertEqual(content['country'], '') self.assertEqual(content['totp_enabled'], False)
def test_totp_delete(self): """ Test whether TOTP device deletion works. """ # Create user and log in. utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Create TOTP device and log in with it. create_totp(self, token=token) totp_token = totp_login(self, SpaUser.objects.get()) self.assertEqual(TOTPDevice.objects.count(), 1) # Logged in, so should be enabled response = totp_enabled(self, token) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(json.loads(response.content), True) # Delete TOTP device. response = totp_delete(self, token=totp_token) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(TOTPDevice.objects.count(), 0) content = json.loads(response.content) new_token = content['token'] # Confirm deleted device no longer shows up as enabled. response = totp_enabled(self, new_token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content, False) # Confirm that the old totp_token is no longer valid response = totp_enabled(self, totp_token) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # With the valid token, we no longer should be required to use a TOTP response = utils.view_user(self, token=new_token) self.assertEqual(response.status_code, status.HTTP_200_OK) # Create new TOTP device and log in with it. create_totp(self, token=new_token) new_totp_token = totp_login(self, SpaUser.objects.get()) self.assertEqual(TOTPDevice.objects.count(), 1) # New and old TOTP token should work, as the device # hasn't changed response = utils.view_user(self, token=new_token) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) #response = utils.view_user(self, token=totp_token) #self.assertEqual(response.status_code, status.HTTP_200_OK) response = utils.view_user(self, token=new_totp_token) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_delete_user_and_static(self): # Create user, log in, and create static device. response = utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] response = create_totp(self, token=token) token = totp_login(self, SpaUser.objects.get()) response = create_static(self, token=token) self.assertEqual(StaticDevice.objects.count(), 1) # Delete user, confirm static device is also deleted. response = utils.delete_user(self, token=token) self.assertEqual(StaticDevice.objects.count(), 0)
def test_totp_enabled(self): """ Test whether user has enabled TOTP device. """ # Create user and log in. response = utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Check if user has an enabled TOTP device. response = totp_enabled(self, token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content, False) # Unable to check if TOTP device is enabled if not logged in. response = totp_enabled(self) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # Create a TOTP device. response = create_totp(self, token=token) self.assertEqual(TOTPDevice.objects.count(), 1) # Confirm newly created TOTP device is not confirmed. response = totp_enabled(self, token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content, False) # Still unable to check if TOTP device is enabled if not logged in. response = totp_enabled(self) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # @TODO: properly test TOTP tokens. # Enable TOTP device. user = SpaUser.objects.get() device = get_user_totp_device(self, user) device.confirmed = True device.save() self.assertEqual(device.confirmed, True) # Confirm TOTP device is enabled.. response = totp_enabled(self, token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content, True)
def test_delete_user_and_totp(self): """ Delete user and associated TOTP device. """ # Create user, log in, and create TOTP device. response = utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] response = create_totp(self, token=token) content = json.loads(response.content) self.assertEqual(TOTPDevice.objects.count(), 1) # Delete user, confirm TOTP device is also deleted. response = utils.delete_user(self, token=token) self.assertEqual(TOTPDevice.objects.count(), 0)
def test_create_totp(self): """ Create a TOTP device. """ # Create user and log in. response = utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Confirm we can't create a TOTP with an invalid token. response = create_totp(self, token='no-such') self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # Confirm we can create a TOTP with a valid token. response = create_totp(self, token=token) self.assertEqual(response.status_code, status.HTTP_201_CREATED) content = json.loads(response.content) # Validate URL pieces. url = urlparse(content) self.assertEqual(url.scheme, 'otpauth') self.assertEqual(url.netloc, 'totp') self.assertEqual(url.path, '/a%40example.com') self.assertEqual(url.params, '') self.assertEqual(url.fragment, '') # Validate URL query pieces. query = parse_qs(url.query) self.assertEqual(query['algorithm'], ['SHA1']) self.assertEqual(query['digits'], ['6']) self.assertEqual(query['period'], ['30']) secret = query['secret'][0] assert len(secret) == 32 # We should have 1 uncomfirmed device. self.assertEqual(TOTPDevice.objects.count(), 1) device = TOTPDevice.objects.get() self.assertEqual(device.confirmed, False)
def test_static_login(self): # Create user, log in, and create static device. response = utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] response = create_totp(self, token=token) token = totp_login(self, SpaUser.objects.get()) # @FIXME: static_login is broken # static can't be verified before created #response = static_login(self, 'abcd3456', token=token) #self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) response = create_static(self, token=token) self.assertEqual(StaticDevice.objects.count(), 1) statics = json.loads(response.content) original_token = token for static in statics: # @FIXME: static_login is broken ## Must be logged in to use static. #response = static_login(self, static) token = static_login_fake(self, SpaUser.objects.get()) #self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) ## Static can be used only one time - we also get a new token each time #response = static_login(self, static, token=token) #self.assertEqual(response.status_code, status.HTTP_201_CREATED) #content = json.loads(response.content) #token = content['token'] # Static gets consumed and fails if used again. #response = static_login(self, static, token=token) #self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # The old token and the new token both work for basic access response = utils.view_user(self, token=token) self.assertEqual(response.status_code, status.HTTP_200_OK) response = utils.view_user(self, token=original_token) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_totp_protects_profile(self): """ A user with a verified totp device must validate it before accessing/editing Profile """ # Create and log in user. response = utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) nototp_token = content['token'] # Verify that currently we can view and edit our profile response = view_profile(self, token=nototp_token) self.assertEqual(response.status_code, status.HTTP_200_OK) data = { 'first_name': 'first', 'last_name': 'last', } response = edit_profile(self, token=nototp_token, data=data) self.assertEqual(response.status_code, status.HTTP_200_OK) # Now verify a TOTP device and confirm that we no longer can view/edit without it. response = create_totp(self, token=nototp_token) totp_token = totp_login(self, SpaUser.objects.get()) response = view_profile(self, token=nototp_token) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) response = edit_profile(self, token=nototp_token, data=data) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) # Finally, verify we CAN view/edit with a validated TOTP response = view_profile(self, token=totp_token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['totp_enabled'], True) response = edit_profile(self, token=totp_token, data=data) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_address_creation(self): """ Verify basic address creation. """ # Create user, log in, and create a bitcoin wallet. passphrase = 'thisISs3cured00d!' utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] wallet.utils.create_wallet_seed(self, token=token, data={'passphrase': passphrase}) response = wallet.utils.create_wallet(self, token=token, data={ 'label': 'default', 'currencycode': 'BTC', 'passphrase': passphrase }) content = json.loads(response.content) btc_wallet_id = content['data']['id'] # Create a bitcoin address. self.assertEqual(Address.objects.count(), 0) response = address.utils.create_address(self, token=token, data={ 'wallet_id': btc_wallet_id, 'label': 'test' }) #content = json.loads(response.content) #pprint(content) self.assertEqual(Address.objects.count(), 1) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) #pprint(content) self.assertEqual(content['status'], 'address created') self.assertEqual(content['data']['label'], 'test') # P2PKH Bitcoin addresses start with 1. self.assertEqual(content['data']['p2pkh'][:1], '1') # Load from database and be sure it matches bitcoin_address = Address.objects.get(wallet=btc_wallet_id) self.assertEqual(content['data']['p2pkh'], bitcoin_address.p2pkh) # Bech32 Bitcoin addresses start with bc1. self.assertEqual(bitcoin_address.bech32[:3], 'bc1') # Request address again: the first address wasn't used so we get back the same address response = address.utils.create_address(self, token=token, data={ 'wallet_id': btc_wallet_id, 'label': 'test' }) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Address.objects.count(), 1) content = json.loads(response.content) self.assertEqual(content['status'], 'address already exists') # Request address but with typo in wallet_id response = address.utils.create_address(self, token=token, data={ 'wallet_id': 'no-such-wallet', 'label': 'test' }) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Address.objects.count(), 1) content = json.loads(response.content) self.assertEqual(content['status'], 'wallet not found') # Create a litecoin wallet and address. response = wallet.utils.create_wallet(self, token=token, data={ 'label': 'default', 'currencycode': 'LTC', 'passphrase': 'thisISs3cured00d!' }) content = json.loads(response.content) ltc_wallet_id = content['data']['id'] response = address.utils.create_address( self, token=token, data={ 'wallet_id': ltc_wallet_id, 'label': 'test', 'passphrase': 'thequickbrownfox1234ABRAMAGIC' }) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Address.objects.count(), 2) content = json.loads(response.content) self.assertEqual(content['data']['label'], 'test') # P2PKH Litecoin addresses start with L. self.assertEqual(content['data']['p2pkh'][:1], 'L') litecoin_address = Address.objects.get(wallet=ltc_wallet_id) # Bech32 Litecoin addresses start with lc1. #self.assertEqual(litecoin_address.bech32[:3], 'lc1') # Create a dogecoin wallet and address. response = wallet.utils.create_wallet(self, token=token, data={ 'label': 'default', 'currencycode': 'DOGE', 'passphrase': 'thisISs3cured00d!' }) content = json.loads(response.content) doge_wallet_id = content['data']['id'] response = address.utils.create_address( self, token=token, data={ 'wallet_id': doge_wallet_id, 'label': 'test', 'passphrase': 'thequickbrownfox1234ABRAMAGIC' }) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(Address.objects.count(), 3) content = json.loads(response.content) self.assertEqual(content['data']['label'], 'test') # P2PKH Dogecoin addresses start with D. self.assertEqual(content['data']['p2pkh'][:1], 'D') dogecoin_address = Address.objects.get(wallet=doge_wallet_id) # Dogecoin doesn't support Bech32 addresses yet. # @TODO: see if Bech32 arrives in 1.14 #self.assertIsNone(dogecoin_address.bech32) # Create a litecoin testnet4 wallet response = wallet.utils.create_wallet(self, token=token, data={ 'label': 'default', 'currencycode': 'XLT', 'passphrase': 'thisISs3cured00d!' }) content = json.loads(response.content) litecoin_testnet4_wallet_id = content['data']['id'] address.utils.create_address(self, token=token, data={ 'wallet_id': litecoin_testnet4_wallet_id, 'label': 'testnet' }) self.assertEqual(Address.objects.count(), 4) # Manually add a live address to the wallet: https://chain.so/address/LTCTEST/n24pZghJBAjjGT5V8i8bufRuhb2LEACuzU known_address = Address(label='manual', p2pkh='n24pZghJBAjjGT5V8i8bufRuhb2LEACuzU', wallet_id=litecoin_testnet4_wallet_id) known_address.save() self.assertEqual(Address.objects.count(), 5)
def test_totp_and_static_delete(self): """ Test whether TOTP device deletion also cleans up statics. """ # Create user and log in. utils.create_user(self) response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Create TOTP device and log in with it. create_totp(self, token=token) totp_token = totp_login(self, SpaUser.objects.get()) # Create Static device. response = create_static(self, token=totp_token) self.assertEqual(StaticDevice.objects.count(), 1) statics = json.loads(response.content) # Delete TOTP device. response = totp_delete(self, token=totp_token) content = json.loads(response.content) new_token = content['token'] ''' # @TODO @FIXME static_login is broken # Make sure statics don't work (they're deleted) i = 0 for static in statics: i = i + 1 # None of our tokens should work response = static_login(self, static, token=new_token) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Only try half of our statics if i > 4: break ''' # Create new TOTP device and log in with it. create_totp(self, token=new_token) new_totp_token = totp_login(self, SpaUser.objects.get()) # Create new Static device. create_static(self, token=new_totp_token) ''' # Make sure old statics still don't work (they're deleted) for static in statics: # None of our tokens should work response = static_login(self, static, token=new_totp_token) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) ''' # Confirm we can create new statics, and that they work response = create_static(self, token=new_totp_token) self.assertEqual(StaticDevice.objects.count(), 1) statics = json.loads(response.content) token = new_totp_token ''' for static in statics: response = static_login(self, static, token=token) self.assertEqual(response.status_code, status.HTTP_201_CREATED) content = json.loads(response.content) token = content['token'] ''' token = static_login_fake(self, SpaUser.objects.get()) # Finally, delete TOTP device again with Static login, and use new token. response = totp_delete(self, token=token) content = json.loads(response.content) new_token = content['token'] response = utils.view_user(self, token=new_token) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_view_and_edit_profile(self): """ Edit a profile """ data = { 'first_name': 'first', 'last_name': 'last', } # Create user. response = utils.create_user(self) # Fail to edit name fields if not logged in. response = edit_profile(self, data=data) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # Log in. response = utils.user_login(self) content = json.loads(response.content) token = content['token'] # Edit name fields. response = edit_profile(self, token=token, data=data) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(SpaProfile.objects.count(), 1) self.assertEqual(SpaProfile.objects.get().first_name, 'first') # View the updated user profile. response = view_profile(self, token=token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['first_name'], 'first') self.assertEqual(content['last_name'], 'last') self.assertEqual(content['date_of_birth'], None) self.assertEqual(content['phone_number'], '') self.assertEqual(content['country'], '') # Edit country field, leaving name fields. response = edit_profile(self, token=token, data={'country': 'US'}) self.assertEqual(response.status_code, status.HTTP_200_OK) # View the updated user profile. response = view_profile(self, token=token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['first_name'], 'first') self.assertEqual(content['last_name'], 'last') self.assertEqual(content['date_of_birth'], None) self.assertEqual(content['phone_number'], '') self.assertEqual(content['country'], 'US') # Zero out the user profile. response = edit_profile(self, token=token, data={ 'first_name': None, 'last_name': None, 'country': None }) self.assertEqual(response.status_code, status.HTTP_200_OK) # View the now empty user profile. response = view_profile(self, token=token) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['first_name'], None) self.assertEqual(content['last_name'], None) self.assertEqual(content['date_of_birth'], None) self.assertEqual(content['phone_number'], '') self.assertEqual(content['country'], '') # Fails to set an invalid phone number. response = edit_profile(self, token=token, data={'phone_number': 'not-valid'}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Sets a valid phone number. response = edit_profile(self, token=token, data={'phone_number': '+18005551212'}) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['phone_number'], '+18005551212') # Fails to set an invalid date of birth. response = edit_profile(self, token=token, data={'date_of_birth': '01-31-1900'}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Sets a valid date of birth. response = edit_profile(self, token=token, data={'date_of_birth': '1900-01-31'}) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['date_of_birth'], '1900-01-31') # Fails to set an invalid country. response = edit_profile(self, token=token, data={'country': 'Nonsuch'}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # Sets a valid country. response = edit_profile(self, token=token, data={'country': 'italy'}) self.assertEqual(response.status_code, status.HTTP_200_OK) content = json.loads(response.content) self.assertEqual(content['country'], 'IT') # There should still only be a single database entry. self.assertEqual(SpaProfile.objects.count(), 1) self.assertEqual(SpaProfile.objects.get().last_name, None)