def test_parser_query_inline_fragment(self): query = """ query GetFilm { returnOfTheJedi: film(id: "1") { ... on Film { title director } } } """ parser = QueryParser(self.swapi_schema) parsed = parser.parse(query) expected = asdict( ParsedQuery( query=query, objects=[ ParsedOperation( name="GetFilm", type="query", children=[ ParsedObject( name="GetFilmData", fields=[ ParsedField( name="returnOfTheJedi", type="Film", nullable=True, ) ], children=[ ParsedObject( name="Film", fields=[ ParsedField(name="title", type="str", nullable=False), ParsedField( name="director", type="str", nullable=False, ), ], ) ], ) ], ) ], )) parsed_dict = asdict(parsed) assert bool(parsed) assert parsed_dict == expected, str(DeepDiff(parsed_dict, expected))
def test_non_nullable_list(self): PersonType = GraphQLObjectType( "Person", lambda: {"name": GraphQLField(GraphQLString)}) schema = GraphQLSchema(query=GraphQLObjectType( name="RootQueryType", fields={ "people": GraphQLField( GraphQLList(GraphQLNonNull(PersonType)), resolve=lambda obj, info: {"name": "eran"}, ) }, )) query = """ query GetPeople { people { name } } """ parser = QueryParser(schema) dataclass_renderer = DataclassesRenderer(schema) parsed = parser.parse(query) rendered = dataclass_renderer.render(parsed) m = self.load_module(rendered) mock_client = MagicMock() mock_client.call = MagicMock(return_value=""" { "data": { "people": [ { "name": "eran" }, { "name": "eran1" } ] } } """) result = m.GetPeople.execute(mock_client) assert result assert isinstance(result, m.GetPeople.GetPeopleData) assert len(result.people) == 2 assert result.people[0].name == "eran" assert result.people[1].name == "eran1"
def verify_file( self, filename: str, parser: QueryParser, renderer: DataclassesRenderer ) -> None: root, _s = os.path.splitext(filename) target_filename = "".join([root, ".py"]) dir_name = os.path.dirname(target_filename) with open(filename, "r") as fin: query = fin.read() parsed = parser.parse(query) rendered = renderer.render(parsed) with open(target_filename, "r") as f: file_content = f.read() self.assert_rendered_file(target_filename, file_content, rendered) enums = renderer.render_enums(parsed) for enum_name, code in enums.items(): target_enum_filename = os.path.join( dir_name, "".join([get_enum_filename(enum_name), ".py"]) ) with open(target_enum_filename, "r") as f: file_content = f.read() self.assert_rendered_file(target_enum_filename, file_content, code) input_objects = renderer.render_input_objects(parsed) for input_object_name, code in input_objects.items(): target_input_object_filename = os.path.join( dir_name, "".join([get_input_filename(input_object_name), ".py"]) ) with open(target_input_object_filename, "r") as f: file_content = f.read() self.assert_rendered_file( target_input_object_filename, file_content, code )
def test_parser_fails_invalid_query(self): query = """ query ShouldFail { allFilms { totalCount edges { node { title nonExistingField } } } } """ parser = QueryParser(self.swapi_schema) with self.assertRaises(InvalidQueryError): parser.parse(query)
def setUp(self) -> None: if "SWAPI_SCHEMA" not in globals(): filename = os.path.join(os.path.dirname(__file__), "fixtures/swapi-schema.graphql") globals()["SWAPI_SCHEMA"] = load_schema(filename) self.swapi_schema = globals()["SWAPI_SCHEMA"] self.swapi_parser = QueryParser(self.swapi_schema) if "GITHUB_SCHEMA" not in globals(): filename = os.path.join(os.path.dirname(__file__), "fixtures/github-schema.graphql") globals()["GITHUB_SCHEMA"] = load_schema(filename) self.github_schema = globals()["GITHUB_SCHEMA"] self.github_parser = QueryParser(self.github_schema) self.swapi_dataclass_renderer = DataclassesRenderer(self.swapi_schema) self.github_dataclass_renderer = DataclassesRenderer( self.github_schema)
def test_parser_fails_on_nameless_op(self): query = """ { allFilms { totalCount edges { node { id title director } } } } """ parser = QueryParser(self.swapi_schema) with self.assertRaises(AnonymousQueryError): parser.parse(query)
def test_graphql_compilation(schema_library: str, graphql_library: str) -> None: schema = compile_schema_library(schema_library) fragment_library = read_fragment_queries(graphql_library) file_names = glob.glob( os.path.join(graphql_library, "**/*.graphql"), recursive=True ) query_parser = QueryParser(schema) query_renderer = DataclassesRenderer(schema) for file_name in file_names: process_file( file_name, schema, query_parser, query_renderer, fragment_library, True )
def test_graphql_compilation(self, mock_popen, mock_path_exists: MagicMock) -> None: schema_library = pkg_resources.resource_filename(__name__, "schema") schema = compile_schema_library(schema_library) graphql_library = pkg_resources.resource_filename(__name__, "graphql") fragment_library = read_fragment_queries(graphql_library) query_parser = QueryParser(schema) query_renderer = DataclassesRenderer(schema) filenames = glob.glob( os.path.join(graphql_library, "**/*.graphql"), recursive=True ) for filename in filenames: process_file( filename, schema, query_parser, query_renderer, fragment_library, True )
def test_graphql_compilation(self, mock_popen, mock_path_exists): schema_library = pkg_resources.resource_filename(__name__, "schema") schema = compile_schema_library(schema_library) graphql_library = pkg_resources.resource_filename(__name__, "graphql") filenames = glob.glob( os.path.join(graphql_library, "**/*.graphql"), recursive=True ) query_parser = QueryParser(schema) query_renderer = DataclassesRenderer(schema) for filename in filenames: with open(filename) as f: query = parse(f.read()) usages = find_deprecated_usages(schema, query) assert len(usages) == 0, ( f"Graphql file name {filename} uses " f"deprecated fields {usages}" ) self.verify_file(filename, query_parser, query_renderer)
def test_parser_mutation(self): query = """ mutation CreateHero { createHero { hero { name } ok } } """ parser = QueryParser(self.swapi_schema) parsed = parser.parse(query) expected = asdict( ParsedQuery( query=query, objects=[ ParsedOperation( name="CreateHero", type="mutation", children=[ ParsedObject( name="CreateHeroData", fields=[ ParsedField( name="createHero", type="CreateHeroPayload", nullable=True, ) ], children=[ ParsedObject( name="CreateHeroPayload", fields=[ ParsedField(name="hero", type="Hero", nullable=True), ParsedField(name="ok", type="bool", nullable=True), ], children=[ ParsedObject( name="Hero", fields=[ ParsedField( name="name", type="str", nullable=False, ) ], ) ], ) ], ) ], ) ], )) parsed_dict = asdict(parsed) assert bool(parsed) assert parsed_dict == expected, str(DeepDiff(parsed_dict, expected))
def test_parser_connection_query(self): query = """ query GetAllFilms { allFilms { count: totalCount edges { node { id title director } } } allHeroes { edges { node { ...HeroFields } } } } fragment HeroFields on Hero { id name } """ parser = QueryParser(self.swapi_schema) parsed = parser.parse(query) expected = asdict( ParsedQuery( query=query, objects=[ ParsedOperation( name="GetAllFilms", type="query", children=[ ParsedObject( name="GetAllFilmsData", fields=[ ParsedField( name="allFilms", type="FilmConnection", nullable=True, ), ParsedField( name="allHeroes", type="HeroConnection", nullable=True, ), ], children=[ ParsedObject( name="FilmConnection", fields=[ ParsedField(name="count", type="int", nullable=True), ParsedField( name="edges", type="List[FilmEdge]", nullable=True, ), ], children=[ ParsedObject( name="FilmEdge", fields=[ ParsedField( name="node", type="Film", nullable=True, ) ], children=[ ParsedObject( name="Film", fields=[ ParsedField( name="id", type="str", nullable=False, ), ParsedField( name="title", type="str", nullable=False, ), ParsedField( name="director", type="str", nullable=False, ), ], ) ], ) ], ), ParsedObject( name="HeroConnection", fields=[ ParsedField( name="edges", type="List[HeroEdge]", nullable=True, ) ], children=[ ParsedObject( name="HeroEdge", fields=[ ParsedField( name="node", type="Hero", nullable=True, ) ], children=[ ParsedObject( name="Hero", parents=["HeroFields"], fields=[], ) ], ) ], ), ], ) ], ), ParsedObject( name="HeroFields", fields=[ ParsedField(name="id", type="str", nullable=False), ParsedField(name="name", type="str", nullable=False), ], ), ], )) parsed_dict = asdict(parsed) assert bool(parsed) assert parsed_dict == expected, str(DeepDiff(parsed_dict, expected))
def test_parser_query_with_variables(self): query = """ query GetFilm($theFilmID: ID!) { returnOfTheJedi: film(id: $theFilmID) { title director } } """ parser = QueryParser(self.swapi_schema) parsed = parser.parse(query) expected = asdict( ParsedQuery( query=query, objects=[ ParsedOperation( name="GetFilm", type="query", variables=[ ParsedVariableDefinition( name="theFilmID", type="str", nullable=False, is_list=False, ) ], children=[ ParsedObject( name="GetFilmData", fields=[ ParsedField( name="returnOfTheJedi", type="Film", nullable=True, ) ], children=[ ParsedObject( name="Film", fields=[ ParsedField(name="title", type="str", nullable=False), ParsedField( name="director", type="str", nullable=False, ), ], ) ], ) ], ) ], )) parsed_dict = asdict(parsed) assert bool(parsed) assert parsed_dict == expected, str(DeepDiff(parsed_dict, expected))
def test_parser_query_complex_fragment(self): query = """ query GetPerson { luke: character(id: "luke") { ...CharacterFields } } fragment CharacterFields on Person { name home: homeworld { name } } """ parser = QueryParser(self.swapi_schema) parsed = parser.parse(query) expected = asdict( ParsedQuery( query=query, objects=[ ParsedOperation( name="GetPerson", type="query", children=[ ParsedObject( name="GetPersonData", fields=[ ParsedField(name="luke", type="Person", nullable=True) ], children=[ ParsedObject( name="Person", parents=["CharacterFields"], fields=[], ) ], ) ], ), ParsedObject( name="CharacterFields", fields=[ ParsedField(name="name", type="str", nullable=False), ParsedField(name="home", type="Planet", nullable=False), ], children=[ ParsedObject( name="Planet", fields=[ ParsedField(name="name", type="str", nullable=False) ], ) ], ), ], )) parsed_dict = asdict(parsed) assert bool(parsed) assert parsed_dict == expected, str(DeepDiff(parsed_dict, expected))
def test_simple_query_with_enums_default_value(self): """ enum LengthUnit { METER KM } type Starship { id: ID! name: String! length(unit: LengthUnit = METER): Float } type Query { ship(id: String!): Starship } """ length_unit_enum = GraphQLEnumType( "LengthUnit", { "METER": GraphQLEnumValue("METER"), "KM": GraphQLEnumValue("KM") }, description="One of the films in the Star Wars Trilogy", ) starship_type = GraphQLObjectType( "Starship", lambda: { "id": GraphQLField(GraphQLNonNull(GraphQLString), description="The id of the ship."), "name": GraphQLField(GraphQLString, description="The name of the ship."), "length": GraphQLField( GraphQLInt, args={ "unit": GraphQLArgument( GraphQLNonNull(length_unit_enum), default_value="METER", description="id of the droid", ) }, ), }, ) query_type = GraphQLObjectType( "Query", lambda: { "ship": GraphQLField( starship_type, args={ "id": GraphQLArgument(GraphQLNonNull(GraphQLString), description="id of the ship") }, ) }, ) schema = GraphQLSchema(query_type, types=[length_unit_enum, starship_type]) query = """ query GetStarship { ship(id: "Enterprise") { id name length(unit: METER) } } """ query_parser = QueryParser(schema) query_renderer = DataclassesRenderer(schema) parsed = query_parser.parse(query) rendered_enums = query_renderer.render_enums(parsed) for rendered_enum in rendered_enums: self.load_module(rendered_enum) rendered = query_renderer.render(parsed) m = self.load_module(rendered) response = m.GetStarship.from_json(""" { "data": { "ship": { "id": "Enterprise", "name": "Enterprise", "length": 100 } } } """) assert response ship = response.data.ship assert ship assert ship.id == "Enterprise" assert ship.name == "Enterprise" assert ship.length == 100