def test_base_uris():
    from dtool_lookup_server.utils import _dict_to_mongo_query

    # Test single base URI.
    query = dict(base_uris=["s3://snow-white"])
    expected_mongo_query = {"base_uri": "s3://snow-white"}
    assert _dict_to_mongo_query(query) == expected_mongo_query

    # Test multiple base URIs.
    query = dict(base_uris=["s3://snow-white", "s3://mr-men"])
    expected_mongo_query = {"$or": [
        {"base_uri": "s3://snow-white"},
        {"base_uri": "s3://mr-men"}
    ]}
    assert _dict_to_mongo_query(query) == expected_mongo_query
def test_tags():
    from dtool_lookup_server.utils import _dict_to_mongo_query

    # Test single tag.
    query = dict(tags=["evil"])
    expected_mongo_query = {"tags": "evil"}
    assert _dict_to_mongo_query(query) == expected_mongo_query

    # Test multiple tags.
    query = dict(tags=["evil", "good"])
    expected_mongo_query = {"tags": {"$all": ["evil", "good"]}}
    assert _dict_to_mongo_query(query) == expected_mongo_query

    # Test empty list.
    query = dict(tags=[])
    assert _dict_to_mongo_query(query) == {}
def test_creator_usernames():
    from dtool_lookup_server.utils import _dict_to_mongo_query

    # Test single creator username.
    query = dict(creator_usernames=["grumpy"])
    expected_mongo_query = {"creator_username": "******"}
    assert _dict_to_mongo_query(query) == expected_mongo_query

    # Test multiple creator usernames.
    query = dict(creator_usernames=["grumpy", "dopey"])
    expected_mongo_query = {"$or": [
        {"creator_username": "******"},
        {"creator_username": "******"}
    ]}
    assert _dict_to_mongo_query(query) == expected_mongo_query

    # Test empty list.
    query = dict(creator_usernames=[])
    assert _dict_to_mongo_query(query) == {}
def test_combinations():

    from dtool_lookup_server.utils import _dict_to_mongo_query

    query = dict(
        free_text="apple",
        base_uris=["s3://snow-white"],
        creator_usernames=["grumpy", "dopey"],
        tags=["good", "evil"]
    )
    expected_mongo_query = {}
    expected_mongo_query = {
        "$and": [
            {"$text": {"$search": "apple"}},
            {"$or": [
                {"creator_username": "******"},
                {"creator_username": "******"}
            ]
            },
            {"base_uri": "s3://snow-white"},
            {"tags": {"$all": ["good", "evil"]}}
        ]
    }
    assert _dict_to_mongo_query(query) == expected_mongo_query
def dependency_graph_by_user_and_uuid(username,
                                      uuid,
                                      dependency_keys=Config.DEPENDENCY_KEYS):
    """Aggregate all datasets within the same dependency graph as uuid.

    :param username: username
    :param uuid: UUID of dataset to start dependency graph search from
    :returns: List of dicts if user is valid and has access to datasets.
              Empty list if user is valid but has not got access to any
              datasets.
    :raises: AuthenticationError if user is invalid.
    """

    # enable undirected view on dependency graph
    if not Config.ENABLE_DEPENDENCY_VIEW:
        logger.warning("Received dependency graph request from user '{}', but "
                       "feature is disabled.".format(username))
        return []  # silently reject request

    # disable dynamic dependency keys
    if not Config.DYNAMIC_DEPENDENCY_KEYS and sorted(
            dependency_keys) != sorted(Config.DEPENDENCY_KEYS):
        logger.warning(
            "Received dependency graph request for dynamic keys '{}' from user "
            "'{}', but dynamic dependency key feature is disabled. Set env "
            "var DTOOL_LOOKUP_SERVER_DYNAMIC_DEPENDENCY_KEYS=True to enable.".
            format(dependency_keys, username))
        dependency_keys = Config.DEPENDENCY_KEYS

    dependency_view = _get_dependency_view_from_keys(dependency_keys)

    # in the pipeline, we need to filter privileges two times. Initially,
    # when looking up the specified uuid , and subsequently after building
    # the dependency graph for the hypothetical case of the user not having
    # sufficient privileges to view all datasets within the same graph.
    # Building those pre- and post-queries relies on the _dict_to_mongo_query
    # utility function and hence requires the 'uuids' keyword configured as
    # an allowed query key. This is the default configuration in config.Config.
    pre_query = _preprocess_privileges(username, {'uuids': [uuid]})
    post_query = _preprocess_privileges(username, {})

    # If there are no base URIs at this point it means that the user has not
    # got privileges to search for anything.
    if (len(pre_query["base_uris"]) == 0) or len(post_query["base_uris"]) == 0:
        return []

    pre_query = _dict_to_mongo_query(pre_query)
    post_query = _dict_to_mongo_query(post_query)

    datasets = []
    mongo_aggregation = query_dependency_graph(
        pre_query=pre_query,
        post_query=post_query,
        dependency_keys=dependency_keys,
        mongo_dependency_view=dependency_view)
    logger.debug("Constructed mongo aggregation: {}".format(mongo_aggregation))
    cx = mongo.db[MONGO_COLLECTION].aggregate(mongo_aggregation)

    for ds in cx:
        # Convert datetime object to float timestamp.
        for key in ("created_at", "frozen_at"):
            if key in ds:
                datetime_obj = ds[key]
                ds[key] = dtoolcore.utils.timestamp(datetime_obj)

        datasets.append(ds)

    return datasets
def test_free_text():
    """Should return {"$text": {"$search": "free_text_here"}}"""
    from dtool_lookup_server.utils import _dict_to_mongo_query
    query = dict(free_text="free_text_here")
    expected_mongo_query = {"$text": {"$search": "free_text_here"}}
    assert _dict_to_mongo_query(query) == expected_mongo_query
def test_empty_dict():
    """An empty dict should return query for all datasets."""
    from dtool_lookup_server.utils import _dict_to_mongo_query
    assert _dict_to_mongo_query({}) == {}