async def test_single_resolver(query): with mock.patch('mongodb_streams.find_one', ) as m: m.side_effect = [dict(username='******'), dict(name='name')] r = await query(''' { bot(where: {username: {eq: "ciao"}}) { username user { name } } } ''') pretty(r) pretty(m.call_args_list) assert r == { "data": { "bot": { "username": "******", "user": { "name": "name" } } } }
async def test_many_relation(query): with mock.patch('mongodb_streams.find_one', ) as m: m.side_effect = [[ dict(username='******'), ], [dict(value=89, timestamp=34)]] r = await query(''' { bots( last: 50, ) { nodes { username _id likes_over_time( first: 20 cursorField: value ) { nodes { value timestamp } } } } } ''') pretty(r) pretty(m.call_args_list)
def test_first_and_after_desc(query, users: Collection): assert not list(users.find({})) LENGTH = 20 users.insert_many( [dict(_id=ObjectId(), name=str(i)) for i in range(LENGTH)]) q = r""" query search($first: Int!, $after: AnyScalar) { UserNodes(first: $first, after: $after, cursorField: _id, direction: DESC) { nodes { _id name url } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } """ res = query(q, dict(first=10)) pretty(res) assert res["data"]["UserNodes"]["nodes"] assert len(res["data"]["UserNodes"]["nodes"]) == 10 after = res["data"]["UserNodes"]["pageInfo"]["endCursor"] res = query(q, dict(first=10, after=after)) pretty(res) assert res["data"]["UserNodes"]["nodes"] assert len(res["data"]["UserNodes"]["nodes"]) == 10
def test_before_and_last_different_cursor(query, users: Collection): assert not list(users.find({})) users.insert_many([dict(_id=ObjectId(), name=str(i)) for i in LETTERS]) q = r""" query search($last: Int!, $before: AnyScalar) { UserNodes(last: $last, before: $before, cursorField: name, direction: ASC) { nodes { _id name url } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } """ res = query(q, dict(last=10)) pretty(res) assert res["data"]["UserNodes"]["nodes"] assert len(res["data"]["UserNodes"]["nodes"]) == 10 before = res["data"]["UserNodes"]["pageInfo"]["startCursor"] res = query(q, dict(last=10, before=before)) pretty(res) assert res["data"]["UserNodes"]["nodes"] assert len(res["data"]["UserNodes"]["nodes"]) == 10
def test_get_user(query): q = """ { User { _id name } } """ res = query(q) pretty(res)
def test_no_error(query, users: Collection): assert not list(users.find({})) q = """ { User { _id name } } """ res = query(q) pretty(res) assert not res.get("errors")
async def test_many_resolver(query): with mock.patch('mongodb_streams.find', ) as m: bots = [dict(_id=str(i), username=str(i)) for i in range(20)] m.return_value = bots r = await query(''' { bots(first: 3) { nodes { username } } } ''') pretty(r, ) print(m.call_args)
def test_objectid_error(query, users: Collection): assert not list(users.find({})) q = """ { User(where: {_id: {eq: "kjh"}}) { _id name } } """ res = query(q) pretty(res) assert res["errors"] pretty(res["errors"][0]["message"])
def test_single_resolver(query): with mock.patch("mongodb_streams.find_one") as m: m.side_effect = [dict(surname="xxx")] r = query(""" { User(where: {surname: {eq: "xxx"}}) { _id name surname } } """) pretty(r) pretty(m.call_args_list) assert r["data"]["User"]["surname"] == "xxx"
def test_get_user_real(query, users: Collection): assert not list(users.find({})) users.insert_one(dict(name="xxx")) q = """ { User { _id name url } } """ res = query(q) pretty(res) assert res["data"]["User"]
def now_handler(event, ctx): handler = Mangum(app, ) pretty(json.loads(event['body'])) try: res = handler(map_event(event), ctx) pretty(res) return map_response(res) except Exception as e: traceback.print_exc() return { "statusCode": 500, "headers": { "content-type": "text/plain; charset=utf-8" }, "body": str(e), }
def test_cursor_field(query): with mock.patch("mongodb_streams.find") as m: xs = [dict(surname=i) for i in iter(LETTERS)] m.return_value = xs r = query(""" { UserNodes(cursorField: surname) { nodes { surname } } } """) pretty(r) print(m.call_args) nodes = r["data"]["UserNodes"]["nodes"] assert len(nodes) == len(LETTERS) assert sorted(nodes, key=lambda x: x["surname"]) == nodes
def test_many_users(query): with mock.patch("mongodb_streams.find") as m: m.side_effect = [[dict(surname="xxx")], [dict(surname="xxx")]] r = query(""" { UserNodes(where: { surname: { eq: "xxx" } }) { nodes { surname } } } """) pretty(r) pretty(m.call_args_list) nodes = r["data"]["UserNodes"]["nodes"] assert len(nodes) == 1 assert nodes[0]["surname"] == "xxx"
def test_id_is_searchable(query, users: Collection): assert not list(users.find({})) id = ObjectId() users.insert_one(dict(_id=id, name="xxx")) q = """ query search($id: ObjectId!) { User(where: {_id: {eq: $id}}) { _id name url } } """ res = query(q, dict(id=str(id))) pretty(res) assert res["data"]["User"] assert res["data"]["User"]["_id"] == str(id)
def test_many_resolver(query): with mock.patch("mongodb_streams.find") as m: bots = [dict(_id=str(i), username=str(i)) for i in range(20)] m.return_value = bots r = query(""" { UserNodes(where: { surname: { eq: "xxx" } }) { nodes { surname friends { nodes { surname } } } } } """) pretty(r) print(m.call_args)
async def connection_resolver( collection: AsyncIOMotorCollection, where: dict, cursorField, # needs to exist always at least one, the fisrst is the cursorField pagination: dict, scalar_name, pipeline=[], ): if os.getenv('DEBUG'): print('executing connection_resolver') pretty({ 'where': where, 'cursorField': cursorField, 'pagination': pagination, 'scalar_name': scalar_name, 'collection': collection, 'pipeline': pipeline, }) direction = pagination['direction'] first, last = pagination.get('first'), pagination.get('last'), after, before = pagination.get('after'), pagination.get('before') if after: after = INPUT_COERCERS.get(scalar_name, lambda x: x)(after) if before: before = INPUT_COERCERS.get(scalar_name, lambda x: x)(before) first = first or 0 last = last or 0 if not first and not last: if after: first = DEFAULT_NODES_COUNT elif before: last = DEFAULT_NODES_COUNT else: first = DEFAULT_NODES_COUNT if after and not (first or before): raise Exception('need `first` or `before` if using `after`') if before and not (last or after): raise Exception('need `last` or `after` if using `before`') if first and last: raise Exception('no sense using first and last together') args: dict = dict() lt = '$gt' if direction == DESCENDING else '$lt' gt = '$lt' if direction == DESCENDING else '$gt' if after != None and before != None: args.update( dict(match={ **where, cursorField: { gt: after, lt: before }, }, )) elif after != None: args.update(dict(match={ **where, cursorField: { gt: after, }, }, )) elif before != None: args.update(dict(match={ **where, cursorField: { lt: before }, }, )) else: args = dict(match=where, ) if pipeline: args.update(dict(pipeline=pipeline)) sorting = direction if not last else opposite_direction(direction) args.update(dict(sort={cursorField: sorting})) if last: args.update(dict(limit=last + 1, )) if first: args.update(dict(limit=first + 1, )) # elif first: # count = await mongodb_streams.count_documents(collection, args['match'], pipeline=pipeline) # toSkip = count - (last + 1) # args.update(dict(skip=max(toSkip, 0))) args.update(dict(max_len=10000)) # pretty(args) nodes = await mongodb_streams.find(collection, **args) hasNext = None hasPrevious = None if first: hasNext = len(nodes) == (first + 1) nodes = nodes[:-1] if hasNext else nodes if last: nodes = list(reversed(nodes)) hasPrevious = len(nodes) == (last + 1) nodes = nodes[1:] if hasPrevious else nodes end_cursor = nodes[-1].get(cursorField) if nodes else None start_cursor = nodes[0].get(cursorField) if nodes else None return { 'nodes': nodes, 'edges': lmap( lambda node: dict(node=node, cursor=OUTPUT_COERCERS[scalar_name] (node.get(cursorField))), nodes), 'pageInfo': { 'endCursor': end_cursor and OUTPUT_COERCERS[scalar_name](end_cursor), 'startCursor': start_cursor and OUTPUT_COERCERS[scalar_name](start_cursor), 'hasNextPage': hasNext, 'hasPreviousPage': hasPrevious, } }
def hello(request): pretty(dir(request)) pretty(request.json) return "Hello world!"