def test_deepcopy(self): """ """ from max.utils.dicts import deepcopy from max.models import User actor = User.from_object(None, {'username': '******', 'displayName': 'Sheldon'}) old_dict = { 'level1_key': { 'level2_key': { 'level3_key': {}, 'level3_value': 54 }, 'level2_value': [ {'inner': 'item'} ] }, 'actor': actor } dict_copy = deepcopy(old_dict) # Dicts and lists get copied self.assertNotEqual(id(old_dict), id(dict_copy)) self.assertNotEqual(id(old_dict['level1_key']), id(dict_copy['level1_key'])) self.assertNotEqual(id(old_dict['level1_key']['level2_key']), id(dict_copy['level1_key']['level2_key'])) self.assertNotEqual(id(old_dict['level1_key']['level2_value']), id(dict_copy['level1_key']['level2_value'])) self.assertNotEqual(id(old_dict['level1_key']['level2_key']['level3_key']), id(dict_copy['level1_key']['level2_key']['level3_key'])) self.assertNotEqual(id(old_dict['level1_key']['level2_value'][0]), id(dict_copy['level1_key']['level2_value'][0])) # Primitives and objects remain referenced self.assertEqual(id(old_dict['actor']), id(dict_copy['actor'])) self.assertEqual(id(old_dict['level1_key']['level2_key']['level3_value']), id(dict_copy['level1_key']['level2_key']['level3_value'])) self.assertEqual(id(old_dict['level1_key']['level2_value'][0]['inner']), id(dict_copy['level1_key']['level2_value'][0]['inner']))
def test_start_conversation_with_nonvisible_as_visible_sharing_contexts(self): from .mockers import message from .mockers import subscribe_context, create_context """ Given i'm a visible person When I try to start a conversation with a nonvisible And we share a context Then I cannot start the conversation """ username_visible1 = 'user1' username_nonvisible1 = 'usernonvisible1' self.create_user(username_visible1) self.create_user(username_nonvisible1) self.create_context(create_context) self.admin_subscribe_user_to_context(username_visible1, subscribe_context) self.admin_subscribe_user_to_context(username_nonvisible1, subscribe_context) message = deepcopy(message) message['contexts'][0]['participants'] = [username_nonvisible1, username_visible1] self.testapp.post('/admin/security/roles/%s/users/%s' % ('NonVisible', username_nonvisible1), "", oauth2Header(test_manager), status=201) self.testapp.post('/conversations', json.dumps(message), oauth2Header(username_visible1), status=403)
def create_activity(self, username, activity, oauth_username=None, expect=201, note=None): oauth_username = oauth_username is not None and oauth_username or username new_activity = deepcopy(activity) if note is not None: new_activity['object']['content'] = note res = self.testapp.post('/people/%s/activities' % username, json.dumps(new_activity), oauth2Header(oauth_username), status=expect) return res
def impersonate_payload(source, username): """ Adds an actor to a payload, to impersonate it """ base = deepcopy(source) base['actor'] = { 'objectType': 'person', 'username': username } return base
def from_object(cls, request, source): instance = cls(request) instance.update(source) instance.old.update(source) instance.old = deepcopy(flatten(instance.old)) if 'id' in source: instance['_id'] = source['id'] instance._post_init_from_object(source) instance.asleep = True return instance
def test_create_activity_with_published_date(self): """ doctest .. http:post:: /people/{username}/activities """ from .mockers import user_status as activity old_activity = deepcopy(activity) old_activity['published'] = '2010-01-01T00:01:30.000Z' username = '******' self.create_user(username) res = self.testapp.post('/people/%s/activities' % username, json.dumps(old_activity), oauth2Header(username), status=201) self.assertEqual(res.json['published'], '2010-01-01T00:01:30Z')
def wake(self): """ Tries to recover a lazy object from the database. Instances marked as asleep = True, are the only ones that will be waked up. """ if self.asleep: obj = self.alreadyExists() if obj: self.update(obj) self.old.update(obj) self.old = deepcopy(flatten(self.old))
def test_start_conversation_with_visible_as_visible_without_sharing_contexts(self): from .mockers import message """ Given i'm a visible person When I try to start a conversation with a visible Then I can start the conversation """ username_visible1 = 'user1' username_visible2 = 'user2' self.create_user(username_visible1) self.create_user(username_visible2) message = deepcopy(message) message['contexts'][0]['participants'] = [username_visible2, username_visible1] self.testapp.post('/conversations', json.dumps(message), oauth2Header(username_visible1), status=201)
def test_user_activities_stats_per_year(self): from .mockers import user_status username = '******' self.create_user(username) self.create_activity(username, user_status) old_activity = deepcopy(user_status) old_activity['published'] = '2010-01-01T00:01:30.000Z' for i in range(11): self.create_activity(username, old_activity, note=str(i)) res = self.testapp.get('/people/%s/activities?date_filter=2010' % username, '', oauth2Header(username), status=200) self.assertEqual(len(res.json), 10) res = self.testapp.head('/people/%s/activities?date_filter=2010' % username, oauth2Header(username), status=200) self.assertEqual(res.headers.get('X-totalItems'), '11')
def test_start_conversation_with_nonvisible_as_nonvisible_without_sharing_contexts(self): from .mockers import message """ Given i'm a nonvisible person When I try to start a conversation with a nonvisible Then I can start the conversation """ username_nonvisible1 = 'usernonvisible1' username_nonvisible2 = 'usernonvisible2' self.create_user(username_nonvisible1) self.create_user(username_nonvisible2) message = deepcopy(message) message['contexts'][0]['participants'] = [username_nonvisible1, username_nonvisible2] self.testapp.post('/admin/security/roles/%s/users/%s' % ('NonVisible', username_nonvisible1), "", oauth2Header(test_manager), status=201) self.testapp.post('/admin/security/roles/%s/users/%s' % ('NonVisible', username_nonvisible2), "", oauth2Header(test_manager), status=201) self.testapp.post('/conversations', json.dumps(message), oauth2Header(username_nonvisible1), status=201)
def search(self, query, keep_private_fields=True, count=False, **kwargs): """ Performs a search on the mongoDB Kwargs may contain: limit: Count of objects to be returned from search before: An id pointing to an activity, whose older fellows will be fetched after: An id pointing to an activity, whose newer fellows will be fetched hashtag: A list of hastags to filter activities by keywords: A list of keywords to filter activities by actor: A username to filter activities by actor tags: A list of tags to filter contexts object_tags: A list of tags to filter context activities twitter_enabled: Boolean for returning objects Twitter attributes """ search_query = deepcopy(query) # Extract known params from kwargs limit = kwargs.get('limit', None) flatten = kwargs.get('flatten', 0) after = kwargs.get('after', None) before = kwargs.get('before', None) hashtag = kwargs.get('hashtag', None) keywords = kwargs.get('keywords', None) actor = kwargs.get('actor', None) favorites = kwargs.get('favorites', None) username = kwargs.get('username', None) tags = kwargs.get('tags', None) context_tags = kwargs.get('context_tags', None) twitter_enabled = kwargs.get('twitter_enabled', None) sort_direction = kwargs.get('sort_direction', DESCENDING) sort_params = kwargs.get('sort_params', [('_id', sort_direction)]) date_filter = kwargs.get('date_filter', None) show_fields = kwargs.get('show_fields', None) offset_field = kwargs.get('offset_field', None) sort_by_field = kwargs.get('sort_by_field', None) if sort_by_field: sort_params = [(sort_by_field, sort_direction)] # After & before contains the ObjectId of the offset that # we must use to skip results when paging results. # Depending on which of the two params is used, we'll determine # the direction of the filtering and store the actual offset # in its definitive variable query offset. if after or before: condition = after and '$gt' or '$lt' offset = after and after or before else: # conflicting offset definition will get no offset offset = None # If we have an offset defined, insert the filtering condition # on the search query. if offset: default_offset_field = sort_params[0][0] if sort_params else '_id' offset_field = offset_field if offset_field else default_offset_field search_query.update({offset_field: {condition: offset}}) if hashtag: # Filter the query to only objects containing certain hashtags # Filter the query to only objects containing certain hashtags hashtag_query = {'object._hashtags': {'$all': hashtag}} search_query.update(hashtag_query) if actor: # Filter the query to only objects containing certain hashtags username_query = {'actor.username': actor} search_query.update(username_query) if favorites: # filter the query to only objectes favorited by the requesting actor favorites_query = {'favorites.username': favorites} search_query.update(favorites_query) if keywords: keyword_field = '_keywords' # XXX Temporary fix to filter by comment keywords if search_query.get('verb') == 'comment': keyword_field = 'object._keywords' # Filter the query to only objects containing certain keywords keywords_query = {keyword_field: {'$all': keywords}} search_query.update(keywords_query) if username: # Filter the query to only objects containing certain hashtags username_query = { "$or": [ {"username": {"$regex": username, "$options": "i", }}, {"displayName": {"$regex": username, "$options": "i", }} ] } search_query.update(username_query) if tags: # Filter the query to only objects containing certain tags tags_query = {'tags': {'$all': tags}} search_query.update(tags_query) if context_tags: # Filter the query to only objects containing certain tags object_tags_query = {'contexts.tags': {'$all': context_tags}} search_query.update(object_tags_query) if twitter_enabled: # Filter the query to only objects (contexts) containing a certain # twitter_hashtag twe_query = { "$or": [ {"twitterUsername": {"$exists": True}}, {"twitterHashtag": {"$exists": True}}, ] } search_query.update(twe_query) if date_filter: # Filter the query to objects matching a specific published date range search_query.update({'published': date_filter}) # Catch mixed unoptimal $or queries and reformulate if '$or' in search_query and len(search_query.keys()) > 1: mixed_specs = {key: value for key, value in search_query.items() if key != '$or'} for spec in search_query['$or']: spec.update(mixed_specs) for spec in mixed_specs: del search_query[spec] # Cursor is lazy, but better to execute search here for mental sanity self.setVisibleResultFields(show_fields) cursor = self.collection.find(search_query, self.show_fields) # If it's a count search, return the cursor's count before sorting and limiting if count: return cursor.count() # Sort the results cursor = cursor.sort(sort_params) if limit: cursor = cursor.limit(limit + 1) # Unpack the lazy cursor, # Wrap the result in its Mad Class, # and flattens it if specified return ResultsWrapper(self.request, cursor, flatten=flatten, keep_private_fields=keep_private_fields, limit=limit)