[ 'name' => 'R2-D2' ] ]; $this->assertValidQuery($query, $expected); } public function testAllowsUsToQueryForTheIDAndFriendsOfR2D2() { $query = ' query HeroNameAndFriendsQuery { hero { id name friends { name } } } '; $expected = [ 'hero' => [ 'id' => '2001', 'name' => 'R2-D2', 'friends' => [ [ 'name' => 'Luke Skywalker', ], [ 'name' => 'Han Solo', ], [ 'name' => 'Leia Organa', ], ] ] ]; $this->assertValidQuery($query, $expected); } // Nested Queries public function testAllowsUsToQueryForTheFriendsOfFriendsOfR2D2() { $query = ' query NestedQuery { hero { name friends { name appearsIn friends { name } } } } '; $expected = [ 'hero' => [ 'name' => 'R2-D2', 'friends' => [ [ 'name' => 'Luke Skywalker', 'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI',], 'friends' => [ ['name' => 'Han Solo',], ['name' => 'Leia Organa',], ['name' => 'C-3PO',], ['name' => 'R2-D2',], ], ], [ 'name' => 'Han Solo', 'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'], 'friends' => [ ['name' => 'Luke Skywalker',], ['name' => 'Leia Organa'], ['name' => 'R2-D2',], ] ], [ 'name' => 'Leia Organa', 'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'], 'friends' => [ ['name' => 'Luke Skywalker',], ['name' => 'Han Solo',], ['name' => 'C-3PO',], ['name' => 'R2-D2',], ], ], ], ] ]; $this->assertValidQuery($query, $expected); } // Using IDs and query parameters to refetch objects public function testAllowsUsToQueryForLukeSkywalkerDirectlyUsingHisID() { $query = ' query FetchLukeQuery { human(id: "1000") { name } } '; $expected = [ 'human' => [ 'name' => 'Luke Skywalker' ] ]; $this->assertValidQuery($query, $expected); } public function testGenericQueryToGetLukeSkywalkerById() { // Allows us to create a generic query, then use it to fetch Luke Skywalker using his ID $query = ' query FetchSomeIDQuery($someId: String!) { human(id: $someId) { name } } '; $params = [ 'someId' => '1000' ]; $expected = [ 'human' => [ 'name' => 'Luke Skywalker' ] ]; $this->assertValidQueryWithParams($query, $params, $expected); } public function testGenericQueryToGetHanSoloById() { // Allows us to create a generic query, then use it to fetch Han Solo using his ID $query = ' query FetchSomeIDQuery($someId: String!) { human(id: $someId) { name } } '; $params = [ 'someId' => '1002' ]; $expected = [ 'human' => [ 'name' => 'Han Solo' ] ]; $this->assertValidQueryWithParams($query, $params, $expected); } public function testGenericQueryWithInvalidId() { // Allows us to create a generic query, then pass an invalid ID to get null back $query = ' query humanQuery($id: String!) { human(id: $id) { name } } '; $params = [ 'id' => 'not a valid id' ]; $expected = [ 'human' => null ]; $this->assertValidQueryWithParams($query, $params, $expected); } // Using aliases to change the key in the response function testLukeKeyAlias() { // Allows us to query for Luke, changing his key with an alias $query = ' query FetchLukeAliased { luke: human(id: "1000") { name } } '; $expected = [ 'luke' => [ 'name' => 'Luke Skywalker' ], ]; $this->assertValidQuery($query, $expected); } function testTwoRootKeysAsAnAlias() { // Allows us to query for both Luke and Leia, using two root fields and an alias $query = ' query FetchLukeAndLeiaAliased { luke: human(id: "1000") { name } leia: human(id: "1003") { name } } '; $expected = [ 'luke' => [ 'name' => 'Luke Skywalker' ], 'leia' => [ 'name' => 'Leia Organa' ] ]; $this->assertValidQuery($query, $expected); } // Uses fragments to express more complex queries function testQueryUsingDuplicatedContent() { // Allows us to query using duplicated content $query = ' query DuplicateFields { luke: human(id: "1000") { name homePlanet } leia: human(id: "1003") { name homePlanet } } '; $expected = [ 'luke' => [ 'name' => 'Luke Skywalker', 'homePlanet' => 'Tatooine' ], 'leia' => [ 'name' => 'Leia Organa', 'homePlanet' => 'Alderaan' ] ]; $this->assertValidQuery($query, $expected); } function testUsingFragment() { // Allows us to use a fragment to avoid duplicating content $query = ' query UseFragment { luke: human(id: "1000") { ...HumanFragment } leia: human(id: "1003") { ...HumanFragment } } fragment HumanFragment on Human { name homePlanet } '; $expected = [ 'luke' => [ 'name' => 'Luke Skywalker', 'homePlanet' => 'Tatooine' ], 'leia' => [ 'name' => 'Leia Organa', 'homePlanet' => 'Alderaan' ] ]; $this->assertValidQuery($query, $expected); } function testFragmentWithProjection() { $query = ' query UseFragment { human(id: "1003") { name ...fa ...fb } } fragment fa on Character { friends { id } } fragment fb on Character { friends { name } } '; $expected = [ 'human' => [ 'name' => 'Leia Organa', 'friends' => [ [ 'name' => 'Luke Skywalker', 'id' => '1000' ], [ 'name' => 'Han Solo', 'id' => '1002' ], [ 'name' => 'C-3PO', 'id' => '2000' ], [ 'name' => 'R2-D2', 'id' => '2001' ] ] ] ]; $this->assertValidQuery($query, $expected); } // Using __typename to find the type of an object public function testVerifyThatR2D2IsADroid() { $query = ' query CheckTypeOfR2 { hero { __typename name } } '; $expected = [ 'hero' => [ '__typename' => 'Droid', 'name' => 'R2-D2' ], ]; $this->assertValidQuery($query, $expected); } public function testVerifyThatLukeIsHuman() { $query = ' query CheckTypeOfLuke { hero(episode: EMPIRE) { __typename name } } '; $expected = [ 'hero' => [ '__typename' => 'Human', 'name' => 'Luke Skywalker' ], ]; $this->assertValidQuery($query, $expected); } /** * Helper function to test a query and the expected response. */ private function assertValidQuery($query, $expected) { $this->assertEquals(['data' => $expected], GraphQL::execute(StarWarsSchema::build(), $query)); } /** * Helper function to test a query with params and the expected response. */ private function assertValidQueryWithParams($query, $params, $expected) { $this->assertEquals(['data' => $expected], GraphQL::execute(StarWarsSchema::build(), $query, null, $params)); } }