Merge pull request #3124 from bison/update-user-schema

endpoints/api: Allow null fields in user metadata
This commit is contained in:
Brad Ison 2018-06-27 17:02:57 -04:00 committed by GitHub
commit 06f3a7d20a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 27 deletions

View file

@ -436,10 +436,18 @@ def update_user_metadata(user, metadata=None):
metadata = metadata if metadata is not None else {} metadata = metadata if metadata is not None else {}
with db_transaction(): with db_transaction():
user.given_name = metadata.get('given_name') or user.given_name if 'given_name' in metadata:
user.family_name = metadata.get('family_name') or user.family_name user.given_name = metadata['given_name']
user.company = metadata.get('company') or user.company
user.location = metadata.get('location') or user.location if 'family_name' in metadata:
user.family_name = metadata['family_name']
if 'company' in metadata:
user.company = metadata['company']
if 'location' in metadata:
user.location = metadata['location']
user.save() user.save()
# Remove any prompts associated with the user's metadata being needed. # Remove any prompts associated with the user's metadata being needed.

View file

@ -0,0 +1,42 @@
import pytest
from mock import patch
from endpoints.api.test.shared import conduct_api_call
from endpoints.api.user import User
from endpoints.test.shared import client_with_identity
from features import FeatureNameValue
from test.fixtures import *
def test_user_metadata_update(client):
with patch('features.USER_METADATA', FeatureNameValue('USER_METADATA', True)):
with client_with_identity('devtable', client) as cl:
metadata = {
'given_name': 'Quay',
'family_name': 'User',
'location': 'NYC',
'company': 'Red Hat',
}
# Update all user metadata fields.
conduct_api_call(cl, User, 'PUT', None, body=metadata)
# Test that they were successfully updated.
user = conduct_api_call(cl, User, 'GET', None).json
for field in metadata:
assert user.get(field) == metadata.get(field)
# Now nullify one of the fields, and remove another.
metadata['company'] = None
location = metadata.pop('location')
conduct_api_call(cl, User, 'PUT', None, body=metadata)
user = conduct_api_call(cl, User, 'GET', None).json
for field in metadata:
assert user.get(field) == metadata.get(field)
# The location field should be unchanged.
assert user.get('location') == location

View file

@ -236,19 +236,19 @@ class User(ApiResource):
'description': 'Custom email address for receiving invoices', 'description': 'Custom email address for receiving invoices',
}, },
'given_name': { 'given_name': {
'type': 'string', 'type': ['string', 'null'],
'description': 'The optional entered given name for the user', 'description': 'The optional entered given name for the user',
}, },
'family_name': { 'family_name': {
'type': 'string', 'type': ['string', 'null'],
'description': 'The optional entered family name for the user', 'description': 'The optional entered family name for the user',
}, },
'company': { 'company': {
'type': 'string', 'type': ['string', 'null'],
'description': 'The optional entered company for the user', 'description': 'The optional entered company for the user',
}, },
'location': { 'location': {
'type': 'string', 'type': ['string', 'null'],
'description': 'The optional entered location for the user', 'description': 'The optional entered location for the user',
}, },
}, },
@ -367,22 +367,16 @@ class User(ApiResource):
model.user.update_email(user, new_email, auto_verify=not features.MAILING) model.user.update_email(user, new_email, auto_verify=not features.MAILING)
if features.USER_METADATA: if features.USER_METADATA:
metadata_fields = ('given_name', 'family_name', 'company', 'location') metadata = {}
if any(field in user_data for field in metadata_fields):
model.user.update_user_metadata(user, {
'given_name': user_data.get('given_name'),
'family_name': user_data.get('family_name'),
'company': user_data.get('company'),
'location': user_data.get('location'),
})
ua_mdata_future = user_analytics.change_metadata( for field in ('given_name', 'family_name', 'company', 'location'):
user.email, if field in user_data:
user_data.get('given_name'), metadata[field] = user_data.get(field)
user_data.get('family_name'),
user_data.get('company'), if len(metadata) > 0:
user_data.get('location'), model.user.update_user_metadata(user, metadata)
)
ua_mdata_future = user_analytics.change_metadata(user.email, **metadata)
ua_mdata_future.add_done_callback(build_error_callback('Change metadata failed')) ua_mdata_future.add_done_callback(build_error_callback('Change metadata failed'))
# Check for username rename. A username can be renamed if the feature is enabled OR the user # Check for username rename. A username can be renamed if the feature is enabled OR the user

View file

@ -146,7 +146,7 @@
$scope.updateMetadataInfo = function(info, callback) { $scope.updateMetadataInfo = function(info, callback) {
var details = {}; var details = {};
details[info.field] = info.value; details[info.field] = (info.value === '' ? null : info.value);
var errorDisplay = ApiService.errorDisplay('Could not update ' + info.title, callback); var errorDisplay = ApiService.errorDisplay('Could not update ' + info.title, callback);

View file

@ -211,7 +211,7 @@
dialog-form="context.metadataform"> dialog-form="context.metadataform">
<form name="context.metadataform" class="co-single-field-dialog"> <form name="context.metadataform" class="co-single-field-dialog">
Please enter an updated {{ changeMetadataInfo.title }}: Please enter an updated {{ changeMetadataInfo.title }}:
<input type="text" class="form-control" ng-model="changeMetadataInfo.value" required> <input type="text" class="form-control" ng-model="changeMetadataInfo.value">
</form> </form>
</div> </div>

View file

@ -97,7 +97,7 @@ class _MarketoAnalyticsClient(object):
lookupField='id', lookupField='id',
) )
def change_metadata(self, email, given_name, family_name, company, location): def change_metadata(self, email, given_name=None, family_name=None, company=None, location=None):
lead_data = self._get_lead_metadata(given_name, family_name, company, location) lead_data = self._get_lead_metadata(given_name, family_name, company, location)
if not lead_data: if not lead_data:
return return