def parse_notification_params(params: dict, is_global: bool=False) -> dict: """ Parses and verifies all the notification params are present. Raises a MissingParameter error otherwise. Returns the params after parsing (currently does nothing, but if transformations are needed in the future, here's where that happens). In total, can raise: MissingParameterError (if required params are missing) IllegalParameterError (if the wrong types are present) EntityValidationError (if an Entity is malformed) """ # * `actor` - an Entity structure - gets turned into an Entity object when returned # * `type` - one of the type keywords # * `target` - optional, a list of Entity structures. This gets turned into a list of # entity object on return # * `object` - object of the notice, an Entity structure. For invitations, the group to be # invited to. For narratives, the narrative UPA. Gets turned into an Entity object # when returned # * `users` - a list of Entity objects, should be of either type user or group # * `level` - alert, error, warning, or request. # * `context` - optional, context of the notification, otherwise it'll be # autogenerated from the info above. if not isinstance(params, dict): raise IllegalParameterError('Expected a JSON object as an input.') required_list = ['verb', 'level'] if not is_global: required_list = required_list + ['actor', 'source', 'object'] missing = [r for r in required_list if r not in params or params.get(r) is None] if missing: raise MissingParameterError("Missing parameter{} - {}".format( "s" if len(missing) > 1 else '', ", ".join(missing) )) if not is_global: # do the entity transformations # If there are any EntityValidationErrors, they'll pop on up. params["actor"] = Entity.from_dict(params["actor"]) params["object"] = Entity.from_dict(params["object"]) if "target" in params: target = params["target"] if isinstance(target, list): params["target"] = [Entity.from_dict(t) for t in target] else: raise IllegalParameterError("Expected target to be a list of Entity structures.") if "users" in params: users = params["users"] if isinstance(users, list): params["users"] = [Entity.from_dict(u) for u in users] else: raise IllegalParameterError("Expected users to be a list of Entity structures.") return params
def test_entity_from_dict(): d = {"id": "foo", "type": "user"} e = Entity.from_dict(d) assert e.to_dict() == d assert e.id == d['id'] assert e.type == d['type'] d = {"id": "bar", "type": "group", "name": "Bar Group"} e = Entity.from_dict(d) assert e.to_dict(with_name=True) == d assert e.id == d['id'] assert e.type == d['type'] assert e.name == d['name']
def from_dict(cls, serial: dict, token: str = None) -> N: """ Returns a new Notification from a serialized dictionary (e.g. used in Mongo) """ try: assert serial is not None and isinstance(serial, dict) except AssertionError: raise InvalidNotificationError( "Can only run 'from_dict' on a dict.") required_keys = set([ 'actor', 'verb', 'object', 'source', 'level', 'created', 'expires', 'id' ]) missing_keys = required_keys.difference(set(serial.keys())) if missing_keys: raise InvalidNotificationError( 'Missing keys: {}'.format(missing_keys)) deserial = cls(Entity.from_dict(serial['actor'], token=token), str(serial['verb']), Entity.from_dict(serial['object'], token=token), serial['source'], level=str(serial['level']), target=[ Entity.from_dict(t, token=token) for t in serial.get('target', []) ], context=serial.get('context'), external_key=serial.get('external_key'), seen=serial.get('seen', False), users=[ Entity.from_dict(u, token=token) for u in serial.get('users', []) ]) deserial.created = serial['created'] deserial.expires = serial['expires'] deserial.id = serial['id'] return deserial
def test_entity_eq(): eid1 = "foo" eid2 = "bar" etype1 = "user" etype2 = "group" e11 = Entity(eid1, etype1) e11_2 = Entity(eid1, etype1) e12 = Entity(eid1, etype2) e21 = Entity(eid2, etype1) e22 = Entity(eid2, etype2) assert e11 == e11 assert e11 == e11_2 assert e12 != e11 assert e11 != e12 assert e11 != e22 assert e21 != e11 assert e22 == Entity.from_dict({"id": eid2, "type": etype2})
assert_is_uuid, test_config ) from feeds.exceptions import ( MissingVerbError, MissingLevelError, InvalidExpirationError, InvalidNotificationError ) from feeds.entity.entity import Entity cfg = test_config() # some dummy "good" inputs for testing actor_d = {"id": "test_actor", "type": "user"} actor = Entity.from_dict(actor_d) verb_inf = "invite" verb_past = "invited" verb_id = 1 object_d = {"id": "foo", "type": "workspace"} note_object = Entity.from_dict(object_d) source = "groups" level_name = "warning" level_id = 2 target_d = {"id": "target_actor", "type": "user"} target = [Entity.from_dict(target_d)] context = {"some": "context"} expires = epoch_ms() + (10 * 24 * 60 * 60 * 1000) # 10 days external_key = "an_external_key" user_d = {"id": "user_actor", "type": "user"} users = [Entity.from_dict(user_d)]
def test_entity_from_dict_fail(d, err, msg): with pytest.raises(err) as e: Entity.from_dict(d) assert msg in str(e)