Added dependency plugins

This commit is contained in:
Moris Zen
2018-06-25 00:00:37 +02:00
parent 720a1c31a4
commit f069f6782f
698 changed files with 289637 additions and 1 deletions

View File

@@ -0,0 +1,30 @@
<?php
class AccessFunctionsTest extends \Codeception\TestCase\WPTestCase
{
public function setUp()
{
// before
parent::setUp();
// your set up methods here
}
public function tearDown()
{
// your tear down methods here
// then
parent::tearDown();
}
// tests
public function testMe()
{
$actual = graphql_format_field_name( 'This is some field name' );
$expected = 'thisIsSomeFieldName';
self::assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,310 @@
<?php
class AuthSchemaTest extends \Codeception\TestCase\WPTestCase {
public $post;
public $admin;
public $editor;
public $subscriber;
public $global_id;
public function setUp() {
// before
parent::setUp();
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
'user_email' => 'schema_admin_test@example.com',
] );
$this->editor = $this->factory->user->create( [
'role' => 'editor',
'user_login' => 'schemaEditor',
] );
$this->subscriber = $this->factory->user->create( [
'role' => 'subscriber',
'user_login' => 'schemaSubscriber',
] );
$this->post = $this->factory->post->create( [
'post_type' => 'post',
'post_status' => 'publish',
] );
$this->global_id = \GraphQLRelay\Relay::toGlobalId( 'post', $this->post );
tests_add_filter( 'graphql_post_fields', function( $fields ) {
$fields['testIsPrivate'] = [
'type' => \WPGraphQL\Types::string(),
'isPrivate' => true,
'resolve' => function() {
return 'isPrivateValue';
}
];
$fields['authCallback'] = [
'type' => \WPGraphQL\Types::string(),
'auth' => [
'callback' => function( $field, $field_key, $source, $args, $context, $info, $field_resolver ) {
/**
* If the current user isn't the user with the login "admin" throw an error
*/
if ( 'schema_admin_test@example.com' !== wp_get_current_user()->user_email ) {
throw new \GraphQL\Error\UserError( __( 'You need the secret!', 'wp-graphql' ) );
}
return $field_resolver;
}
],
'resolve' => function() {
return 'authCallbackValue';
}
];
$fields['authRoles'] = [
'type' => \WPGraphQL\Types::string(),
'auth' => [
'allowedRoles' => [ 'administrator', 'editor' ],
],
'resolve' => function() {
return 'allowedRolesValue';
}
];
$fields['authCaps'] = [
'type' => \WPGraphQL\Types::string(),
'auth' => [
'allowedCaps' => [ 'manage_options', 'graphql_rocks' ],
],
'resolve' => function() {
return 'allowedCapsValue';
}
];
return $fields;
} );
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* This tests to make sure a field marked isPrivate will return a null value for the resolver
*/
public function testIsPrivate() {
/**
* Set the current user to nobody
*/
wp_set_current_user( 0 );
$request = '
query getPost( $id:ID! ) {
post( id:$id ) {
id
postId
testIsPrivate
}
}
';
/**
* Run the request
*/
$variables = wp_json_encode( [ 'id' => $this->global_id ] );
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertNull( $actual['data']['post']['testIsPrivate'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
/**
* Set the user as an admin
*/
wp_set_current_user( $this->admin );
/**
* Run the request
*/
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, and should NOT contain errors but should properly resolve the "isPrivateValue"
* for the "testIsPrivate" field
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertEquals( 'isPrivateValue', $actual['data']['post']['testIsPrivate'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
}
public function testAuthCallback() {
/**
* Set the current user to nobody
*/
wp_set_current_user( $this->subscriber );
$request = '
query getPost( $id:ID! ) {
post( id:$id ) {
id
postId
authCallback
}
}
';
/**
* Run the request
*/
$variables = wp_json_encode( [ 'id' => $this->global_id ] );
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertNull( $actual['data']['post']['authCallback'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
wp_set_current_user( $this->admin );
/**
* Run the request
*/
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, and should NOT contain errors, but should contain the value
* of the authCallback field
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertEquals( 'authCallbackValue', $actual['data']['post']['authCallback'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
}
public function testAuthRoles() {
/**
* Set the current user to nobody
*/
wp_set_current_user( $this->admin );
$request = '
query getPost( $id:ID! ) {
post( id:$id ) {
id
postId
authRoles
}
}
';
/**
* Run the request
*/
$variables = wp_json_encode( [ 'id' => $this->global_id ] );
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertEquals( 'allowedRolesValue', $actual['data']['post']['authRoles'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
wp_set_current_user( $this->editor );
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertEquals( 'allowedRolesValue', $actual['data']['post']['authRoles'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
wp_set_current_user( $this->subscriber );
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertNull( $actual['data']['post']['authRoles'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
}
public function testAuthCaps() {
/**
* Set the current user to nobody
*/
wp_set_current_user( $this->subscriber );
$request = '
query getPost( $id:ID! ) {
post( id:$id ) {
id
postId
authCaps
}
}
';
/**
* Run the request
*/
$variables = wp_json_encode( [ 'id' => $this->global_id ] );
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertNull( $actual['data']['post']['authCaps'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
/**
* Remove the caps from the user
*/
wp_set_current_user( $this->admin );
/**
* Run the request, this time the value should be null and there should be an error
*/
$actual = do_graphql_request( $request, 'getPost', $variables );
/**
* The query should execute, but should contain errors
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertArrayHasKey( 'data', $actual );
$this->assertEquals( 'allowedCapsValue', $actual['data']['post']['authCaps'] );
$this->assertEquals( $this->post, $actual['data']['post']['postId'] );
}
}

View File

@@ -0,0 +1,233 @@
<?php
class AvatarObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public $admin;
public function setUp() {
parent::setUp();
$this->admin = $this->factory()->user->create( [
'role' => 'admin',
'user_email' => 'test@test.com'
] );
}
public function tearDown() {
parent::tearDown();
}
/**
* testPostQuery
*
* This tests creating a single post with data and retrieving said post via a GraphQL query
*
* @since 0.0.5
*/
public function testAvatarQuery() {
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $this->admin );
// Override avatar url to match $this->avatar_test_url()
add_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ), 10, 1 );
/**
* Create the query string to pass to the $query
* Set the size to 0 to make sure that it defaults back to 96 as it has to be a positive
* integer
*/
$query = "
query {
user(id: \"{$global_id}\") {
avatar(size:0 rating:G forceDefault:true) {
default,
extraAttr,
forceDefault,
foundAvatar,
height,
rating,
scheme,
size,
url,
width
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'avatar' => [
'default' => 'mm',
'extraAttr' => null,
'forceDefault' => true,
'foundAvatar' => true,
'height' => 96,
'rating' => 'g',
'scheme' => null,
'size' => 96,
'url' => 'http://test-url.com',
'width' => 96,
],
],
],
];
$this->assertEquals( $expected, $actual );
// Clean up filter usage.
remove_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ) );
}
/**
* testPostQuery
*
* This tests creating a single post with data and retrieving said post via a GraphQL query
*
* @since 0.0.5
*/
public function testAvatarQueryWithSizeInput() {
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $this->admin );
// Override avatar url to match $this->avatar_test_url()
add_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ), 10, 1 );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
avatar(size: 48) {
default,
extraAttr,
forceDefault,
foundAvatar,
height,
rating,
scheme,
size,
url,
width
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'avatar' => [
'default' => 'mm',
'extraAttr' => null,
'forceDefault' => false,
'foundAvatar' => true,
'height' => 48,
'rating' => 'g',
'scheme' => null,
'size' => 48,
'url' => 'http://test-url.com',
'width' => 48,
],
],
],
];
$this->assertEquals( $expected, $actual );
// Clean up filter usage.
remove_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ) );
}
/**
* testPostQuery
*
* This tests creating a single post with data and retrieving said post via a GraphQL query
*
* @since 0.0.5
*/
public function testAvatarQueryNotFound() {
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $this->admin );
// Override avatar url to match $this->avatar_test_url()
add_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ), 10, 1 );
add_filter( 'get_avatar_data', array( $this, 'fake_unfound_avatar' ) );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
avatar(size: 48) {
default,
extraAttr,
forceDefault,
foundAvatar,
height,
rating,
scheme,
size,
url,
width
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* The avatar should be empty.
*/
$expected = [
'data' => [
'user' => [
'avatar' => null
],
],
];
$this->assertEquals( $expected, $actual );
// Clean up filter usage.
remove_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ) );
remove_filter( 'get_avatar_data', array( $this, 'fake_unfound_avatar' ) );
}
public function avatar_test_url( $url ) {
return 'http://test-url.com';
}
public function fake_unfound_avatar( $args ) {
$args['found_avatar'] = false;
return $args;
}
}

View File

@@ -0,0 +1,238 @@
<?php
class CommentConnectionQueriesTest extends \Codeception\TestCase\WPTestCase {
public $post_id;
public $current_time;
public $current_date;
public $current_date_gmt;
public $admin;
public $created_comment_ids;
public function setUp() {
// before
parent::setUp();
$this->post_id = $this->factory->post->create();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
$this->created_comment_ids = $this->create_comments();
}
public function tearDown() {
// then
parent::tearDown();
}
public function createCommentObject( $args = [] ) {
/**
* Set up the $defaults
*/
$defaults = [
'comment_author' => $this->admin,
'comment_content' => 'Test comment content',
'comment_approved' => 1,
];
/**
* Combine the defaults with the $args that were
* passed through
*/
$args = array_merge( $defaults, $args );
/**
* Create the page
*/
$comment_id = $this->factory->comment->create( $args );
/**
* Return the $id of the comment_object that was created
*/
return $comment_id;
}
/**
* Creates several comments (with different timestamps) for use in cursor query tests
*
* @return array
*/
public function create_comments() {
// Create 20 comments
$created_comments = [];
for ( $i = 1; $i <= 20; $i ++ ) {
$date = date( 'Y-m-d H:i:s', strtotime( "-1 day +{$i} minutes" ) );
$created_comments[ $i ] = $this->createCommentObject( [
'comment_content' => $i,
'comment_date' => $date,
] );
}
return $created_comments;
}
public function commentsQuery( $variables ) {
$query = 'query commentsQuery($first:Int $last:Int $after:String $before:String $where:RootCommentsCommentArgs){
comments( first:$first last:$last after:$after before:$before where:$where ) {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
id
commentId
content
date
}
}
nodes {
commentId
}
}
}';
return do_graphql_request( $query, 'commentsQuery', $variables );
}
public function testFirstComment() {
$variables = [
'first' => 1,
];
$results = $this->commentsQuery( $variables );
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( [
'comment_status' => 'approved',
'number' => 1,
'order' => 'DESC',
'orderby' => 'comment_date',
'comment_parent' => 0,
] );
$first_comment = $comments[0];
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $first_comment->comment_ID );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['comments']['edges'] ) );
$this->assertEquals( $first_comment->comment_ID, $results['data']['comments']['edges'][0]['node']['commentId'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['endCursor'] );
$this->assertEquals( $first_comment->comment_ID, $results['data']['comments']['nodes'][0]['commentId'] );
}
public function testForwardPagination() {
/**
* Create the cursor for the comment with the oldest comment_date
*/
$first_comment_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $this->created_comment_ids[20] );
/**
* Set the variables to use in the GraphQL Query
*/
$variables = [
'first' => 1,
'after' => $first_comment_cursor,
];
/**
* Run the GraphQL Query
*/
$results = $this->commentsQuery( $variables );
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( [
'comment_status' => 'approved',
'number' => 1,
'offset' => 1,
'order' => 'DESC',
'orderby' => 'comment_date',
'comment_parent' => 0,
] );
$second_comment = $comments[0];
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $second_comment->comment_ID );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['comments']['edges'] ) );
$this->assertEquals( $second_comment->comment_ID, $results['data']['comments']['edges'][0]['node']['commentId'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['endCursor'] );
}
public function testLastComment() {
$variables = [
'last' => 1,
];
$results = $this->commentsQuery( $variables );
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( [
'comment_status' => 'approved',
'number' => 1,
'order' => 'ASC',
'orderby' => 'comment_date',
'comment_parent' => 0,
] );
$last_comment = $comments[0];
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $last_comment->comment_ID );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['comments']['edges'] ) );
$this->assertEquals( $last_comment->comment_ID, $results['data']['comments']['edges'][0]['node']['commentId'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['endCursor'] );
}
public function testBackwardPagination() {
/**
* Create the cursor for the comment with the newest comment_date
*/
$last_comment_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $this->created_comment_ids[1] );
$variables = [
'last' => 1,
'before' => $last_comment_cursor,
];
$results = $this->commentsQuery( $variables );
$comments_query = new WP_Comment_Query;
$comments = $comments_query->query( [
'comment_status' => 'approved',
'number' => 1,
'offset' => 1,
'order' => 'ASC',
'orderby' => 'comment_date',
'comment_parent' => 0,
] );
$second_to_last_comment = $comments[0];
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $second_to_last_comment->comment_ID );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['comments']['edges'] ) );
$this->assertEquals( $second_to_last_comment->comment_ID, $results['data']['comments']['edges'][0]['node']['commentId'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['comments']['pageInfo']['endCursor'] );
}
}

View File

@@ -0,0 +1,341 @@
<?php
class CommentObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $admin;
public function setUp() {
parent::setUp();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
}
public function tearDown() {
parent::tearDown();
}
public function createCommentObject( $args = [] ) {
/**
* Set up the $defaults
*/
$defaults = [
'comment_author' => $this->admin,
'comment_content' => 'Test comment content',
'comment_approved' => 1,
'comment_date' => $this->current_date,
'comment_date_gmt' => $this->current_date_gmt,
];
/**
* Combine the defaults with the $args that were
* passed through
*/
$args = array_merge( $defaults, $args );
/**
* Create the page
*/
$comment_id = $this->factory->comment->create( $args );
/**
* Return the $id of the comment_object that was created
*/
return $comment_id;
}
/**
* testCommentQuery
*
* This tests creating a single comment with data and retrieving said comment via a GraphQL query
*
* @since 0.0.5
*/
public function testCommentQuery() {
/**
* Create a comment
*/
$comment_id = $this->createCommentObject( [
'user_id' => $this->admin,
] );
/**
* Create the global ID based on the comment_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
comment(id: \"{$global_id}\") {
agent
approved
author{
...on User {
userId
}
}
authorIp
children {
edges {
node {
id
}
}
}
commentId
commentedOn {
... on Post {
id
}
}
content
date
dateGmt
id
karma
parent {
id
}
type
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'comment' => [
'agent' => '',
'approved' => '1',
'author' => [
'userId' => $this->admin,
],
'authorIp' => '',
'children' => [
'edges' => [],
],
'commentId' => $comment_id,
'commentedOn' => null,
'content' => 'Test comment content',
'date' => $this->current_date,
'dateGmt' => $this->current_date_gmt,
'id' => $global_id,
'karma' => 0,
'parent' => null,
'type' => null,
],
],
];
$this->assertEqualSets( $expected, $actual );
}
/**
* testCommentQuery
*
* This tests creating a single comment with data and retrieving said comment via a GraphQL query
*
* @since 0.0.5
*/
public function testCommentWithCommentAuthor() {
/**
* Create a comment
*/
$comment_id = $this->createCommentObject( [
'comment_author' => 'Author Name',
'comment_author_email' => 'test@test.com',
'comment_author_url' => 'http://example.com',
] );
/**
* Create the global ID based on the comment_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
comment(id: \"{$global_id}\") {
agent
approved
author{
...on CommentAuthor {
id
name
email
url
}
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'comment' => [
'agent' => '',
'approved' => '1',
'author' => [
'id' => \GraphQLRelay\Relay::toGlobalId( 'commentAuthor', get_comment_author_email( $comment_id ) ),
'name' => get_comment_author( $comment_id ),
'email' => get_comment_author_email( $comment_id ),
'url' => get_comment_author_url( $comment_id ),
],
],
],
];
$this->assertEqualSets( $expected, $actual );
}
/**
* testCommentQuery
*
* This tests creating a single comment with data and retrieving said comment via a GraphQL query
*
* @since 0.0.5
*/
public function testCommentQueryWithChildrenAssignedPostAndParent() {
// Post object to assign comments to.
$post_id = $this->factory->post->create( [
'post_content' => 'Post object',
] );
// Parent comment.
$parent_comment = $this->createCommentObject(
[
'comment_post_ID' => $post_id,
'comment_content' => 'Parent comment',
]
);
/**
* Create a comment
*/
$comment_id = $this->createCommentObject( [
'comment_post_ID' => $post_id,
'comment_content' => 'Test comment',
'comment_parent' => $parent_comment,
] );
// Create child comments.
$child_1 = $this->createCommentObject( [
'comment_post_ID' => $post_id,
'comment_content' => 'Child 1',
'comment_parent' => $comment_id,
] );
$child_2 = $this->createCommentObject( [
'comment_post_ID' => $post_id,
'comment_content' => 'Child 2',
'comment_parent' => $comment_id,
] );
/**
* Create the global ID based on the comment_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
comment(id: \"{$global_id}\") {
children {
edges {
node {
commentId
content
}
}
}
commentId
commentedOn {
... on Post {
content
}
}
content
parent {
commentId
content
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'comment' => [
'children' => [
'edges' => [
[
'node' => [
'commentId' => $child_2,
'content' => 'Child 2',
],
],
[
'node' => [
'commentId' => $child_1,
'content' => 'Child 1',
],
],
],
],
'commentId' => $comment_id,
'commentedOn' => [
'content' => apply_filters( 'the_content', 'Post object' ),
],
'content' => 'Test comment',
'parent' => [
'commentId' => $parent_comment,
'content' => 'Parent comment',
],
],
],
];
$this->assertEqualSets( $expected, $actual );
}
}

View File

@@ -0,0 +1,90 @@
<?php
use WPGraphQL\Data\Config;
class DataConfigTest extends \Codeception\TestCase\WPTestCase {
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
if ( ! defined( 'GRAPHQL_REQUEST' ) ) {
define( 'GRAPHQL_REQUEST', true );
}
}
/**
* Create n posts, making sure that publish dates are offset by at least one
* second. The posts can either simulate being published in the same order as
* the post IDs (e.g., 1, 2, 3, ... 10) or out of order (e.g., 10, 9, ... 1).
*/
private function create_posts( $count, $operator, $offset_multiplier = 1 ) {
$iterable = array_keys( array_fill( 0, $count, null ) );
// Make sure starting timestamp is sufficiently in the past so that posts
// do not receive a post_status of "future".
$timestamp = time() - 1000;
$posts = array_map( function ( $offset ) use ( $timestamp, $offset_multiplier ) {
return $this->factory->post->create_and_get(
array(
'post_date' => date( 'Y-m-d H:i:s', $timestamp + ( $offset * $offset_multiplier ) ),
)
);
}, $iterable );
// Sort posts either ASC (">") or DESC ("<") by post_date.
usort( $posts, function ( $one, $two ) use ( $operator ) {
if ( '<' === $operator ) {
return strcmp( $two->post_date, $one->post_date );
}
return strcmp( $one->post_date, $two->post_date );
} );
return $posts;
}
/**
* Data provider for testGraphqlWpQueryCursorPaginationSupportMethod
*/
public function get_create_posts_args() {
return array(
array( '<', 1 ),
array( '<', -1 ),
array( '>', 1 ),
array( '>', -1 ),
);
}
/**
* Tests WP_Query pagination support.
*
* @dataProvider get_create_posts_args
*/
public function testGraphqlWpQueryCursorPaginationSupportMethod( $operator, $offset_multiplier ) {
$posts = $this->create_posts( 15, $operator, $offset_multiplier );
// Simulate a GraphQL request for:
// posts(
// after: '[id of tenth post]',
// first: 10
// )
$query = new WP_Query(
array(
'graphql_cursor_offset' => $posts[9]->ID,
'graphql_cursor_compare' => $operator,
'order' => '<' === $operator ? 'DESC' : 'ASC',
'orderby' => 'date',
'posts_per_page' => 11,
)
);
$this->assertTrue( $query->have_posts() );
$this->assertEquals( 5, count( $query->posts ) );
// Make sure each of the returned posts matches the expected "second page"
// of the posts we created (indexes 10-14).
foreach ( $query->posts as $index => $post ) {
$this->assertEquals( $posts[ $index + 10 ]->ID, $post->ID );
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
class DataSourceTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
// before
parent::setUp();
// your set up methods here
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* Tests retrieving a post by slug
*/
public function testGetPostObjectByMethod() {
$slug = 'some-sample-slug';
$args = [
'post_content' => 'Some sample content',
'post_title' => 'Some sample post here',
'post_name' => $slug,
];
$post_id = $this->factory->post->create( $args );
$expected = get_post( $post_id );
$actual = \WPGraphQL\Data\DataSource::get_post_object_by_uri( $slug );
$this->assertEquals( $expected, $actual );
}
/**
* Tests retrieving a post by slug when two posts have the same slug in different post types
*/
public function testGetPostObjectByMethodForMultiplePosts() {
$slug = 'some-other-slug';
$args = [
'post_content' => 'Sample duplicate content',
'post_title' => 'Some Duplicate Content',
'post_name' => $slug,
];
$post_id = $this->factory->post->create( $args );
$args['post_type'] = 'page';
$page_id = $this->factory->post->create( $args );
$expected = get_post( $page_id );
$actual = \WPGraphQL\Data\DataSource::get_post_object_by_uri( $slug, OBJECT, [ 'post', 'page' ] );
$this->assertEquals( $expected, $actual );
}
/**
* Tests retrieving a post object by slug that doesn't exist
*/
public function testGetPostObjectByMethodForNonExistantSlug() {
$actual = \WPGraphQL\Data\DataSource::get_post_object_by_uri( 'non-existent-uri' );
$this->assertEquals( null, $actual );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,333 @@
<?php
class MediaItemQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $admin;
public function setUp() {
parent::setUp();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
$this->subscriber = $this->factory()->user->create( [
'role' => 'subscriber',
] );
}
public function tearDown() {
parent::tearDown();
}
public function createPostObject( $args ) {
/**
* Set up the $defaults
*/
$defaults = [
'post_author' => $this->admin,
'post_content' => 'Test page content',
'post_excerpt' => 'Test excerpt',
'post_status' => 'publish',
'post_title' => 'Test Title',
'post_type' => 'post',
'post_date' => $this->current_date,
];
/**
* Combine the defaults with the $args that were
* passed through
*/
$args = array_merge( $defaults, $args );
/**
* Create the page
*/
$post_id = $this->factory->post->create( $args );
/**
* Update the _edit_last and _edit_lock fields to simulate a user editing the page to
* test retrieving the fields
*
* @since 0.0.5
*/
update_post_meta( $post_id, '_edit_lock', $this->current_time . ':' . $this->admin );
update_post_meta( $post_id, '_edit_last', $this->admin );
/**
* Return the $id of the post_object that was created
*/
return $post_id;
}
/**
* Data provider for testMediaItemQuery.
*/
public function provideImageMeta() {
return [
[
[],
],
[
[
'caption' => '',
],
],
];
}
/**
* testPostQuery
*
* This tests creating a single post with data and retrieving said post via a GraphQL query
*
* @dataProvider provideImageMeta
* @param array $image_meta Image meta to merge into defaults.
* @since 0.0.5
*/
public function testMediaItemQuery( $image_meta = [] ) {
/**
* Create a post to set as the attachment's parent
*/
$post_id = $this->createPostObject( [
'post_type' => 'post',
] );
/**
* Create an attachment with a post set as it's parent
*/
$image_description = 'some description';
$attachment_id = $this->createPostObject( [
'post_type' => 'attachment',
'post_parent' => $post_id,
'post_content' => $image_description,
] );
$default_image_meta = [
'aperture' => 0,
'credit' => 'some photographer',
'camera' => 'some camera',
'caption' => 'some caption',
'created_timestamp' => strtotime( $this->current_date ),
'copyright' => 'Copyright WPGraphQL',
'focal_length' => 0,
'iso' => 0,
'shutter_speed' => 0,
'title' => 'some title',
'orientation' => 'some orientation',
'keywords' => [
'keyword1',
'keyword2',
],
];
$meta_data = [
'width' => 300,
'height' => 300,
'file' => 'example.jpg',
'sizes' => [
'thumbnail' => [
'file' => 'example-thumbnail.jpg',
'width' => 150,
'height' => 150,
'mime-type' => 'image/jpeg',
'source_url' => 'example-thumbnail.jpg',
],
'full' => [
'file' => 'example-full.jpg',
'width' => 1500,
'height' => 1500,
'mime-type' => 'image/jpeg',
'source_url' => 'example-full.jpg',
],
],
'image_meta' => array_merge( $default_image_meta, $image_meta ),
];
update_post_meta( $attachment_id, '_wp_attachment_metadata', $meta_data );
/**
* Create the global ID based on the post_type and the created $id
*/
$attachment_global_id = \GraphQLRelay\Relay::toGlobalId( 'attachment', $attachment_id );
$post_global_id = \GraphQLRelay\Relay::toGlobalId( 'post', $post_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
mediaItem(id: \"{$attachment_global_id}\") {
altText
author{
id
}
caption
commentCount
commentStatus
comments{
edges{
node{
id
}
}
}
content
date
dateGmt
description
desiredSlug
editLast{
userId
}
editLock{
editTime
}
enclosure
excerpt
guid
id
link
mediaDetails{
file
height
meta{
aperture
credit
camera
caption
createdTimestamp
copyright
focalLength
iso
shutterSpeed
title
orientation
keywords
}
sizes{
name
file
width
height
mimeType
sourceUrl
}
width
}
mediaItemId
mediaType
menuOrder
mimeType
modified
modifiedGmt
parent{
...on Post{
id
}
}
pingStatus
slug
sourceUrl
status
title
toPing
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
$mediaItem = $actual['data']['mediaItem'];
$this->assertNotEmpty( $mediaItem );
$this->assertTrue( ( null === $mediaItem['altText'] || is_string( $mediaItem['altText'] ) ) );
$this->assertTrue( ( null === $mediaItem['author'] || is_string( $mediaItem['author']['id'] ) ) );
$this->assertTrue( ( null === $mediaItem['caption'] || is_string( $mediaItem['caption'] ) ) );
$this->assertTrue( ( null === $mediaItem['commentCount'] || is_int( $mediaItem['commentCount'] ) ) );
$this->assertTrue( ( null === $mediaItem['commentStatus'] || is_string( $mediaItem['commentStatus'] ) ) );
$this->assertTrue( ( empty( $mediaItem['comments']['edges'] ) || is_string( $mediaItem['comments']['edges'] ) ) );
$this->assertTrue( ( null === $mediaItem['content'] || is_string( $mediaItem['content'] ) ) );
$this->assertTrue( ( null === $mediaItem['date'] || is_string( $mediaItem['date'] ) ) );
$this->assertTrue( ( null === $mediaItem['dateGmt'] || is_string( $mediaItem['dateGmt'] ) ) );
$this->assertTrue( ( null === $mediaItem['description'] || is_string( $mediaItem['description'] ) ) );
$this->assertTrue( ( null === $mediaItem['desiredSlug'] || is_string( $mediaItem['desiredSlug'] ) ) );
$this->assertTrue( ( empty( $mediaItem['editLast'] ) || is_integer( $mediaItem['editLast']['userId'] ) ) );
$this->assertTrue( ( empty( $mediaItem['editLock'] ) || is_string( $mediaItem['editLock']['editTime'] ) ) );
$this->assertTrue( ( null === $mediaItem['enclosure'] || is_string( $mediaItem['enclosure'] ) ) );
$this->assertTrue( ( null === $mediaItem['excerpt'] || is_string( $mediaItem['excerpt'] ) ) );
$this->assertTrue( ( null === $mediaItem['guid'] || is_string( $mediaItem['guid'] ) ) );
$this->assertEquals( $attachment_global_id, $mediaItem['id'] );
$this->assertEquals( $attachment_id, $mediaItem['mediaItemId'] );
$this->assertTrue( ( null === $mediaItem['mediaType'] || is_string( $mediaItem['mediaType'] ) ) );
$this->assertTrue( ( null === $mediaItem['menuOrder'] || is_integer( $mediaItem['menuOrder'] ) ) );
$this->assertTrue( ( null === $mediaItem['mimeType'] || is_string( $mediaItem['mimeType'] ) ) );
$this->assertTrue( ( null === $mediaItem['modified'] || is_string( $mediaItem['modified'] ) ) );
$this->assertTrue( ( null === $mediaItem['modifiedGmt'] || is_string( $mediaItem['modifiedGmt'] ) ) );
$this->assertTrue( ( null === $mediaItem['pingStatus'] || is_string( $mediaItem['pingStatus'] ) ) );
$this->assertTrue( ( empty( $mediaItem['pinged'] ) || is_array( $mediaItem['pinged'] ) ) );
$this->assertTrue( ( null === $mediaItem['slug'] || is_string( $mediaItem['slug'] ) ) );
$this->assertTrue( ( null === $mediaItem['sourceUrl'] || is_string( $mediaItem['sourceUrl'] ) ) );
$this->assertTrue( ( null === $mediaItem['status'] || is_string( $mediaItem['status'] ) ) );
$this->assertTrue( ( null === $mediaItem['title'] || is_string( $mediaItem['title'] ) ) );
$this->assertTrue( ( empty( $mediaItem['toPing'] ) || is_array( $mediaItem['toPing'] ) ) );
$this->assertEquals(
[
'id' => $post_global_id,
],
$mediaItem['parent']
);
$this->assertNotEmpty( $mediaItem['description'] );
$this->assertEquals( apply_filters( 'the_content', $image_description ), $mediaItem['description'] );
$this->assertNotEmpty( $mediaItem['mediaDetails'] );
$mediaDetails = $mediaItem['mediaDetails'];
$this->assertEquals( $meta_data['file'], $mediaDetails['file'] );
$this->assertEquals( $meta_data['height'], $mediaDetails['height'] );
$this->assertEquals( $meta_data['width'], $mediaDetails['width'] );
$this->assertNotEmpty( $mediaDetails['meta'] );
$meta = $mediaDetails['meta'];
$this->assertEquals( $meta_data['image_meta']['aperture'], $meta['aperture'] );
$this->assertEquals( $meta_data['image_meta']['credit'], $meta['credit'] );
$this->assertEquals( $meta_data['image_meta']['camera'], $meta['camera'] );
$this->assertEquals( $meta_data['image_meta']['caption'], $meta['caption'] );
$this->assertEquals( $meta_data['image_meta']['created_timestamp'], $meta['createdTimestamp'] );
$this->assertEquals( $meta_data['image_meta']['copyright'], $meta['copyright'] );
$this->assertEquals( $meta_data['image_meta']['focal_length'], $meta['focalLength'] );
$this->assertEquals( $meta_data['image_meta']['iso'], $meta['iso'] );
$this->assertEquals( $meta_data['image_meta']['shutter_speed'], $meta['shutterSpeed'] );
$this->assertEquals( $meta_data['image_meta']['title'], $meta['title'] );
$this->assertEquals( $meta_data['image_meta']['orientation'], $meta['orientation'] );
$this->assertNotEmpty( $meta_data['image_meta']['keywords'] );
$keywords = $meta_data['image_meta']['keywords'];
$this->assertEquals( 'keyword1', $keywords[0] );
$this->assertEquals( 'keyword2', $keywords[1] );
$this->assertNotEmpty( $meta_data['sizes'] );
$sizes = $mediaDetails['sizes'];
$this->assertEquals( 'thumbnail', $sizes[0]['name'] );
$this->assertEquals( 'example-thumbnail.jpg', $sizes[0]['file'] );
$this->assertEquals( 150, $sizes[0]['height'] );
$this->assertEquals( 150, $sizes[0]['width'] );
$this->assertEquals( 'image/jpeg', $sizes[0]['mimeType'] );
$this->assertEquals( 'example-thumbnail.jpg', $sizes[0]['sourceUrl'] );
}
}

View File

@@ -0,0 +1,496 @@
<?php
class NodesTest extends \Codeception\TestCase\WPTestCase {
public $admin;
public function setUp() {
// before
parent::setUp();
$this->admin = $this->factory()->user->create( [
'role' => 'administrator'
] );
}
public function tearDown() {
// then
parent::tearDown();
}
public function testNodeQueryWithVariables() {
/**
* Set up the $args
*/
$args = array(
'post_status' => 'publish',
'post_content' => 'Test page content',
'post_title' => 'Test Page Title',
'post_type' => 'page',
'post_author' => $this->admin,
);
/**
* Create the page
*/
$page_id = $this->factory->post->create( $args );
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'page', $page_id );
/**
* Create the query string to pass to the $query
*/
$query = '
query getPageByNode( $id:ID! ) {
node( id:$id ) {
__typename
...on Page {
pageId
}
}
}';
$variables = wp_json_encode( [
'id' => $global_id,
] );
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query, 'getPageByNode', $variables );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'node' => [
'__typename' => 'Page',
'pageId' => $page_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testPageNodeQuery
*
* @since 0.0.5
*/
public function testPageNodeQuery() {
/**
* Set up the $args
*/
$args = array(
'post_status' => 'publish',
'post_content' => 'Test page content',
'post_title' => 'Test Page Title',
'post_type' => 'page',
'post_author' => $this->admin,
);
/**
* Create the page
*/
$page_id = $this->factory->post->create( $args );
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'page', $page_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
node(id: \"{$global_id}\") {
__typename
...on Page {
pageId
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query, '', '' );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'node' => [
'__typename' => 'Page',
'pageId' => $page_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testPostNodeQuery
*
* @since 0.0.5
*/
public function testPostNodeQuery() {
$args = array(
'post_status' => 'publish',
'post_content' => 'Test post content',
'post_title' => 'Test post Title',
'post_type' => 'post',
'post_author' => $this->admin,
);
$post_id = $this->factory->post->create( $args );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'post', $post_id );
$query = "
query {
node(id: \"{$global_id}\") {
__typename
... on Post {
postId
}
}
}";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'__typename' => 'Post',
'postId' => $post_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testAttachmentNodeQuery
*
* @since 0.0.5
*/
public function testAttachmentNodeQuery() {
$args = array(
'post_status' => 'inherit',
'post_content' => 'Test attachment content',
'post_title' => 'Test attachment Title',
'post_type' => 'attachment',
'post_author' => $this->admin,
);
$attachment_id = $this->factory->post->create( $args );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'attachment', $attachment_id );
$query = "
query {
node(id: \"{$global_id}\") {
__typename
...on MediaItem {
mediaItemId
}
}
}";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'__typename' => 'MediaItem',
'mediaItemId' => $attachment_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testPluginNodeQuery
*
* @since 0.0.5
*/
public function testPluginNodeQuery() {
$plugin_name = 'Hello Dolly';
$global_id = \GraphQLRelay\Relay::toGlobalId( 'plugin', $plugin_name );
$query = "
query {
node(id: \"{$global_id}\") {
__typename
... on Plugin {
name
}
}
}";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'__typename' => 'Plugin',
'name' => $plugin_name,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testThemeNodeQuery
*
* @since 0.0.5
*/
public function testThemeNodeQuery() {
$theme_slug = 'twentyseventeen';
$global_id = \GraphQLRelay\Relay::toGlobalId( 'theme', $theme_slug );
$query = "
query {
node(id: \"{$global_id}\") {
__typename
...on Theme{
slug
}
}
}";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'__typename' => 'Theme',
'slug' => $theme_slug,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testUserNodeQuery
*
* @since 0.0.5
*/
public function testUserNodeQuery() {
$user_args = array(
'role' => 'editor',
'user_email' => 'graphqliscool@wpgraphql.com',
);
$user_id = $this->factory->user->create( $user_args );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
$query = "
query {
node(id: \"{$global_id}\") {
__typename
...on User{
userId
}
}
}
";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'__typename' => 'User',
'userId' => $user_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testCommentNodeQuery
*
* @since 0.0.5
*/
public function testCommentNodeQuery() {
$user_args = array(
'role' => 'editor',
'user_email' => 'graphqliscool@wpgraphql.com',
);
$user_id = $this->factory->user->create( $user_args );
$comment_args = array(
'user_id' => $user_id,
'comment_content' => 'GraphQL is really awesome, dude!',
);
$comment_id = $this->factory->comment->create( $comment_args );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id );
$query = "
query {
node(id: \"{$global_id}\") {
__typename
...on Comment{
commentId
}
}
}
";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'__typename' => 'Comment',
'commentId' => $comment_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* Tests querying for a single post node
*/
public function testSuccessfulPostTypeResolver() {
$query = "
{
node(id:\"cG9zdFR5cGU6cG9zdA==\"){
...on PostType {
name
}
}
}
";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'name' => 'post',
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* Tests querying for a single post node where the post id doesn't exist
*/
public function testUnsuccessfulPostTypeResolver() {
$query = "
{
node(id:\"cG9zdFR5cGU6dGVzdA==\"){
...on PostType {
name
}
}
}
";
$actual = do_graphql_request( $query );
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* Tests querying for a single taxonomy node
*/
public function testSuccessfulTaxonomyResolver() {
$query = "
{
node(id:\"dGF4b25vbXk6Y2F0ZWdvcnk=\"){
...on Taxonomy {
name
}
}
}
";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'node' => [
'name' => 'category',
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* Tests querying for a single taxonomy node where the ID doesn't exist
*/
public function testUnsuccessfulTaxonomyResolver() {
$query = "
{
node(id:\"dGF4b25vbXk6dGVzdA==\"){
...on Taxonomy {
name
}
}
}
";
$actual = do_graphql_request( $query );
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* Tests querying for a single comment node where the comment ID doesn't exist
*/
public function testUnsuccessfulCommentResolver() {
$query = "
{
node(id:\"Y29tbWVudDo5OTk5\"){
...on Comment {
id
}
}
}
";
$actual = do_graphql_request( $query );
$this->assertArrayHasKey( 'errors', $actual );
}
}

View File

@@ -0,0 +1,125 @@
<?php
class PluginConnectionQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $admin;
public function setUp() {
parent::setUp();
$this->current_time = strtotime( 'now' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* testPluginsQuery
* This tests querying for a list of plugins.
* The test suite should have Hello Dolly and Akismet plugins, so this
* should return those plugins.
* @since 0.0.5
*/
public function testPluginsQuery() {
$query = '
{
plugins {
edges {
node {
id
name
}
}
nodes {
id
}
}
}
';
$actual = do_graphql_request( $query );
/**
* We don't really care what the specifics are because the default plugins could change at any time
* and we don't care to maintain the exact match, we just want to make sure we are
* properly getting a theme back in the query
*/
$this->assertNotEmpty( $actual['data']['plugins']['edges'] );
$this->assertNotEmpty( $actual['data']['plugins']['edges'][0]['node']['id'] );
$this->assertNotEmpty( $actual['data']['plugins']['edges'][0]['node']['name'] );
$this->assertNotEmpty( $actual['data']['plugins']['nodes'][0]['id'] );
$this->assertEquals( $actual['data']['plugins']['nodes'][0]['id'], $actual['data']['plugins']['edges'][0]['node']['id'] );
foreach ( $actual['data']['plugins']['edges'] as $key => $edge ) {
$this->assertEquals( $actual['data']['plugins']['nodes'][ $key ]['id'], $edge['node']['id'] );
}
}
/**
* testPluginQuery
* @since 0.0.5
*/
public function testPluginQuery() {
$query = '
{
plugin(id: "cGx1Z2luOkhlbGxvIERvbGx5"){
id
name
author
authorUri
description
name
pluginUri
version
}
}
';
$actual = do_graphql_request( $query );
/**
* We don't really care what the specifics are because the default plugins could change at any time
* and we don't care to maintain the exact match, we just want to make sure we are
* properly getting a theme back in the query
*/
$this->assertNotEmpty( $actual['data']['plugin']['id'] );
$this->assertNotEmpty( $actual['data']['plugin']['name'] );
$plugin_id = $actual['data']['plugin']['id'];
$this->assertTrue( ( is_string( $plugin_id ) || null === $plugin_id ) );
$plugin_name = $actual['data']['plugin']['name'];
$this->assertTrue( ( is_string( $plugin_name ) || null === $plugin_name ) );
$plugin_author = $actual['data']['plugin']['author'];
$this->assertTrue( ( is_string( $plugin_author ) || null === $plugin_author ) );
$plugin_author_uri = $actual['data']['plugin']['authorUri'];
$this->assertTrue( ( is_string( $plugin_author_uri ) || null === $plugin_author_uri ) );
$plugin_description = $actual['data']['plugin']['description'];
$this->assertTrue( ( is_string( $plugin_description ) || null === $plugin_description ) );
$plugin_uri = $actual['data']['plugin']['pluginUri'];
$this->assertTrue( ( is_string( $plugin_uri ) || null === $plugin_uri ) );
$plugin_version = $actual['data']['plugin']['version'];
$this->assertTrue( ( is_string( $plugin_version ) || null === $plugin_version ) );
}
}

View File

@@ -0,0 +1,123 @@
<?php
class PluginObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
/**
* testPluginQuery
*
* This tests creating a single plugin with data and retrieving said plugin via a GraphQL query
*
* @since 0.0.5
*/
public function testPluginQuery() {
/**
* Create the global ID based on the plugin_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'plugin', 'Hello Dolly' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
plugin(id: \"{$global_id}\") {
author
authorUri
description
id
name
pluginUri
version
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'plugin' => [
'author' => 'Matt Mullenweg',
'authorUri' => 'http://ma.tt/',
'description' => 'This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.',
'id' => $global_id,
'name' => 'Hello Dolly',
'pluginUri' => 'http://wordpress.org/plugins/hello-dolly/',
'version' => '1.6',
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testPluginQueryWherePluginDoesNotExist
*
* Tests a query for non existant plugin.
*
* @since 0.0.5
*/
public function testPluginQueryWherePluginDoesNotExist() {
/**
* Create the global ID based on the plugin_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'plugin', 'doesNotExist' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
plugin(id: \"{$global_id}\") {
version
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'plugin' => null,
],
'errors' => [
[
'message' => 'No plugin was found with the name doesNotExist',
'locations' => [
[
'line' => 3,
'column' => 4,
],
],
'path' => [
'plugin',
],
'category' => 'user',
],
],
];
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,708 @@
<?php
class PostObjectConnectionQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $created_post_ids;
public $admin;
public function setUp() {
parent::setUp();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
$this->created_post_ids = $this->create_posts();
$this->app_context = new \WPGraphQL\AppContext();
$this->app_info = new \GraphQL\Type\Definition\ResolveInfo( array() );
}
public function tearDown() {
parent::tearDown();
}
public function createPostObject( $args ) {
/**
* Set up the $defaults
*/
$defaults = [
'post_author' => $this->admin,
'post_content' => 'Test page content',
'post_excerpt' => 'Test excerpt',
'post_status' => 'publish',
'post_title' => 'Test Title',
'post_type' => 'post',
'post_date' => $this->current_date,
'has_password' => false,
'post_password'=> null,
];
/**
* Combine the defaults with the $args that were
* passed through
*/
$args = array_merge( $defaults, $args );
/**
* Create the page
*/
$post_id = $this->factory->post->create( $args );
/**
* Update the _edit_last and _edit_lock fields to simulate a user editing the page to
* test retrieving the fields
*
* @since 0.0.5
*/
update_post_meta( $post_id, '_edit_lock', $this->current_time . ':' . $this->admin );
update_post_meta( $post_id, '_edit_last', $this->admin );
/**
* Return the $id of the post_object that was created
*/
return $post_id;
}
/**
* Creates several posts (with different timestamps) for use in cursor query tests
*
* @return array
*/
public function create_posts() {
// Create 20 posts
$created_posts = [];
for ( $i = 1; $i <= 200; $i ++ ) {
// Set the date 1 minute apart for each post
$date = date( 'Y-m-d H:i:s', strtotime( "-1 day +{$i} minutes" ) );
$created_posts[ $i ] = $this->createPostObject( [
'post_type' => 'post',
'post_date' => $date,
'post_status' => 'publish',
'post_title' => $i,
] );
}
return $created_posts;
}
public function postsQuery( $variables ) {
$query = 'query postsQuery($first:Int $last:Int $after:String $before:String $where:RootPostsQueryArgs){
posts( first:$first last:$last after:$after before:$before where:$where ) {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
id
postId
title
date
}
}
nodes {
id
postId
}
}
}';
return do_graphql_request( $query, 'postsQuery', $variables );
}
public function testFirstPost() {
/**
* Here we're querying the first post in our dataset
*/
$variables = [
'first' => 1,
];
$results = $this->postsQuery( $variables );
/**
* Let's query the first post in our data set so we can test against it
*/
$first_post = new WP_Query( [
'posts_per_page' => 1,
] );
$first_post_id = $first_post->posts[0]->ID;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $first_post_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['posts']['edges'] ) );
$this->assertEquals( $first_post_id, $results['data']['posts']['edges'][0]['node']['postId'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['endCursor'] );
$this->assertEquals( $first_post_id, $results['data']['posts']['nodes'][0]['postId'] );
$this->forwardPagination( $expected_cursor );
}
public function testLastPost() {
/**
* Here we're trying to query the last post in our dataset
*/
$variables = [
'last' => 1,
];
$results = $this->postsQuery( $variables );
/**
* Let's query the last post in our data set so we can test against it
*/
$last_post = new WP_Query( [
'posts_per_page' => 1,
'order' => 'ASC',
] );
$last_post_id = $last_post->posts[0]->ID;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $last_post_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['posts']['edges'] ) );
$this->assertEquals( $last_post_id, $results['data']['posts']['edges'][0]['node']['postId'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['endCursor'] );
$this->backwardPagination( $expected_cursor );
}
public function forwardPagination( $cursor ) {
$variables = [
'first' => 1,
'after' => $cursor,
];
$results = $this->postsQuery( $variables );
$second_post = new WP_Query( [
'posts_per_page' => 1,
'paged' => 2,
] );
$second_post_id = $second_post->posts[0]->ID;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $second_post_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['posts']['edges'] ) );
$this->assertEquals( $second_post_id, $results['data']['posts']['edges'][0]['node']['postId'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['endCursor'] );
}
public function backwardPagination( $cursor ) {
$variables = [
'last' => 1,
'before' => $cursor,
];
$results = $this->postsQuery( $variables );
$second_to_last_post = new WP_Query( [
'posts_per_page' => 1,
'paged' => 2,
'order' => 'ASC',
] );
$second_to_last_post_id = $second_to_last_post->posts[0]->ID;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $second_to_last_post_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['posts']['edges'] ) );
$this->assertEquals( $second_to_last_post_id, $results['data']['posts']['edges'][0]['node']['postId'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['posts']['pageInfo']['endCursor'] );
}
public function testMaxQueryAmount() {
$variables = [
'first' => 150,
];
$results = $this->postsQuery( $variables );
$this->assertNotEmpty( $results );
/**
* The max that can be queried by default is 100 items
*/
$this->assertCount( 100, $results['data']['posts']['edges'] );
$this->assertTrue( $results['data']['posts']['pageInfo']['hasNextPage'] );
/**
* Test the filter to make sure it's capping the results properly
*/
add_filter( 'graphql_connection_max_query_amount', function() {
return 20;
} );
$variables = [
'first' => 150,
];
$results = $this->postsQuery( $variables );
add_filter( 'graphql_connection_max_query_amount', function() {
return 100;
} );
$this->assertCount( 20, $results['data']['posts']['edges'] );
$this->assertTrue( $results['data']['posts']['pageInfo']['hasNextPage'] );
}
public function testPostHasPassword() {
// Create a test post with a password
$this->createPostObject( [
'post_title' => 'Password protected',
'post_type' => 'post',
'post_status' => 'publish',
'post_password' => 'password',
] );
/**
* WP_Query posts with a password
*/
$wp_query_posts_with_password = new WP_Query( [
'has_password' => true,
] );
/**
* GraphQL query posts that have a password
*/
$variables = [
'where' => [
'hasPassword' => true,
],
];
$request = $this->postsQuery( $variables );
$this->assertNotEmpty( $request );
$this->assertArrayNotHasKey( 'errors', $request );
$edges = $request['data']['posts']['edges'];
$this->assertNotEmpty( $edges );
/**
* Loop through all the returned posts
*/
foreach ( $edges as $edge ) {
/**
* Assert that all posts returned have a password, since we queried for
* posts using "has_password => true"
*/
$password = get_post( $edge['node']['postId'] )->post_password;
$this->assertNotEmpty( $password );
}
}
public function testPageWithChildren() {
$parent_id = $this->factory->post->create( [
'post_type' => 'page'
] );
$child_id = $this->factory->post->create( [
'post_type' => 'page',
'post_parent' => $parent_id
] );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'page', $parent_id );
$global_child_id = \GraphQLRelay\Relay::toGlobalId( 'page', $child_id );
$query = '
{
page( id: "' . $global_id . '" ) {
id
pageId
childPages {
edges {
node {
id
pageId
}
}
}
}
}
';
$actual = do_graphql_request( $query );
/**
* Make sure the query didn't return any errors
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$parent = $actual['data']['page'];
$child = $parent['childPages']['edges'][0]['node'];
/**
* Make sure the child and parent data matches what we expect
*/
$this->assertEquals( $global_id, $parent['id'] );
$this->assertEquals( $parent_id, $parent['pageId'] );
$this->assertEquals( $global_child_id, $child['id'] );
$this->assertEquals( $child_id, $child['pageId'] );
}
public function testSanitizeInputFieldsAuthorArgs() {
$mock_args = [
'authorName' => 'testAuthorName',
'authorIn' => [ 1, 2, 3 ],
'authorNotIn' => [ 4, 5, 6 ],
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertEquals( 'testAuthorName', $actual['author_name'] );
$this->assertEquals( [ 1, 2, 3 ], $actual['author__in'] );
$this->assertEquals( [ 4, 5, 6 ], $actual['author__not_in'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'authorName', $actual );
$this->assertArrayNotHasKey( 'authorIn', $actual );
$this->assertArrayNotHasKey( 'authorNotIn', $actual );
}
public function testSanitizeInputFieldsCategoryArgs() {
$mock_args = [
'categoryId' => 1,
'categoryName' => 'testCategory',
'categoryIn' => [ 4, 5, 6 ],
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertEquals( 1, $actual['cat'] );
$this->assertEquals( 'testCategory', $actual['category_name'] );
$this->assertEquals( [ 4, 5, 6 ], $actual['category__in'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'categoryId', $actual );
$this->assertArrayNotHasKey( 'categoryName', $actual );
$this->assertArrayNotHasKey( 'categoryIn', $actual );
}
public function testSanitizeInputFieldsTagArgs() {
$mock_args = [
'tagId' => 1,
'tagIds' => [ 1, 2, 3 ],
'tagSlugAnd' => [ 4, 5, 6 ],
'tagSlugIn' => [ 6, 7, 8 ],
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertEquals( 1, $actual['tag_id'] );
$this->assertEquals( [ 1, 2, 3 ], $actual['tag__and'] );
$this->assertEquals( [ 4, 5, 6 ], $actual['tag_slug__and'] );
$this->assertEquals( [ 6, 7, 8 ], $actual['tag_slug__in'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'tagId', $actual );
$this->assertArrayNotHasKey( 'tagIds', $actual );
$this->assertArrayNotHasKey( 'tagSlugAnd', $actual );
$this->assertArrayNotHasKey( 'tagSlugIn', $actual );
}
public function testSanitizeInputFieldsSearchArgs() {
$mock_args = [
'search' => 'testSearchString',
'id' => 1,
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertEquals( 'testSearchString', $actual['s'] );
$this->assertEquals( 1, $actual['p'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'search', $actual );
$this->assertArrayNotHasKey( 'id', $actual );
}
public function testSanitizeInputFieldsParentArgs() {
$mock_args = [
'parent' => 2,
'parentIn' => [ 3, 4, 5 ],
'parentNotIn' => [ 6, 7, 8 ],
'in' => [ 9, 10, 11 ],
'notIn' => [ 12, 13, 14 ],
'nameIn' => [ 'testPost1', 'testPost2', 'testPost3' ],
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertEquals( 2, $actual['post_parent'] );
$this->assertEquals( [ 3, 4, 5 ], $actual['post_parent__in'] );
$this->assertEquals( [ 6, 7, 8 ], $actual['post_parent__not_in'] );
$this->assertEquals( [ 9, 10, 11 ], $actual['post__in'] );
$this->assertEquals( [ 12, 13, 14 ], $actual['post__not_in'] );
$this->assertEquals( [ 'testPost1', 'testPost2', 'testPost3' ], $actual['post_name__in'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'parent', $actual );
$this->assertArrayNotHasKey( 'parentIn', $actual );
$this->assertArrayNotHasKey( 'parentNotIn', $actual );
$this->assertArrayNotHasKey( 'in', $actual );
$this->assertArrayNotHasKey( 'notIn', $actual );
$this->assertArrayNotHasKey( 'nameIn', $actual );
}
public function testSanitizeInputFieldsMiscArgs() {
$mock_args = [
'hasPassword' => true,
'password' => 'myPostPassword123',
'status' => 'publish',
'dateQuery' => array(
array(
'year' => 2012,
'month' => 12,
'day' => 12,
),
),
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertTrue( $actual['has_password'] );
$this->assertEquals( 'myPostPassword123', $actual['post_password'] );
$this->assertEquals( 'publish', $actual['post_status'] );
$this->assertEquals(
array(
array(
'year' => 2012,
'month' => 12,
'day' => 12,
),
)
, $actual['date_query'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'hasPassword', $actual );
$this->assertArrayNotHasKey( 'password', $actual );
$this->assertArrayNotHasKey( 'status', $actual );
$this->assertArrayNotHasKey( 'dateQuery', $actual );
}
public function testSanitizeInputFieldsListOfPostStatusEnum() {
$mock_args = [
'stati' => [ 'publish', 'private' ],
];
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info );
/**
* Make sure the returned values are equal to mock args
*/
$this->assertEquals( ['publish', 'private'], $actual['post_status'] );
/**
* Make sure the query didn't return these array values
*/
$this->assertArrayNotHasKey( 'status', $actual );
}
/**
* @group get_query_args
*/
public function testGetQueryArgs() {
/**
* Mock args
*/
$mock_args = array(
'orderby' => 'DESC',
'where' => array(
'orderby' => array(
array(
'field' => 'author',
'order' => 'ASC',
),
),
),
);
/**
* Create post
*/
$test_post = $this->factory->post->create();
$source = get_post( $test_post );
/**
* New page
*/
$actual = new \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver( 'page' );
$actual = $actual::get_query_args( $source, $mock_args, $this->app_context, $this->app_info );
/**
* Expected result
*/
$expected = array(
'post_type' => 'page',
'no_found_rows' => true,
'post_status' => 'publish',
'posts_per_page' => 11,
'post_parent' => $test_post,
'graphql_cursor_offset' => 0,
'graphql_cursor_compare' => '<',
'graphql_args' => array(
'orderby' => 'DESC',
'where' => array(
'orderby' => array(
0 => array(
'field' => 'author',
'order' => 'ASC',
)
),
),
),
'orderby' => array(
'author' => 'ASC',
),
);
/**
* Make sure the expected result is equal to the response of $actual
*/
$this->assertEquals( $expected, $actual );
}
/**
* @group get_query_args
*/
public function testGetQueryArgsAttachment() {
/**
* Mock args
*/
$mock_args = array(
'post_status' => 'publish',
);
/**
* Create attachment
*/
$child_id = $this->factory->post->create( [
'post_type' => 'attachment',
] );
$post_type = 'attachment';
$source = get_post( $child_id );
/**
* New post type attachment
*/
$actual = new \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver( $post_type );
$actual = $actual->get_query_args( $source, $mock_args, $this->app_context, $this->app_info );
/**
* Make sure the post status is equal to inherit
*/
$this->assertEquals( 'inherit', $actual['post_status'] );
/**
* Make sure get_query_args is setting the post id as post_parent
*/
$this->assertEquals( $child_id, $actual['post_parent'] );
}
/**
* @group get_query_args
*/
public function testGetQueryArgsPostType() {
/**
* Get post type object
*/
$source = get_post_type_object( 'post' );
$mock_args = array();
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::get_query_args( $source, $mock_args, $this->app_context, $this->app_info );
/**
* Make sure that post type is equals to post
*/
$this->assertEquals( 'post', $actual['post_type'] );
}
/**
* @group get_query_args
*/
public function testGetQueryArgsUser() {
/**
* Create a user
*/
$user_id = $this->factory->user->create();
$source = get_user_by( 'ID', $user_id );
$mock_args = array();
$actual = \WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver::get_query_args( $source, $mock_args, $this->app_context, $this->app_info );
/**
* Make sure the author is equal to the user previously created
*/
$this->assertEquals( $user_id, $actual['author'] );
}
}

View File

@@ -0,0 +1,801 @@
<?php
class PostObjectMutationsTest extends \Codeception\TestCase\WPTestCase {
public $title;
public $content;
public $client_mutation_id;
public $admin;
public $subscriber;
public $author;
public function setUp() {
// before
parent::setUp();
$this->title = 'some title';
$this->content = 'some content';
$this->client_mutation_id = 'someUniqueId';
$this->author = $this->factory()->user->create( [
'role' => 'author',
] );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
$this->subscriber = $this->factory()->user->create( [
'role' => 'subscriber',
] );
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* This processes a mutation to create a post
*
* @return array
*/
public function createPostMutation() {
$mutation = '
mutation createPost( $clientMutationId:String!, $title:String!, $content:String! ){
createPost(
input:{
clientMutationId:$clientMutationId,
title:$title
content:$content
}
){
clientMutationId
post{
title
content
}
}
}
';
$variables = wp_json_encode( [
'clientMutationId' => $this->client_mutation_id,
'title' => $this->title,
'content' => $this->content,
] );
$actual = do_graphql_request( $mutation, 'createPost', $variables );
return $actual;
}
public function createPageMutation() {
$mutation = '
mutation createPage( $clientMutationId:String!, $title:String!, $content:String! ){
createPage(
input:{
clientMutationId:$clientMutationId,
title:$title
content:$content
}
){
clientMutationId
page{
title
content
}
}
}
';
$variables = wp_json_encode( [
'clientMutationId' => $this->client_mutation_id,
'title' => $this->title,
'content' => $this->content,
] );
$actual = do_graphql_request( $mutation, 'createPage', $variables );
return $actual;
}
public function testUpdatePageMutation() {
$args = [
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => 'Original Title',
'post_content' => 'Original Content',
];
/**
* Create a page to test against
*/
$page_id = $this->factory()->post->create( $args );
/**
* Get the new page object
*/
$new_page = get_post( $page_id );
/**
* Verify the page was created with the original content as expected
*/
$this->assertEquals( $new_page->post_type, 'page' );
$this->assertEquals( $new_page->post_title, 'Original Title' );
$this->assertEquals( $new_page->post_content, 'Original Content' );
/**
* Prepare the mutation
*/
$mutation = '
mutation updatePageTest( $clientMutationId:String! $id:ID! $title:String $content:String ){
updatePage(
input: {
clientMutationId:$clientMutationId
id:$id,
title:$title,
content:$content,
}
) {
clientMutationId
page{
id
title
content
pageId
}
}
}';
/**
* Set the variables to use with the mutation
*/
$variables = wp_json_encode( [
'id' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'title' => 'Some updated title',
'content' => 'Some updated content',
'clientMutationId' => 'someId',
] );
/**
* Set the current user as the subscriber so we can test, and expect to fail
*/
wp_set_current_user( $this->subscriber );
/**
* Execute the request
*/
$actual = do_graphql_request( $mutation, 'updatePageTest', $variables );
/**
* We should get an error because the user is a subscriber and can't edit posts
*/
$this->assertArrayHasKey( 'errors', $actual );
/**
* Set the current user to a user with permission to edit posts, but NOT permission to edit OTHERS posts
*/
wp_set_current_user( $this->author );
/**
* Execute the request
*/
$actual = do_graphql_request( $mutation, 'updatePageTest', $variables );
/**
* We should get an error because the user is an and can't edit others posts
*/
$this->assertArrayHasKey( 'errors', $actual );
/**
* Set the current user as the admin role so we
* successfully run the mutation
*/
wp_set_current_user( $this->admin );
/**
* Execute the request
*/
$actual = do_graphql_request( $mutation, 'updatePageTest', $variables );
/**
* Define the expected output.
*
* The mutation should've updated the article to contain the updated content
*/
$expected = [
'data' => [
'updatePage' => [
'clientMutationId' => 'someId',
'page' => [
'id' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'title' => apply_filters( 'the_title', 'Some updated title' ),
'content' => apply_filters( 'the_content', 'Some updated content' ),
'pageId' => $page_id,
],
],
],
];
/**
* Compare the actual output vs the expected output
*/
$this->assertEquals( $actual, $expected );
/**
* Make sure the edit lock is removed after the mutation has finished
*/
$this->assertFalse( get_post_meta( '_edit_lock', $page_id, true ) );
}
public function testDeletePageMutation() {
/**
* Set the current user as the admin role so we
* can test the mutation
*/
wp_set_current_user( $this->subscriber );
$args = [
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => 'Original Title',
'post_content' => 'Original Content',
];
/**
* Create a page to test against
*/
$page_id = $this->factory()->post->create( $args );
/**
* Get the new page object
*/
$new_page = get_post( $page_id );
/**
* Verify the page was created with the original content as expected
*/
$this->assertEquals( $new_page->post_type, 'page' );
$this->assertEquals( $new_page->post_title, 'Original Title' );
$this->assertEquals( $new_page->post_content, 'Original Content' );
/**
* Prepare the mutation
*/
$mutation = '
mutation deletePageTest($input:DeletePageInput!){
deletePage(input:$input){
clientMutationId
deletedId
page{
id
title
content
pageId
}
}
}';
/**
* Set the variables to use with the mutation
*/
$variables = [
'input' => [
'id' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'clientMutationId' => 'someId',
],
];
/**
* Execute the request
*/
$actual = do_graphql_request( $mutation, 'deletePageTest', $variables );
/**
* The deletion should fail because we're a subscriber
*/
$this->assertArrayHasKey( 'errors', $actual );
/**
* Set the user to an admin and try again
*/
wp_set_current_user( $this->admin );
/**
* Execute the request
*/
$actual = do_graphql_request( $mutation, 'deletePageTest', $variables );
/**
* Define the expected output.
*
* The mutation should've updated the article to contain the updated content
*/
$expected = [
'data' => [
'deletePage' => [
'clientMutationId' => 'someId',
'deletedId' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'page' => [
'id' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'title' => apply_filters( 'the_title', 'Original Title' ),
'content' => apply_filters( 'the_content', 'Original Content' ),
'pageId' => $page_id,
],
],
],
];
/**
* Compare the actual output vs the expected output
*/
$this->assertEquals( $actual, $expected );
/**
* Try to delete again
*/
$actual = do_graphql_request( $mutation, 'deletePageTest', $variables );
/**
* We should get an error because we're not using forceDelete
*/
$this->assertArrayHasKey( 'errors', $actual );
/**
* Try to delete again, this time with forceDelete
*/
$variables = [
'input' => [
'id' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'clientMutationId' => 'someId',
'forceDelete' => true,
],
];
$actual = do_graphql_request( $mutation, 'deletePageTest', $variables );
/**
* This time, we used forceDelete so the mutation should have succeeded
*/
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertEquals( 'someId', $actual['data']['deletePage']['clientMutationId'] );
$this->assertEquals( \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ), $actual['data']['deletePage']['deletedId'] );
/**
* Try to delete the page one more time, and now there's nothing to delete, not even from the trash
*/
$actual = do_graphql_request( $mutation, 'deletePageTest', $variables );
/**
* Now we should have errors again, because there's nothing to be deleted
*/
$this->assertArrayHasKey( 'errors', $actual );
}
public function testUpdatePostWithInvalidId() {
$mutation = '
mutation updatePostWithInvalidId($input:updatePostInput!) {
updatePost(input:$input) {
clientMutationId
}
}
';
$variables = [
'input' => [
'clientMutationId' => 'someId',
'id' => 'invalidIdThatShouldThrowAnError',
],
];
$actual = do_graphql_request( $mutation, 'updatePostWithInvalidId', $variables );
/**
* We should get an error thrown if we try and update a post with an invalid id
*/
$this->assertArrayHasKey( 'errors', $actual );
$page_id = $this->factory()->post->create( [
'post_type' => 'page',
] );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'page', $page_id );
$variables = [
'input' => [
'clientMutationId' => 'someId',
'id' => $global_id,
],
];
/**
* Try to update a post, with a valid ID of a page
*/
$actual = do_graphql_request( $mutation, 'updatePostWithInvalidId', $variables );
/**
* We should get an error here because the updatePost mutation should only be able to update "post" objects
*/
$this->assertArrayHasKey( 'errors', $actual );
}
public function testDeletePostOfAnotherType() {
$args = [
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => 'Original Title',
'post_content' => 'Original Content',
];
/**
* Create a page to test against
*/
$page_id = $this->factory()->post->create( $args );
$mutation = '
mutation deletePostWithPageIdShouldFail{
deletePost( $clientMutationId:String! $id:ID! ){
post{
id
}
}
}
';
$variables = wp_json_encode( [
'id' => \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ),
'clientMutationId' => 'someId',
] );
/**
* Run the mutation
*/
$actual = do_graphql_request( $mutation, 'deletePostWithPageIdShouldFail', $variables );
/**
* The mutation should fail because the ID is for a page, but we're trying to delete a post
*/
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* This tests to make sure a user without proper capabilities cannot create a post
*/
public function testCreatePostObjectWithoutProperCapabilities() {
/**
* Set the current user as the subscriber role so we
* can test the mutation and make sure they cannot create a post
* since they don't have proper permissions
*/
wp_set_current_user( $this->subscriber );
/**
* Run the mutation.
*/
$actual = $this->createPostMutation();
/**
* We're asserting that this will properly return an error
* because this user doesn't have permissions to create a post as a
* subscriber
*/
$this->assertNotEmpty( $actual['errors'] );
}
/**
* This tests a createPage mutation by an admin, to verify that a user WITH proper
* capabilities can create a page
*/
public function testCreatePageObjectByAdmin() {
/**
* Set the current user as the admin role so we
* can test the mutation
*/
wp_set_current_user( $this->admin );
/**
* Run the mutation
*/
$actual = $this->createPageMutation();
/**
* We're expecting to have createPage returned with a nested clientMutationId matching the
* clientMutationId we sent through, as well as the title and content we passed through in the mutation
*/
$expected = [
'data' => [
'createPage' => [
'clientMutationId' => $this->client_mutation_id,
'page' => [
'title' => apply_filters( 'the_title', $this->title ),
'content' => apply_filters( 'the_content', $this->content ),
],
],
],
];
$this->assertEquals( $expected, $actual );
}
public function testCreatePostWithNoInput() {
$mutation = '
mutation {
createPost{
post{
id
}
}
}
';
$actual = do_graphql_request( $mutation );
/**
* Make sure we're throwing an error if there's no $input with the mutation
*/
$this->assertArrayHasKey( 'errors', $actual );
}
public function createPostWithDatesMutation( $input ) {
wp_set_current_user( $this->admin );
$mutation = 'mutation createPost( $input:CreatePostInput! ) {
createPost(input: $input) {
post {
id
postId
title
date
dateGmt
modified
modifiedGmt
}
}
}
';
$defaults = [
'clientMutationId' => uniqid(),
'title' => 'New Post',
'status' => 'PUBLISH',
];
$input = array_merge( $defaults, $input );
$variables = [
'input' => $input,
];
/**
* Run the mutation.
*/
$results = do_graphql_request( $mutation, 'createPost', $variables );
return $results;
}
public function testDateInputsForCreatePost() {
/**
* Set the current user as the admin role so we
* can test the mutation
*/
wp_set_current_user( $this->admin );
/**
* Set the expected date outcome
*/
$dateExpected = '2017-01-03 00:00:00';
$dateGmtExpected = '2017-01-03T00:00:00';
$results = $this->createPostWithDatesMutation([
'date' => '1/3/2017',
'status' => 'PUBLISH'
]);
/**
* Make sure there are no errors
*/
$this->assertArrayNotHasKey( 'errors', $results );
/**
* We're expecting the date variable to match the date entry regardless of the way user enters it
*/
$this->assertEquals( $dateExpected, $results['data']['createPost']['post']['date'] );
$this->assertEquals( $dateGmtExpected, $results['data']['createPost']['post']['dateGmt'] );
$this->assertNotEquals( '0000-00-00 00:00:00', $results['data']['createPost']['post']['modified'] );
$this->assertNotEquals( '0000-00-00 00:00:00', $results['data']['createPost']['post']['modifiedGmt'] );
}
public function testDateInputsWithSlashFormattingForCreatePost() {
/**
* Set the current user as the admin role so we
* can test the mutation
*/
wp_set_current_user( $this->admin );
/**
* Set the input and expected date outcome
*/
$dateExpected = '2017-01-03 00:00:00';
$dateGmtExpected = '2017-01-03T00:00:00';
$results = $this->createPostWithDatesMutation([
'date' => '2017/01/03',
]);
/**
* Make sure there are no errors
*/
$this->assertArrayNotHasKey( 'errors', $results );
/**
* We're expecting the date variable to match the date entry regardless of the way user enters it
*/
$this->assertEquals( $dateExpected, $results['data']['createPost']['post']['date'] );
$this->assertEquals( $dateGmtExpected, $results['data']['createPost']['post']['dateGmt'] );
$this->assertNotEquals( '0000-00-00 00:00:00', $results['data']['createPost']['post']['modified'] );
$this->assertNotEquals( '0000-00-00 00:00:00', $results['data']['createPost']['post']['modifiedGmt'] );
}
public function testDateInputsWithStatusPendingAndDashesCreatePost() {
/**
* Set the current user as the admin role so we
* can test the mutation
*/
wp_set_current_user( $this->admin );
/**
* Set the input and expected date outcome
*/
$dateExpected = '2017-01-03 00:00:00';
$dateGmtExpected = null;
$results = $this->createPostWithDatesMutation([
'date' => '3-1-2017',
'status' => 'PENDING'
]);
/**
* Make sure there are no errors
*/
$this->assertArrayNotHasKey( 'errors', $results );
/**
* We're expecting the date variable to match the date entry regardless of the way user enters it
*/
$this->assertEquals( $dateExpected, $results['data']['createPost']['post']['date'] );
$this->assertEquals( $dateGmtExpected, $results['data']['createPost']['post']['dateGmt'] );
$this->assertNotEquals( '0000-00-00 00:00:00', $results['data']['createPost']['post']['modified'] );
$this->assertNotEquals( '0000-00-00 00:00:00', $results['data']['createPost']['post']['modifiedGmt'] );
}
public function testDateInputsWithDraftAndPublishUpdatePost() {
/**
* Set the current user as the admin role so we
* can test the mutation
*/
wp_set_current_user( $this->admin );
/**
* Create a post to test against and set global ID
*/
$test_post = $this->factory()->post->create( [
'post_title' => 'My Test Post',
'post_status' => 'draft',
] );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'post', $test_post );
/**
* Prepare mutation for GQL request
*/
$request = '
{
post( id: "'. $global_id . '" ) {
id
postId
title
date
dateGmt
modified
modifiedGmt
}
}
';
/**
* Run GQl request
*/
$results = do_graphql_request( $request );
/**
* Set the expected dateGmt outcome
*/
$dateGmtExpected = null;
/**
* Assert results dateGmt equals the expected outcome
*/
$this->assertEquals( $dateGmtExpected, $results['data']['post']['dateGmt'] );
/**
* Update post to test against status: published
*/
wp_update_post( [
'ID' => $test_post,
'post_status' => 'publish',
] );
/**
* Run GQl request
*/
$results = do_graphql_request( $request );
/**
* Assert timestamp is not null
*/
$this->assertNotNull( $results['data']['post']['dateGmt'] );
/**
* Update post back to draft
*/
wp_update_post( [
'ID' => $test_post,
'post_status' => 'draft'
] );
/**
* Run GQl request
*/
$results = do_graphql_request( $request );
/**
* Assert timestamp is STILL not null
*/
$this->assertNotNull( $results['data']['post']['dateGmt'] );
}
}

View File

@@ -0,0 +1,279 @@
<?php
class PostObjectNestedMutationsTest extends \Codeception\TestCase\WPTestCase {
public $title;
public $content;
public $client_mutation_id;
public $admin;
public $subscriber;
public $author;
public function setUp() {
// before
parent::setUp();
$this->title = 'some title';
$this->content = 'some content';
$this->client_mutation_id = 'someUniqueId';
$this->author = $this->factory()->user->create( [
'role' => 'author',
] );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
$this->subscriber = $this->factory()->user->create( [
'role' => 'subscriber',
] );
}
public function tearDown() {
parent::tearDown();
}
public function createPostMutation( $args = [] ) {
$mutation = '
mutation CreatePostWithTerms( $input: CreatePostInput! ) {
createPost( input: $input ) {
post {
id
postId
title
tags {
edges {
node {
id
tagId
name
description
slug
}
}
}
categories {
edges {
node {
id
categoryId
name
description
slug
}
}
}
}
}
}
';
$default = [
'clientMutationId' => uniqid(),
'title' => 'Test Title',
'status' => 'PUBLISH',
];
$input = array_merge( $default, $args );
$variables = [
'input' => $input,
];
$response = do_graphql_request( $mutation, 'CreatePostWithTerms', $variables );
return $response;
}
public function testCreatePostAndAttachCategories() {
$tag_slug = uniqid();
$tag = wp_insert_term( $tag_slug, 'post_tag' );
$expected_tag_id = \GraphQLRelay\Relay::toGlobalId( 'post_tag', absint( $tag['term_id'] ) );
$category_slug = uniqid();
$category = wp_insert_term( $category_slug, 'category' );
$expected_category_id = \GraphQLRelay\Relay::toGlobalId( 'category', absint( $category['term_id'] ) );
wp_set_current_user( $this->admin );
$results = $this->createPostMutation([
'tags' => [
'append' => false,
'nodes' => [
[
'slug' => $tag_slug
],
]
],
'categories' => [
'append' => false,
'nodes' => [
[
'slug' => $category_slug
],
]
]
]);
$this->assertArrayNotHasKey( 'errors', $results );
$createdPost = $results['data']['createPost']['post'];
$this->assertEquals( 'Test Title', $createdPost['title'] );
$this->assertEquals( $expected_tag_id, $createdPost['tags']['edges'][0]['node']['id'] );
$this->assertEquals( $expected_category_id, $createdPost['categories']['edges'][0]['node']['id'] );
}
public function testCreatePostAndAttachTagByID() {
wp_set_current_user( $this->admin );
$new_term = $this->factory->term->create([
'name' => 'Test Term',
'taxonomy' => 'post_tag'
]);
$new_term_global_id = \GraphQLRelay\Relay::toGlobalId( 'post_tag', $new_term );
$results = $this->createPostMutation([
'tags' => [
'append' => false,
'nodes' => [
[
'id' => $new_term_global_id
],
]
],
]);
$this->assertArrayNotHasKey( 'errors', $results );
$createdPost = $results['data']['createPost']['post'];
$this->assertEquals( 'Test Title', $createdPost['title'] );
$this->assertEquals( $new_term, $createdPost['tags']['edges'][0]['node']['tagId'] );
$this->assertEquals( $new_term_global_id, $createdPost['tags']['edges'][0]['node']['id'] );
}
public function testCreatePostAndAttachTagByTagID() {
wp_set_current_user( $this->admin );
$new_term = $this->factory->term->create([
'name' => 'Test Term',
'taxonomy' => 'post_tag'
]);
$new_term_global_id = \GraphQLRelay\Relay::toGlobalId( 'post_tag', $new_term );
$results = $this->createPostMutation([
'tags' => [
'append' => false,
'nodes' => [
[
'id' => (int) $new_term
],
]
],
]);
$this->assertArrayNotHasKey( 'errors', $results );
$createdPost = $results['data']['createPost']['post'];
$this->assertEquals( 'Test Title', $createdPost['title'] );
$this->assertEquals( $new_term, $createdPost['tags']['edges'][0]['node']['tagId'] );
$this->assertEquals( $new_term_global_id, $createdPost['tags']['edges'][0]['node']['id'] );
}
public function testCreatePostWithInvalidTagId() {
wp_set_current_user( $this->admin );
$new_term = $this->factory->term->create([
'name' => 'Test Term',
'taxonomy' => 'category'
]);
$new_term_global_id = \GraphQLRelay\Relay::toGlobalId( 'category', $new_term );
$results = $this->createPostMutation([
'tags' => [
'append' => false,
'nodes' => [
[
'id' => $new_term_global_id
],
],
],
]);
$this->assertArrayNotHasKey( 'errors', $results );
$createdPost = $results['data']['createPost']['post'];
$this->assertEquals( 'Test Title', $createdPost['title'] );
/**
* The tags edges _should_ be empty because we tried to add a tag
* with an invalid id.
*/
$this->assertEmpty( $createdPost['tags']['edges'] );
}
public function testCreatePostAndCreateTerms() {
wp_set_current_user( $this->admin );
$results = $this->createPostMutation([
'tags' => [
'append' => false,
'nodes' => [
[
'name' => 'Test Tag',
'slug' => 'test-tag',
'description' => 'Test Tag Description',
],
],
],
'categories' => [
'append' => false,
'nodes' => [
[
'slug' => 'test-category',
'description' => 'Test Category Description',
],
],
],
]);
$this->assertArrayNotHasKey( 'errors', $results );
$createdPost = $results['data']['createPost']['post'];
$this->assertEquals( 'Test Title', $createdPost['title'] );
/**
* The tags edges _should_ be empty because we tried to add a tag
* with an invalid id.
*/
$this->assertEquals( 'Test Tag Description', $createdPost['tags']['edges'][0]['node']['description'] );
$this->assertEquals( 'Test Category Description', $createdPost['categories']['edges'][0]['node']['description'] );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,378 @@
<?php
class PostTypeObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $admin;
public function setUp() {
// before
parent::setUp();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* testPostTypeQueryForPosts
*
* This tests post type info for posts post type.
*
* @since 0.0.5
*/
public function testPostTypeQueryForPosts() {
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'postType', 'post' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
posts {
postTypeInfo {
canExport
connectedTaxonomies {
name
}
connectedTaxonomyNames
deleteWithUser
description
excludeFromSearch
graphqlPluralName
graphqlSingleName
hasArchive
hierarchical
id
label
labels {
name
singularName
addNew
addNewItem
editItem
newItem
viewItem
viewItems
searchItems
notFound
notFoundInTrash
parentItemColon
allItems
archives
attributes
insertIntoItem
uploadedToThisItem
featuredImage
setFeaturedImage
removeFeaturedImage
useFeaturedImage
menuName
filterItemsList
itemsListNavigation
itemsList
}
menuIcon
menuPosition
name
public
publiclyQueryable
restBase
restControllerClass
showInAdminBar
showInGraphql
showInMenu
showInNavMenus
showInRest
showUi
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'posts' => [
'postTypeInfo' => [
'canExport' => true,
'connectedTaxonomies' => [
[
'name' => 'category'
],
[
'name' => 'post_tag'
],
],
'connectedTaxonomyNames' => [ 'category', 'post_tag' ],
'deleteWithUser' => true,
'description' => '',
'excludeFromSearch' => false,
'graphqlPluralName' => 'posts',
'graphqlSingleName' => 'post',
'hasArchive' => false,
'hierarchical' => false,
'id' => $global_id,
'label' => 'Posts',
'labels' => [
'name' => 'Posts',
'singularName' => 'Post',
'addNew' => 'Add New',
'addNewItem' => 'Add New Post',
'editItem' => 'Edit Post',
'newItem' => 'New Post',
'viewItem' => 'View Post',
'viewItems' => 'View Posts',
'searchItems' => 'Search Posts',
'notFound' => 'No posts found.',
'notFoundInTrash' => 'No posts found in Trash.',
'parentItemColon' => null,
'allItems' => 'All Posts',
'archives' => 'Post Archives',
'attributes' => 'Post Attributes',
'insertIntoItem' => 'Insert into post',
'uploadedToThisItem' => 'Uploaded to this post',
'featuredImage' => 'Featured Image',
'setFeaturedImage' => 'Set featured image',
'removeFeaturedImage' => 'Remove featured image',
'useFeaturedImage' => null,
'menuName' => 'Posts',
'filterItemsList' => 'Filter posts list',
'itemsListNavigation' => 'Posts list navigation',
'itemsList' => 'Posts list',
],
'menuIcon' => null,
'menuPosition' => 5,
'name' => 'post',
'public' => true,
'publiclyQueryable' => true,
'restBase' => 'posts',
'restControllerClass' => 'WP_REST_Posts_Controller',
'showInAdminBar' => false,
'showInGraphql' => true,
'showInMenu' => true,
'showInNavMenus' => true,
'showInRest' => true,
'showUi' => true,
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testPostTypeQueryForPages
*
* This tests post type info for pages post type.
*
* @since 0.0.5
*/
public function testPostTypeQueryForPages() {
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'postType', 'page' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
pages {
postTypeInfo {
canExport
connectedTaxonomies {
name
}
connectedTaxonomyNames
deleteWithUser
description
excludeFromSearch
graphqlPluralName
graphqlSingleName
hasArchive
hierarchical
id
label
menuIcon
menuPosition
name
public
publiclyQueryable
restBase
restControllerClass
showInAdminBar
showInGraphql
showInMenu
showInNavMenus
showInRest
showUi
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'pages' => [
'postTypeInfo' => [
'canExport' => true,
'connectedTaxonomies' => null,
'connectedTaxonomyNames' => null,
'deleteWithUser' => true,
'description' => '',
'excludeFromSearch' => false,
'graphqlPluralName' => 'pages',
'graphqlSingleName' => 'page',
'hasArchive' => false,
'hierarchical' => true,
'id' => $global_id,
'label' => 'Pages',
'menuIcon' => null,
'menuPosition' => 20,
'name' => 'page',
'public' => true,
'publiclyQueryable' => false,
'restBase' => 'pages',
'restControllerClass' => 'WP_REST_Posts_Controller',
'showInAdminBar' => false,
'showInGraphql' => true,
'showInMenu' => true,
'showInNavMenus' => true,
'showInRest' => true,
'showUi' => true,
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testPostTypeQueryForMedia
*
* This tests post type info for attachment post type.
*
* @since 0.0.5
*/
public function testPostTypeQueryForMedia() {
/**
* Create the global ID based on the post_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'postType', 'attachment' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
mediaItems {
postTypeInfo {
canExport
connectedTaxonomies {
name
}
connectedTaxonomyNames
deleteWithUser
description
excludeFromSearch
graphqlPluralName
graphqlSingleName
hasArchive
hierarchical
id
label
menuIcon
menuPosition
name
public
publiclyQueryable
restBase
restControllerClass
showInAdminBar
showInGraphql
showInMenu
showInNavMenus
showInRest
showUi
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'mediaItems' => [
'postTypeInfo' => [
'canExport' => true,
'connectedTaxonomies' => null,
'connectedTaxonomyNames' => null,
'deleteWithUser' => true,
'description' => '',
'excludeFromSearch' => false,
'graphqlPluralName' => 'mediaItems',
'graphqlSingleName' => 'mediaItem',
'hasArchive' => false,
'hierarchical' => false,
'id' => $global_id,
'label' => 'Media',
'menuIcon' => null,
'menuPosition' => null,
'name' => 'attachment',
'public' => true,
'publiclyQueryable' => true,
'restBase' => 'media',
'restControllerClass' => 'WP_REST_Attachments_Controller',
'showInAdminBar' => false,
'showInGraphql' => true,
'showInMenu' => true,
'showInNavMenus' => null,
'showInRest' => true,
'showUi' => true,
],
],
],
];
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,8 @@
# WPUnit Tests
These are tests utilizing the WP_UnitTestCase. They're really integration tests more than "unit" tests, as they
test functionality of any particular piece of code in context of running with
WordPress core (and potentially other plugins or theme code).
There are helper functions/factories for creating dummy data and making assertions against that data, etc.
These tests help ensure that WPGraphQL works with WordPress as it should.

View File

@@ -0,0 +1,146 @@
<?php
class RelayMutationSchemaTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
// before
parent::setUp();
// your set up methods here
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* This tests to make sure the mutation schema follows the Relay spec
*
* @see: https://facebook.github.io/relay/graphql/mutations.htm#sec-Introspection
*/
public function testRelayMutationSchema() {
$introspection_query = '
{
__schema {
mutationType {
fields {
type {
kind
fields {
name
type {
kind
ofType {
name
kind
}
}
}
}
args {
name
type {
kind
ofType {
kind
inputFields {
name
type {
kind
ofType {
name
kind
}
}
}
}
}
}
}
}
}
}
';
/**
* Run the introspection query
*/
$actual = do_graphql_request( $introspection_query );
/**
* Get the mutationType fields out of the response tree
*/
$mutation_type_fields = ! empty( $actual['data']['__schema']['mutationType']['fields'] ) ? $actual['data']['__schema']['mutationType']['fields'] : null;
/**
* Verify that the $mutation_type_fields is not empty
*/
$this->assertNotEmpty( $mutation_type_fields );
/**
* If the fields are a populated array
*/
if ( ! empty( $mutation_type_fields ) && is_array( $mutation_type_fields ) ) {
/**
* Loop through the fields to ensure they have fields of their own
*/
foreach ( $mutation_type_fields as $mutation_type_field ) {
$type = ! empty( $mutation_type_field['type'] ) ? $mutation_type_field['type'] : null;
/**
* All mutations should declare a Type
*/
$this->assertNotEmpty( $type );
/**
* All types should have a "kind"
*/
$this->assertArrayHasKey( 'kind', $type );
/**
* All rootMutations should be Object types
*/
$this->assertEquals( $type['kind'], 'OBJECT' );
/**
* All rootMutations should have fields
*/
$this->assertNotEmpty( $type['fields'] );
/**
* All rootMutations should have a clientMutationId field
*/
$this->assertTrue( $this->checkIfClientMutationIdExists( $type['fields'] ) );
}
}
}
/**
* This is a helper that searches an array to see if any nested items contain the "name" attribute
* with a value of "clientMutationId"
*
* @param $array
*
* @return bool
*/
public function checkIfClientMutationIdExists( $array ) {
$this->assertNotEmpty( $array );
foreach ( $array as $item ) {
if ( 'clientMutationId' === $item['name'] ) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,285 @@
<?php
class RouterTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
// before
parent::setUp();
// your set up methods here
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
public function testRouteEndpoint() {
/**
* Test that the default route is set to "graphql"
*/
$this->assertEquals( 'graphql', apply_filters( 'graphql_endpoint', \WPGraphQL\Router::$route ) );
}
/**
* Test to make sure that the rewrite rules properly include the graphql route
*/
public function testGraphQLRewriteRule() {
global $wp_rewrite;
$route = apply_filters( 'graphql_endpoint', \WPGraphQL\Router::$route );
$this->assertArrayHasKey( $route . '/?$', $wp_rewrite->extra_rules_top );
}
public function testAddQueryVar() {
$query_vars = [];
$actual = \WPGraphQL\Router::add_query_var( $query_vars );
$this->assertEquals( $actual, [ apply_filters( 'graphql_endpoint', \WPGraphQL\Router::$route ) ] );
}
public function testGetRawData() {
$router = new \WPGraphQL\Router();
global $HTTP_RAW_POST_DATA;
$actual = $router->get_raw_data();
$this->assertEquals( $actual, $HTTP_RAW_POST_DATA );
}
public function testGetRawDataEmptyGlobal() {
$router = new \WPGraphQL\Router();
global $HTTP_RAW_POST_DATA;
$HTTP_RAW_POST_DATA = null;
$actual = $router->get_raw_data();
$this->assertEquals( $actual, $HTTP_RAW_POST_DATA );
}
/**
* Test the "send_header" method in the Router class
*
* @see: https://github.com/sebastianbergmann/phpunit/issues/720
* @runInSeparateProcess
*/
// public function testSendHeader() {
// $router = new \WPGraphQL\Router();
// $router::send_header( 'some_key', 'some_value' );
// if ( function_exists( 'xdebug_get_headers' ) ) {
// $this->assertContains( 'some_key: some_value', xdebug_get_headers() );
// }
// }
//
// public function testAddRewriteRule() {
//
// global $wp_rewrite;
// \WPGraphQL\Router::add_rewrite_rule();
// flush_rewrite_rules();
//
// $this->assertContains( 'index.php?' . \WPGraphQL\Router::$route . '=true', $wp_rewrite->extra_rules_top );
//
// }
/**
* @runInSeparateProcess
*/
// public function testSetHeadersNoCache() {
//
// $router = new \WPGraphQL\Router();
// $router::set_headers( '200' );
//
// $headers = xdebug_get_headers();
//
// $this->assertContains( 'Access-Control-Allow-Origin: *', $headers );
// $this->assertContains( 'Content-Type: application/json ; charset=' . get_option( 'blog_charset' ), $headers );
// $this->assertContains( 'X-Robots-Tag: noindex', $headers );
// $this->assertContains( 'X-Content-Type-Options: nosniff', $headers );
// $this->assertContains( 'Access-Control-Allow-Headers: Authorization, Content-Type', $headers );
// $this->assertContains( 'X-hacker: If you\'re reading this, you should visit github.com/wp-graphql and contribute!', $headers );
//
// }
/**
* @runInSeparateProcess
*/
// public function testSetHeadersWithCache() {
//
// add_filter( 'graphql_send_nocache_headers', function() {
// return true;
// } );
//
// $router = new \WPGraphQL\Router();
// $router::set_headers( '200' );
// $headers = xdebug_get_headers();
// $this->assertContains( 'Cache-Control: no-cache, must-revalidate, max-age=0', $headers );
//
// }
/**
* This tests the WPGraphQL Router resolving HTTP requests.
*/
// public function testResolveRequest() {
//
// /**
// * Create a test a query
// */
// $this->factory->post->create( [
// 'post_title' => 'test',
// 'post_status' => 'publish',
// ] );
//
// /**
// * Filter the request data
// */
// add_filter( 'graphql_request_data', function( $data ) {
// $data['query'] = 'query getPosts($first:Int){ posts(first:$first){ edges{ node{ id } } } }';
// $data['variables'] = [ 'first' => 1 ];
// $data['operationName'] = 'getPosts';
//
// return $data;
// } );
//
// /**
// * Set the query var to "graphql" so we can mock like we're visiting the endpoint via
// */
// set_query_var( 'graphql', true );
// $GLOBALS['wp']->query_vars['graphql'] = true;
//
// /**
// * Instantiate the router
// */
// $router = new \WPGraphQL\Router();
//
// /**
// * Process the request using our filtered data
// */
// $router::resolve_http_request();
//
// /**
// * Make sure the constant gets defined when it's a GraphQL Request
// */
// $this->assertTrue( defined( 'GRAPHQL_HTTP_REQUEST' ) );
// $this->assertEquals( true, GRAPHQL_HTTP_REQUEST );
//
// /**
// * Make sure the actions we expect to be firing are firing
// */
// $this->assertNotFalse( did_action( 'graphql_process_http_request' ) );
// $this->assertNotFalse( did_action( 'graphql_process_http_request_response' ) );
//
// }
//
// public function testResolveHttpRequestWithJsonVariables() {
//
// /**
// * Create a test a query
// */
// $this->factory->post->create( [
// 'post_title' => 'test',
// 'post_status' => 'publish',
// ] );
//
// /**
// * Filter the request data
// */
// add_filter( 'graphql_request_data', function( $data ) {
// $data['query'] = 'query getPosts($first:Int){ posts(first:$first){ edges{ node{ id } } } }';
// $data['variables'] = wp_json_encode( [ 'first' => 1 ] );
// $data['operationName'] = 'getPosts';
//
// return $data;
// } );
//
// /**
// * Set the query var to "graphql" so we can mock like we're visiting the endpoint via
// */
// set_query_var( 'graphql', true );
// $GLOBALS['wp']->query_vars['graphql'] = true;
//
// /**
// * Instantiate the router
// */
// $router = new \WPGraphQL\Router();
//
// /**
// * Process the request using our filtered data
// */
// $router::resolve_http_request();
//
// /**
// * Make sure the constant gets defined when it's a GraphQL Request
// */
// $this->assertTrue( defined( 'GRAPHQL_HTTP_REQUEST' ) );
// $this->assertEquals( true, GRAPHQL_HTTP_REQUEST );
//
// /**
// * Make sure the actions we expect to be firing are firing
// */
// $this->assertNotFalse( did_action( 'graphql_process_http_request' ) );
// $this->assertNotFalse( did_action( 'graphql_process_http_request_response' ) );
//
// }
//
// /**
// * This tests the resolve_http_request method for a route that's not the
// * /graphql endpoint to make sure that graphql isn't improperly initiated
// * when it's not supposed to be.
// */
// public function testResolveHttpRequestWrongQueryVars() {
//
// set_query_var( 'graphql', false );
// $GLOBALS['wp']->query_vars['graphql'] = false;
//
// /**
// * Instantiate the router
// */
// $router = new \WPGraphQL\Router();
//
// /**
// * Process the request using our filtered data
// */
// $this->assertNull( $router::resolve_http_request() );
//
// }
//
// public function testResolveHttpRequestWithEmptyQuery() {
//
// /**
// * Filter the request data
// */
// add_filter( 'graphql_request_data', function( $data ) {
// $data['query'] = null;
// $data['variables'] = null;
// $data['operationName'] = null;
//
// return $data;
// } );
//
// /**
// * Set the query var to "graphql" so we can mock like we're visiting the endpoint via
// */
// set_query_var( 'graphql', true );
// $GLOBALS['wp']->query_vars['graphql'] = true;
//
// /**
// * Instantiate the router
// */
// $router = new \WPGraphQL\Router();
//
// /**
// * Process the request using our filtered data
// */
// $router::resolve_http_request();
//
// /**
// * Make sure the constant gets defined when it's a GraphQL Request
// */
// $this->assertTrue( defined( 'GRAPHQL_HTTP_REQUEST' ) );
// $this->assertEquals( true, GRAPHQL_HTTP_REQUEST );
//
// /**
// * Make sure the actions we expect to be firing are firing
// */
// $this->assertNotFalse( did_action( 'graphql_process_http_request' ) );
// $this->assertNotFalse( did_action( 'graphql_process_http_request_response' ) );
//
// }
}

View File

@@ -0,0 +1,325 @@
<?php
class SettingQueriesTest extends \Codeception\TestCase\WPTestCase {
public $admin;
public $editor;
public function setUp() {
// before
parent::setUp();
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
$this->editor = $this->factory->user->create( [
'role' => 'editor',
] );
}
public function tearDown() {
parent::tearDown();
}
/**
* Method for testing whether a user can query settings
* if they don't have the 'manage_options' capability
*
* @access public
* @return void
*/
public function testSettingQueryAsEditor() {
/**
* Set the editor user
* Set the query
* Make the request
* Validate the request has errors
*/
wp_set_current_user( $this->editor );
$query = "
query {
generalSettings {
email
}
}
";
$actual = do_graphql_request( $query );
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* Method for testing the generalSettings
*
* @access public
* @return void
*/
public function testGeneralSettingQuery() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
$mock_options = [
'date_format' => 'test date format',
'blogdescription' => 'test description',
'admin_email' => 'test@test.com',
'language' => 'test language',
'start_of_week' => 0,
'time_format' => 'test_time_format',
'timezone_string' => 'UTC',
'blogname' => 'test_title',
'siteurl' => 'http://test.com'
];
foreach ( $mock_options as $mock_option_key => $mock_value ) {
update_option( $mock_option_key, $mock_value );
}
if ( is_multisite() ) {
update_network_option( 1, 'admin_email', 'test email' );
}
if ( true === is_multisite() ) {
$query = "
query {
generalSettings {
dateFormat
description
language
startOfWeek
timeFormat
timezone
title
}
}
";
} else {
$query = "
query {
generalSettings {
dateFormat
description
email
language
startOfWeek
timeFormat
timezone
title
url
}
}
";
}
$actual = do_graphql_request( $query );
$generalSettings = $actual['data']['generalSettings'];
$this->assertNotEmpty( $generalSettings );
$this->assertEquals( $mock_options['date_format'], $generalSettings['dateFormat'] );
$this->assertEquals( $mock_options['blogdescription'], $generalSettings['description'] );
if ( ! is_multisite() ) {
$this->assertEquals( $mock_options['admin_email'], $generalSettings['email'] );
}
$this->assertEquals( $mock_options['start_of_week'], $generalSettings['startOfWeek'] );
$this->assertEquals( $mock_options['time_format'], $generalSettings['timeFormat'] );
$this->assertEquals( $mock_options['timezone_string'], $generalSettings['timezone'] );
$this->assertEquals( $mock_options['blogname'], $generalSettings['title'] );
if ( ! is_multisite() ) {
$this->assertEquals( $mock_options['siteurl'], $generalSettings['url'] );
}
}
/**
* Method for testing the writingSettings
*
* @access public
* @return void
*/
public function testWritingSettingQuery() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
$query = "
query {
writingSettings {
defaultCategory
defaultPostFormat
useSmilies
}
}
";
$actual = do_graphql_request( $query );
$writingSettings = $actual['data']['writingSettings'];
$this->assertNotEmpty( $writingSettings );
$this->assertTrue( is_int( $writingSettings['defaultCategory'] ) );
$this->assertTrue( is_string( $writingSettings['defaultPostFormat'] ) );
$this->assertTrue( is_bool( $writingSettings['useSmilies'] ) );
}
/**
* Method for testing the readingSettings
*
* @access public
* @return array $actual
*/
public function testReadingSettingQuery() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
update_option( 'posts_per_page', 12 );
$query = "
query {
readingSettings {
postsPerPage
}
}
";
$actual = do_graphql_request( $query );
$readingSettings = $actual['data']['readingSettings'];
$this->assertNotEmpty( $readingSettings );
$this->assertEquals( 12, $readingSettings['postsPerPage'] );
}
/**
* Method for testing the discussionSettings
*
* @access public
* @return array $actual
*/
public function testDiscussionSettingQuery() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
update_option( 'default_comment_status', 'test_value' );
update_option( 'default_ping_status', 'test_value' );
$query = "
query {
discussionSettings {
defaultCommentStatus
defaultPingStatus
}
}
";
$actual = do_graphql_request( $query );
$discussionSettings = $actual['data']['discussionSettings'];
$this->assertNotEmpty( $discussionSettings );
$this->assertEquals( 'test_value', $discussionSettings['defaultCommentStatus'] );
$this->assertEquals( 'test_value', $discussionSettings['defaultPingStatus'] );
}
/**
* Method for testing the testGetAllowedSettingsByGroup
* and then checking that zoolSettings gets added and removed
*
* @access public
* @return void
*/
public function testGetAllowedSettingsByGroup() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
/**
* Manually Register a setting for testing
*
* This registers a setting as a number to see if it gets the correct type
* associated with it and returned through WPGraphQL
*/
register_setting( 'zool', 'points', array(
'type' => 'number',
'description' => __( 'Test how many points we have in Zool.' ),
'show_in_graphql' => true,
'default' => 4.5,
) );
$actual = \WPGraphQL\Data\DataSource::get_allowed_settings_by_group();
$this->assertArrayHasKey( 'zool', $actual );
unregister_setting( 'zool', 'points' );
$actual = \WPGraphQL\Data\DataSource::get_allowed_settings_by_group();
$this->assertArrayNotHasKey( 'zool', $actual );
}
/**
* Method for testing the testGetAllowedSettings
* and then checking that zoolSettings gets added and removed
*
* @access public
* @return void
*/
public function testGetAllowedSettings() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
/**
* Manually Register a setting for testing
*
* This registers a setting as a number to see if it gets the correct type
* associated with it and returned through WPGraphQL
*/
register_setting( 'zool', 'points', array(
'type' => 'number',
'description' => __( 'Test how many points we have in Zool.' ),
'show_in_graphql' => true,
'default' => 4.5,
) );
$actual = \WPGraphQL\Data\DataSource::get_allowed_settings();
$this->assertArrayHasKey( 'points', $actual );
unregister_setting( 'zool', 'points' );
$actual = \WPGraphQL\Data\DataSource::get_allowed_settings();
$this->assertArrayNotHasKey( 'points', $actual );
}
}

View File

@@ -0,0 +1,440 @@
<?php
class WP_GraphQL_Test_Settings_Mutations extends \Codeception\TestCase\WPTestCase {
public $clientMutationId;
public $defaultCategory;
public $discussionSettingsDefaultCommentStatus;
public $discussionSettingsDefaultPingStatus;
public $generalSettingsDateFormat;
public $generalSettingsDescription;
public $generalSettingsEmail;
public $generalSettingsLanguage;
public $generalSettingsStartOfWeek;
public $generalSettingsTimeFormat;
public $generalSettingsTitle;
public $readingSettingsPostsPerPage;
public $writingSettingsDefaultCategory;
public $writingSettingsUseSmilies;
public $writingSettingsDefaultPostFormat;
public $update_variables;
public $subscriber;
public $subscriber_name;
public $author;
public $author_name;
public $admin;
public $admin_name;
public function setUp() {
$this->subscriber = $this->factory->user->create( [
'role' => 'subscriber',
] );
$this->subscriber_name = 'User ' . $this->subscriber;
$this->author = $this->factory->user->create( [
'role' => 'author',
] );
$this->author_name = 'User ' . $this->author;
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
$this->admin_name = 'User ' . $this->admin;
/**
* Set up the updateSettings variables
*/
$this->clientMutationId = 'testMutationId';
$this->discussionSettingsDefaultCommentStatus = 'closed';
$this->discussionSettingsDefaultPingStatus = 'closed';
$this->generalSettingsDateFormat = 'Y-m-d';
$this->generalSettingsDescription = 'Local Testing Site';
$this->generalSettingsEmail = 'hdevore@medianewsgroup.com';
$this->generalSettingsLanguage = 'en_US';
$this->generalSettingsStartOfWeek = 2;
$this->generalSettingsTimeFormat = 'g:i:s a';
$this->generalSettingsTimezone = 'America/Denver';
$this->generalSettingsTitle = 'WPGraphQL Site Title';
$this->readingSettingsPostsPerPage = 20;
$this->writingSettingsDefaultCategory = $this->factory()->category->create();
$this->writingSettingsDefaultPostFormat = 'quote';
$this->writingSettingsUseSmilies = false;
/**
* Set the createMediaItem mutation input variables
*/
if ( is_multisite() ) {
$this->update_variables = [
'input' => [
'clientMutationId' => $this->clientMutationId,
'discussionSettingsDefaultCommentStatus' => $this->discussionSettingsDefaultCommentStatus,
'discussionSettingsDefaultPingStatus' => $this->discussionSettingsDefaultPingStatus,
'generalSettingsDateFormat' => $this->generalSettingsDateFormat,
'generalSettingsDescription' => $this->generalSettingsDescription,
'generalSettingsLanguage' => $this->generalSettingsLanguage,
'generalSettingsStartOfWeek' => $this->generalSettingsStartOfWeek,
'generalSettingsTimeFormat' => $this->generalSettingsTimeFormat,
'generalSettingsTimezone' => $this->generalSettingsTimezone,
'generalSettingsTitle' => $this->generalSettingsTitle,
'readingSettingsPostsPerPage' => $this->readingSettingsPostsPerPage,
'writingSettingsDefaultCategory' => $this->writingSettingsDefaultCategory,
'writingSettingsDefaultPostFormat' => $this->writingSettingsDefaultPostFormat,
'writingSettingsUseSmilies' => $this->writingSettingsUseSmilies,
],
];
} else {
$this->update_variables = [
'input' => [
'clientMutationId' => $this->clientMutationId,
'discussionSettingsDefaultCommentStatus' => $this->discussionSettingsDefaultCommentStatus,
'discussionSettingsDefaultPingStatus' => $this->discussionSettingsDefaultPingStatus,
'generalSettingsDateFormat' => $this->generalSettingsDateFormat,
'generalSettingsDescription' => $this->generalSettingsDescription,
'generalSettingsEmail' => $this->generalSettingsEmail,
'generalSettingsLanguage' => $this->generalSettingsLanguage,
'generalSettingsStartOfWeek' => $this->generalSettingsStartOfWeek,
'generalSettingsTimeFormat' => $this->generalSettingsTimeFormat,
'generalSettingsTimezone' => $this->generalSettingsTimezone,
'generalSettingsTitle' => $this->generalSettingsTitle,
'readingSettingsPostsPerPage' => $this->readingSettingsPostsPerPage,
'writingSettingsDefaultCategory' => $this->writingSettingsDefaultCategory,
'writingSettingsDefaultPostFormat' => $this->writingSettingsDefaultPostFormat,
'writingSettingsUseSmilies' => $this->writingSettingsUseSmilies,
],
];
}
/**
* Manually Register a setting for testing
*
* This registers a setting as a number to see if it gets the correct type
* associated with it and returned through WPGraphQL
*/
register_setting( 'Zool', 'points', array(
'type' => 'number',
'description' => __( 'Test how many points we have in Zool.' ),
'show_in_graphql' => true,
'default' => 4.5,
) );
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
/**
* This function tests the updateSettings mutation
* and is reused throughout the updateSettings tests
*
* @access public
* @return array $actual
*/
public function updateSettingsMutation() {
/**
* Prepare the updateSettings mutation
*/
if ( is_multisite() ) {
$mutation = '
mutation updateSettings( $input: UpdateSettingsInput! ){
updateSettings( input: $input ) {
clientMutationId
allSettings {
discussionSettingsDefaultCommentStatus
discussionSettingsDefaultPingStatus
generalSettingsDateFormat
generalSettingsDescription
generalSettingsLanguage
generalSettingsStartOfWeek
generalSettingsTimeFormat
generalSettingsTimezone
generalSettingsTitle
readingSettingsPostsPerPage
writingSettingsDefaultCategory
writingSettingsDefaultPostFormat
writingSettingsUseSmilies
}
discussionSettings {
defaultCommentStatus
defaultPingStatus
}
generalSettings {
dateFormat
description
language
startOfWeek
timeFormat
timezone
title
}
readingSettings {
postsPerPage
}
writingSettings {
defaultCategory
defaultPostFormat
useSmilies
}
}
}
';
} else {
$mutation = '
mutation updateSettings( $input: UpdateSettingsInput! ){
updateSettings( input: $input ) {
clientMutationId
allSettings {
discussionSettingsDefaultCommentStatus
discussionSettingsDefaultPingStatus
generalSettingsDateFormat
generalSettingsDescription
generalSettingsEmail
generalSettingsLanguage
generalSettingsStartOfWeek
generalSettingsTimeFormat
generalSettingsTimezone
generalSettingsTitle
generalSettingsUrl
readingSettingsPostsPerPage
writingSettingsDefaultCategory
writingSettingsDefaultPostFormat
writingSettingsUseSmilies
}
discussionSettings {
defaultCommentStatus
defaultPingStatus
}
generalSettings {
dateFormat
description
email
language
startOfWeek
timeFormat
timezone
title
url
}
readingSettings {
postsPerPage
}
writingSettings {
defaultCategory
defaultPostFormat
useSmilies
}
}
}
';
}
$actual = do_graphql_request( $mutation, 'updateSettings', $this->update_variables );
return $actual;
}
/**
* This function tests whether a user can update settings if they don't have the right credentials
*
* @source wp-content/plugins/wp-graphql/src/Type/Settings/Mutation/SettingsUpdate.php:51
* @access public
* @return void
*/
public function testUpdateSettingsAsAuthor() {
/**
* Set the current user as the author role so we
* receive an auth error back
*/
wp_set_current_user( $this->author );
$actual = $this->updateSettingsMutation();
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* Method for testing whether a user can query settings
* if they don't have the 'manage_options' capability
*
* They should not be able to query for the admin email
* so we should receive an error back
*
* @access public
* @return void
*/
public function testSettingsQueryAsEditor() {
/**
* Set the editor user
* Set the query
* Make the request
* Validate the request has errors
*/
wp_set_current_user( $this->editor );
$query = "
query {
allSettings {
generalSettingsEmail
}
}
";
$actual = do_graphql_request( $query );
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* This function tests whether we receive an error or success
* when trying to update the site's URL
*
* @source wp-content/plugins/wp-graphql/src/Type/Settings/Mutation/SettingsUpdate.php:63
* @access public
* @return void
*/
public function testUpdateSettingsSiteURLMutation() {
/**
* Set the current user as the admin role so we
* successfully run the mutation
*/
wp_set_current_user( $this->admin );
$this->update_variables['input']['generalSettingsUrl'] = 'http://exampleTEST.org';
$actual = $this->updateSettingsMutation();
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* This function tests the updateSettings mutation
*
* @source wp-content/plugins/wp-graphql/src/Type/Settings/Mutation/SettingsUpdate.php
* @access public
* @return void
*/
public function testUpdateSettingsMutation() {
/**
* Set the current user as the admin role so we
* successfully run the mutation
*/
wp_set_current_user( $this->admin );
$actual = $this->updateSettingsMutation();
/**
* Define the expected output.
*/
if ( is_multisite() ) {
$expected = [
'data' => [
'updateSettings' => [
'clientMutationId' => $this->clientMutationId,
'allSettings' => [
'discussionSettingsDefaultCommentStatus' => $this->discussionSettingsDefaultCommentStatus,
'discussionSettingsDefaultPingStatus' => $this->discussionSettingsDefaultPingStatus,
'generalSettingsDateFormat' => $this->generalSettingsDateFormat,
'generalSettingsDescription' => $this->generalSettingsDescription,
'generalSettingsLanguage' => $this->generalSettingsLanguage,
'generalSettingsStartOfWeek' => $this->generalSettingsStartOfWeek,
'generalSettingsTimeFormat' => $this->generalSettingsTimeFormat,
'generalSettingsTimezone' => $this->generalSettingsTimezone,
'generalSettingsTitle' => $this->generalSettingsTitle,
'readingSettingsPostsPerPage' => $this->readingSettingsPostsPerPage,
'writingSettingsDefaultCategory' => $this->writingSettingsDefaultCategory,
'writingSettingsDefaultPostFormat' => $this->writingSettingsDefaultPostFormat,
'writingSettingsUseSmilies' => $this->writingSettingsUseSmilies,
],
'discussionSettings' => [
'defaultCommentStatus' => $this->discussionSettingsDefaultCommentStatus,
'defaultPingStatus' => $this->discussionSettingsDefaultPingStatus,
],
'generalSettings' => [
'dateFormat' => $this->generalSettingsDateFormat,
'description' => $this->generalSettingsDescription,
'language' => $this->generalSettingsLanguage,
'startOfWeek' => $this->generalSettingsStartOfWeek,
'timeFormat' => $this->generalSettingsTimeFormat,
'timezone' => $this->generalSettingsTimezone,
'title' => $this->generalSettingsTitle,
],
'readingSettings' => [
'postsPerPage' => $this->readingSettingsPostsPerPage,
],
'writingSettings' => [
'defaultCategory' => $this->writingSettingsDefaultCategory,
'defaultPostFormat' => $this->writingSettingsDefaultPostFormat,
'useSmilies' => $this->writingSettingsUseSmilies,
],
],
],
];
} else {
$expected = [
'data' => [
'updateSettings' => [
'clientMutationId' => $this->clientMutationId,
'allSettings' => [
'discussionSettingsDefaultCommentStatus' => $this->discussionSettingsDefaultCommentStatus,
'discussionSettingsDefaultPingStatus' => $this->discussionSettingsDefaultPingStatus,
'generalSettingsDateFormat' => $this->generalSettingsDateFormat,
'generalSettingsDescription' => $this->generalSettingsDescription,
'generalSettingsEmail' => $this->generalSettingsEmail,
'generalSettingsLanguage' => $this->generalSettingsLanguage,
'generalSettingsStartOfWeek' => $this->generalSettingsStartOfWeek,
'generalSettingsTimeFormat' => $this->generalSettingsTimeFormat,
'generalSettingsTimezone' => $this->generalSettingsTimezone,
'generalSettingsTitle' => $this->generalSettingsTitle,
'generalSettingsUrl' => 'http://wpgraphql.test',
'readingSettingsPostsPerPage' => $this->readingSettingsPostsPerPage,
'writingSettingsDefaultCategory' => $this->writingSettingsDefaultCategory,
'writingSettingsDefaultPostFormat' => $this->writingSettingsDefaultPostFormat,
'writingSettingsUseSmilies' => $this->writingSettingsUseSmilies,
],
'discussionSettings' => [
'defaultCommentStatus' => $this->discussionSettingsDefaultCommentStatus,
'defaultPingStatus' => $this->discussionSettingsDefaultPingStatus,
],
'generalSettings' => [
'dateFormat' => $this->generalSettingsDateFormat,
'description' => $this->generalSettingsDescription,
'email' => $this->generalSettingsEmail,
'language' => $this->generalSettingsLanguage,
'startOfWeek' => $this->generalSettingsStartOfWeek,
'timeFormat' => $this->generalSettingsTimeFormat,
'timezone' => $this->generalSettingsTimezone,
'title' => $this->generalSettingsTitle,
'url' => 'http://wpgraphql.test',
],
'readingSettings' => [
'postsPerPage' => $this->readingSettingsPostsPerPage,
],
'writingSettings' => [
'defaultCategory' => $this->writingSettingsDefaultCategory,
'defaultPostFormat' => $this->writingSettingsDefaultPostFormat,
'useSmilies' => $this->writingSettingsUseSmilies,
],
],
],
];
}
/**
* Compare the actual output vs the expected output
*/
$this->assertEquals( $actual, $expected );
}
}

View File

@@ -0,0 +1,175 @@
<?php
class WP_GraphQL_Test_Settings_Queries extends \Codeception\TestCase\WPTestCase {
public function setUp() {
/**
* Manually Register a setting for testing
*
* This registers a setting as a number to see if it gets the correct type
* associated with it and returned through WPGraphQL
*/
register_setting( 'Zool', 'points', array(
'type' => 'number',
'description' => __( 'Test how many points we have in Zool.' ),
'show_in_graphql' => true,
'default' => 4.5,
) );
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
$this->editor = $this->factory->user->create( [
'role' => 'editor',
] );
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
/**
* Method for testing whether a user can query settings
* if they don't have the 'manage_options' capability
*
* They should not be able to query for the admin email
* so we should receive an error back
*
* @access public
* @return void
*/
public function testAllSettingsQueryAsEditor() {
/**
* Set the editor user
* Set the query
* Make the request
* Validate the request has errors
*/
wp_set_current_user( $this->editor );
$query = "
query {
allSettings {
generalSettingsEmail
}
}
";
$actual = do_graphql_request( $query );
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* Method for testing the generalSettings
*
* @access public
* @return void
*/
public function testAllSettingsQuery() {
/**
* Set the admin user
* Set the query
* Make the request
* Validate the request
*/
wp_set_current_user( $this->admin );
$mock_options = [
'default_comment_status' => 'closed',
'default_ping_status' => 'closed',
'date_format' => 'test date format',
'blogdescription' => 'test description',
'admin_email' => 'test@test.com',
'start_of_week' => 0,
'time_format' => 'test_time_format',
'timezone_string' => 'UTC',
'blogname' => 'test_title',
'siteurl' => 'http://test.com',
'posts_per_page' => 20,
'default_category' => 2,
'default_post_format' => 'quote',
'use_smilies' => 0,
'points' => 5.5,
];
foreach ( $mock_options as $mock_option_key => $mock_value ) {
update_option( $mock_option_key, $mock_value );
}
if ( true === is_multisite() ) {
$query = "
query {
allSettings {
discussionSettingsDefaultCommentStatus
discussionSettingsDefaultPingStatus
generalSettingsDateFormat
generalSettingsDescription
generalSettingsLanguage
generalSettingsStartOfWeek
generalSettingsTimeFormat
generalSettingsTimezone
generalSettingsTitle
readingSettingsPostsPerPage
writingSettingsDefaultCategory
writingSettingsDefaultPostFormat
writingSettingsUseSmilies
}
}
";
} else {
$query = "
query {
allSettings {
discussionSettingsDefaultCommentStatus
discussionSettingsDefaultPingStatus
generalSettingsDateFormat
generalSettingsDescription
generalSettingsEmail
generalSettingsLanguage
generalSettingsStartOfWeek
generalSettingsTimeFormat
generalSettingsTimezone
generalSettingsTitle
generalSettingsUrl
readingSettingsPostsPerPage
writingSettingsDefaultCategory
writingSettingsDefaultPostFormat
writingSettingsUseSmilies
}
}
";
}
$actual = do_graphql_request( $query );
$allSettings = $actual['data']['allSettings'];
$this->assertNotEmpty( $allSettings );
$this->assertEquals( $mock_options['default_comment_status'], $allSettings['discussionSettingsDefaultCommentStatus'] );
$this->assertEquals( $mock_options['default_ping_status'], $allSettings['discussionSettingsDefaultPingStatus'] );
$this->assertEquals( $mock_options['date_format'], $allSettings['generalSettingsDateFormat'] );
$this->assertEquals( $mock_options['blogdescription'], $allSettings['generalSettingsDescription'] );
if ( ! is_multisite() ) {
$this->assertEquals( $mock_options['admin_email'], $allSettings['generalSettingsEmail'] );
}
$this->assertEquals( 'en_US', $allSettings['generalSettingsLanguage'] );
$this->assertEquals( $mock_options['start_of_week'], $allSettings['generalSettingsStartOfWeek'] );
$this->assertEquals( $mock_options['time_format'], $allSettings['generalSettingsTimeFormat'] );
$this->assertEquals( $mock_options['timezone_string'], $allSettings['generalSettingsTimezone'] );
$this->assertEquals( $mock_options['blogname'], $allSettings['generalSettingsTitle'] );
if ( ! is_multisite() ) {
$this->assertEquals( $mock_options['siteurl'], $allSettings['generalSettingsUrl'] );
}
$this->assertEquals( $mock_options['posts_per_page'], $allSettings['readingSettingsPostsPerPage'] );
$this->assertEquals( $mock_options['default_category'], $allSettings['writingSettingsDefaultCategory'] );
$this->assertEquals( $mock_options['default_post_format'], $allSettings['writingSettingsDefaultPostFormat'] );
$this->assertEquals( $mock_options['use_smilies'], $allSettings['writingSettingsUseSmilies'] );
}
}

View File

@@ -0,0 +1,285 @@
<?php
class TaxonomyObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public $admin;
public function setUp() {
parent::setUp();
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
}
public function tearDown() {
parent::tearDown();
}
/**
* testTaxonomyQueryForCategories
*
* This tests the category taxonomy.
*
* @since 0.0.5
*/
public function testTaxonomyQueryForCategories() {
/**
* Create the query string to pass to the $query
*/
$query = "
query {
categories {
taxonomyInfo {
connectedPostTypeNames
connectedPostTypes {
name
}
description
graphqlPluralName
graphqlSingleName
hierarchical
id
label
name
public
restBase
restControllerClass
showCloud
showInAdminColumn
showInGraphql
showInMenu
showInNavMenus
showInQuickEdit
showInRest
showUi
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'taxonomy', 'category' );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'categories' => [
'taxonomyInfo' => [
'connectedPostTypeNames' => [ 'post' ],
'connectedPostTypes' => [ [ 'name' => 'post' ] ],
'description' => '',
'graphqlPluralName' => 'categories',
'graphqlSingleName' => 'category',
'hierarchical' => true,
'id' => $global_id,
'label' => 'Categories',
'name' => 'category',
'public' => true,
'restBase' => 'categories',
'restControllerClass' => 'WP_REST_Terms_Controller',
'showCloud' => true,
'showInAdminColumn' => true,
'showInGraphql' => true,
'showInMenu' => true,
'showInNavMenus' => true,
'showInQuickEdit' => true,
'showInRest' => true,
'showUi' => true,
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testTaxonomyQueryForTags
*
* This tests the post tags taxonomy.
*
* @since 0.0.5
*/
public function testTaxonomyQueryForTags() {
/**
* Create the query string to pass to the $query
*/
$query = "
query {
tags {
taxonomyInfo {
connectedPostTypeNames
connectedPostTypes {
name
}
description
graphqlPluralName
graphqlSingleName
hierarchical
id
label
name
public
restBase
restControllerClass
showCloud
showInAdminColumn
showInGraphql
showInMenu
showInNavMenus
showInQuickEdit
showInRest
showUi
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'taxonomy', 'post_tag' );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'tags' => [
'taxonomyInfo' => [
'connectedPostTypeNames' => [ 'post' ],
'connectedPostTypes' => [ [ 'name' => 'post' ] ],
'description' => '',
'graphqlPluralName' => 'tags',
'graphqlSingleName' => 'tag',
'hierarchical' => false,
'id' => $global_id,
'label' => 'Tags',
'name' => 'post_tag',
'public' => true,
'restBase' => 'tags',
'restControllerClass' => 'WP_REST_Terms_Controller',
'showCloud' => true,
'showInAdminColumn' => true,
'showInGraphql' => true,
'showInMenu' => true,
'showInNavMenus' => true,
'showInQuickEdit' => true,
'showInRest' => true,
'showUi' => true,
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testTaxonomyQueryCategoryConnections.
*
* This tests the category taxonomy post object connections.
*
* @since 0.0.5
*/
public function testTaxonomyQueryCategoryConnections() {
$post_id = $this->factory->post->create();
$page_id = $this->factory->post->create( [ 'post_type' => 'page' ] );
$attachment_id = $this->factory->post->create( [ 'post_type' => 'attachment' ] );
$category_id = $this->factory->term->create( [ 'name' => 'Test' ] );
wp_set_object_terms( $post_id, $category_id, 'category' );
wp_set_object_terms( $page_id, $category_id, 'category' );
wp_set_object_terms( $attachment_id, $category_id, 'category' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
categories {
taxonomyInfo {
name
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
$global_id = \GraphQLRelay\Relay::toGlobalId( 'taxonomy', 'category' );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'categories' => [
'taxonomyInfo' => [
'name' => 'category',
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testTaxonomyQueryTagsConnections.
*
* This tests the tags taxonomy post object connections.
*
* @since 0.0.5
*/
public function testTaxonomyQueryTagsConnections() {
$post_id = $this->factory->post->create();
$post_tag_id = $this->factory->term->create( [ 'name' => 'Test' ] );
wp_set_object_terms( $post_id, $post_tag_id, 'post_tag' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
tags {
taxonomyInfo {
name
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'tags' => [
'taxonomyInfo' => [
'name' => 'post_tag',
],
],
],
];
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,244 @@
<?php
class TermObjectConnectionQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $created_post_ids;
public $admin;
public function setUp() {
// before
parent::setUp();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory()->user->create( [
'role' => 'administrator',
] );
$this->created_term_ids = $this->create_terms();
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
public function createTermObject( $args ) {
/**
* Set up the $defaults
*/
$defaults = [
'taxonomy' => 'category',
'description' => 'just a description',
];
/**
* Combine the defaults with the $args that were
* passed through
*/
$args = array_merge( $defaults, $args );
/**
* Create the page
*/
$term_id = $this->factory()->term->create( $args );
/**
* Return the $id of the post_object that was created
*/
return $term_id;
}
/**
* Creates several posts (with different timestamps) for use in cursor query tests
*
* @return array
*/
public function create_terms() {
// Create 20 posts
$created_terms = [];
for ( $i = 1; $i <= 20; $i ++ ) {
$term_id = $this->createTermObject( [
'taxonomy' => 'category',
'description' => $i,
'name' => $i,
] );
$created_terms[ $i ] = $term_id;
}
return $created_terms;
}
public function categoriesQuery( $variables ) {
$query = 'query categoriesQuery($first:Int $last:Int $after:String $before:String $where:RootCategoriesTermArgs){
categories( first:$first last:$last after:$after before:$before where:$where ) {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
id
categoryId
name
description
slug
}
}
nodes {
categoryId
}
}
}';
return do_graphql_request( $query, 'categoriesQuery', $variables );
}
public function testfirstCategory() {
/**
* Here we're querying the first category in our dataset
*/
$variables = [
'first' => 1,
];
$results = $this->categoriesQuery( $variables );
/**
* Let's query the first post in our data set so we can test against it
*/
$query = new WP_Term_Query( [
'taxonomy' => 'category',
'number' => 1,
'parent' => 0,
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
] );
$terms = $query->get_terms();
$first_term_id = $terms[0]->term_id;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $first_term_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['categories']['edges'] ) );
$this->assertEquals( $first_term_id, $results['data']['categories']['edges'][0]['node']['categoryId'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['endCursor'] );
$this->assertEquals( $first_term_id, $results['data']['categories']['nodes'][0]['categoryId'] );
$this->forwardPagination( $expected_cursor );
}
public function forwardPagination( $cursor ) {
$variables = [
'first' => 1,
'after' => $cursor,
];
$results = $this->categoriesQuery( $variables );
$offset = 1;
$query = new WP_Term_Query( [
'taxonomy' => 'category',
'number' => 1,
'offset' => $offset,
'parent' => 0,
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
] );
$terms = $query->get_terms();
$second_term_id = $terms[ $offset ]->term_id;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $second_term_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['categories']['edges'] ) );
$this->assertEquals( $second_term_id, $results['data']['categories']['edges'][0]['node']['categoryId'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['endCursor'] );
}
public function testLastPost() {
/**
* Here we're trying to query the last post in our dataset
*/
$variables = [
'last' => 1,
];
$results = $this->categoriesQuery( $variables );
/**
* Let's query the last post in our data set so we can test against it
*/
$query = new WP_Term_Query( [
'taxonomy' => 'category',
'number' => 1,
'parent' => 0,
'orderby' => 'name',
'order' => 'DESC',
'hide_empty' => false,
] );
$terms = $query->get_terms();
$last_term_id = $terms[0]->term_id;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $last_term_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['categories']['edges'] ) );
$this->assertEquals( $last_term_id, $results['data']['categories']['edges'][0]['node']['categoryId'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['endCursor'] );
$this->backwardPagination( $expected_cursor );
}
public function backwardPagination( $cursor ) {
$variables = [
'last' => 1,
'before' => $cursor,
];
$results = $this->categoriesQuery( $variables );
$offset = 1;
$query = new WP_Term_Query( [
'taxonomy' => 'category',
'number' => 1,
'parent' => 0,
'offset' => $offset,
'orderby' => 'name',
'order' => 'DESC',
'hide_empty' => false,
] );
$terms = $query->get_terms();
$second_last_term_id = $terms[ $offset ]->term_id;
$expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $second_last_term_id );
$this->assertNotEmpty( $results );
$this->assertEquals( 1, count( $results['data']['categories']['edges'] ) );
$this->assertEquals( $second_last_term_id, $results['data']['categories']['edges'][0]['node']['categoryId'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['edges'][0]['cursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['startCursor'] );
$this->assertEquals( $expected_cursor, $results['data']['categories']['pageInfo']['endCursor'] );
}
}

View File

@@ -0,0 +1,624 @@
<?php
class TermObjectMutationsTest extends \Codeception\TestCase\WPTestCase
{
public $category_name;
public $tag_name;
public $description;
public $description_update;
public $client_mutation_id;
public $admin;
public $subscriber;
public function setUp()
{
parent::setUp();
$this->category_name = 'Test Category';
$this->tag_name = 'Test Tag';
$this->description = 'Test Term Description';
$this->description_update = 'Description Update';
$this->client_mutation_id = 'someUniqueId';
$this->admin = $this->factory()->user->create([
'role' => 'administrator',
]);
$this->subscriber = $this->factory()->user->create([
'role' => 'subscriber',
]);
}
public function tearDown()
{
// your tear down methods here
// then
parent::tearDown();
}
/**
* Function that executes the mutation
*/
public function createCategoryMutation() {
$mutation = '
mutation createCategory( $clientMutationId:String!, $name:String!, $description:String ) {
createCategory(
input: {
clientMutationId: $clientMutationId
name: $name
description: $description
}
) {
clientMutationId
category {
id
name
description
}
}
}
';
$variables = wp_json_encode([
'clientMutationId' => $this->client_mutation_id,
'name' => $this->category_name,
'description' => $this->description,
]);
return do_graphql_request( $mutation, 'createCategory', $variables );
}
/**
* Function that executes the mutation
*/
public function createTagMutation() {
$mutation = '
mutation createTag( $clientMutationId:String!, $name:String!, $description:String ) {
createTag(
input: {
clientMutationId: $clientMutationId
name: $name
description: $description
}
) {
clientMutationId
tag {
id
name
description
}
}
}
';
$variables = wp_json_encode([
'clientMutationId' => $this->client_mutation_id,
'name' => $this->tag_name,
'description' => $this->description,
]);
return do_graphql_request( $mutation, 'createTag', $variables );
}
/**
* Update Tag
*
* @param string $id The ID of the term to update
* @return array
*/
public function updateTagMutation( $id ) {
$mutation = '
mutation updateTag( $clientMutationId:String!, $id:ID! $description:String ) {
updateTag(
input: {
clientMutationId: $clientMutationId
description: $description
id: $id
}
) {
clientMutationId
tag {
id
name
description
}
}
}
';
$variables = wp_json_encode([
'clientMutationId' => $this->client_mutation_id,
'id' => $id,
'description' => $this->description_update,
]);
return do_graphql_request( $mutation, 'updateTag', $variables );
}
public function deleteTagMutation( $id ) {
$mutation = '
mutation deleteTag( $clientMutationId:String!, $id:ID! ) {
deleteTag(
input: {
id: $id
clientMutationId: $clientMutationId
}
) {
clientMutationId
deletedId
tag {
id
name
}
}
}
';
$variables = wp_json_encode([
'id' => $id,
'clientMutationId' => $this->client_mutation_id,
]);
return do_graphql_request( $mutation, 'deleteTag', $variables );
}
/**
* Update Category
*
* @param string $id The ID of the term to update
* @return array
*/
public function updateCategoryMutation( $id ) {
$mutation = '
mutation updateCategory( $clientMutationId:String!, $id:ID! $description:String ) {
updateCategory(
input: {
clientMutationId: $clientMutationId
description: $description
id: $id
}
) {
clientMutationId
category {
id
name
description
}
}
}
';
$variables = wp_json_encode([
'clientMutationId' => $this->client_mutation_id,
'id' => $id,
'description' => $this->description_update,
]);
return do_graphql_request( $mutation, 'updateCategory', $variables );
}
public function deleteCategoryMutation( $id ) {
$mutation = '
mutation deleteCategory( $clientMutationId:String!, $id:ID! ) {
deleteCategory(
input: {
id: $id
clientMutationId: $clientMutationId
}
) {
clientMutationId
category {
id
name
}
}
}
';
$variables = wp_json_encode([
'id' => $id,
'clientMutationId' => $this->client_mutation_id,
]);
return do_graphql_request( $mutation, 'deleteCategory', $variables );
}
/**
* Test creating a category
*/
public function testCategoryMutations() {
/**
* Set the current user as a subscriber, who doesn't have permission
* to create terms
*/
wp_set_current_user( $this->admin );
/**
* Run the mutation
*/
$actual = $this->createCategoryMutation();
/**
* Assert that the created tag is what it should be
*/
$this->assertEquals( $actual['data']['createCategory']['clientMutationId'], $this->client_mutation_id );
$this->assertNotEmpty( $actual['data']['createCategory']['category']['id'] );
$id_parts = \GraphQLRelay\Relay::fromGlobalId( $actual['data']['createCategory']['category']['id'] );
$this->assertEquals( $id_parts['type'], 'category' );
$this->assertNotEmpty( $id_parts['id'] );
$this->assertEquals( $actual['data']['createCategory']['category']['name'], $this->category_name );
$this->assertEquals( $actual['data']['createCategory']['category']['description'], $this->description );
/**
* Try to update a Tag using a category ID, which should return errors
*/
$try_to_update_tag = $this->updateTagMutation( $actual['data']['createCategory']['category']['id'] );
$this->assertNotEmpty( $try_to_update_tag['errors'] );
/**
* Try to update a Tag using a category ID, which should return errors
*/
$try_to_delete_tag = $this->deleteTagMutation( $actual['data']['createCategory']['category']['id'] );
$this->assertNotEmpty( $try_to_delete_tag['errors'] );
/**
* Run the update mutation with the ID of the created tag
*/
$updated_category = $this->updateCategoryMutation( $actual['data']['createCategory']['category']['id'] );
/**
* Make some assertions on the response
*/
$this->assertEquals( $updated_category['data']['updateCategory']['clientMutationId'], $this->client_mutation_id );
$this->assertNotEmpty( $updated_category['data']['updateCategory']['category']['id'] );
$id_parts = \GraphQLRelay\Relay::fromGlobalId( $updated_category['data']['updateCategory']['category']['id'] );
$this->assertEquals( $id_parts['type'], 'category' );
$this->assertNotEmpty( $id_parts['id'] );
$this->assertEquals( $updated_category['data']['updateCategory']['category']['name'], $this->category_name );
$this->assertEquals( $updated_category['data']['updateCategory']['category']['description'], $this->description_update );
/**
* Delete the tag
*/
wp_set_current_user( $this->subscriber );
$deleted_category = $this->deleteCategoryMutation( $updated_category['data']['updateCategory']['category']['id'] );
/**
* A subscriber shouldn't be able to delete, so we should get an error
*/
$this->assertArrayHasKey( 'errors', $deleted_category );
/**
* Set the user back to admin and delete again
*/
wp_set_current_user( $this->admin );
$deleted_category = $this->deleteCategoryMutation( $updated_category['data']['updateCategory']['category']['id'] );
/**
* Make some assertions on the response
*/
$this->assertNotEmpty( $deleted_category );
$this->assertEquals( $deleted_category['data']['deleteCategory']['clientMutationId'], $this->client_mutation_id );
$id_parts = \GraphQLRelay\Relay::fromGlobalId( $deleted_category['data']['deleteCategory']['category']['id'] );
$this->assertEquals( $id_parts['type'], 'category' );
$this->assertNotEmpty( $id_parts['id'] );
$this->assertEquals( $deleted_category['data']['deleteCategory']['category']['name'], $this->category_name );
}
public function testCreateTagThatAlreadyExists() {
/**
* Set the user as the admin
*/
wp_set_current_user( $this->admin );
/**
* Run the mutation
*/
$actual1 = $this->createCategoryMutation();
$actual2 = $this->createCategoryMutation();
/**
* Create the term
*/
$this->assertNotEmpty( $actual1 );
/**
* Make sure there were no errors
*/
$this->assertArrayNotHasKey( 'errors', $actual1 );
$this->assertArrayHasKey( 'data', $actual1 );
/**
* Try to create the exact same term
*/
$this->assertNotEmpty( $actual2 );
/**
* Now we should expect an error
*/
$this->assertArrayHasKey( 'errors', $actual2 );
$this->assertArrayHasKey( 'data', $actual2 );
}
public function testTermIdNotReturningAfterCreate() {
/**
* Filter the term response to simulate a failure with the response of a term creation mutation
*/
add_filter( 'term_id_filter', '__return_false' );
/**
* Set the user as the admin
*/
wp_set_current_user( $this->admin );
/**
* Run the mutation
*/
$actual = $this->createCategoryMutation();
$this->assertArrayHasKey( 'errors', $actual );
$actual = $this->deleteTagMutation( 'someInvalidId' );
/**
* We should get an error because the ID is invalid
*/
$this->assertArrayHasKey( 'errors', $actual );
/**
* Cleanup by removing the filter
*/
remove_filter( 'term_id_filter', '__return_false' );
/**
* Now let's filter to mimick the response returning a WP_Error to make sure we also respond with an error
*/
add_filter( 'get_post_tag', function() {
return new \WP_Error( 'this is a test error' );
} );
/**
* Create a term
*/
$term = $this->factory()->term->create([
'taxonomy' => 'post_tag',
'name' => 'some random name',
]);
/**
* Now try and delete it.
*/
$id = \GraphQLRelay\Relay::toGlobalId( 'post_tag', $term );
$actual = $this->deleteTagMutation( $id );
/**
* Assert that we have an error because the response to the deletion responded with a WP_Error
*/
$this->assertArrayHasKey( 'errors', $actual );
}
public function testCreateTagWithNoName() {
$mutation = '
mutation createTag( $clientMutationId:String!, $name:String!, $description:String ) {
createTag(
input: {
clientMutationId: $clientMutationId
name: $name
description: $description
}
) {
clientMutationId
tag {
id
name
description
}
}
}
';
$variables = wp_json_encode([
'clientMutationId' => $this->client_mutation_id,
'description' => $this->description,
]);
$actual = do_graphql_request( $mutation, 'createTag', $variables );
$this->assertNotEmpty( $actual );
$this->assertArrayHasKey( 'errors', $actual );
}
/**
* Test creating a tag
*/
public function testTagMutations() {
/**
* Set the current user as a subscriber, who doesn't have permission
* to create terms
*/
wp_set_current_user( $this->admin );
/**
* Run the mutation
*/
$actual = $this->createTagMutation();
/**
* Assert that the created tag is what it should be
*/
$this->assertEquals( $actual['data']['createTag']['clientMutationId'], $this->client_mutation_id );
$this->assertNotEmpty( $actual['data']['createTag']['tag']['id'] );
$id_parts = \GraphQLRelay\Relay::fromGlobalId( $actual['data']['createTag']['tag']['id'] );
$this->assertEquals( $id_parts['type'], 'post_tag' );
$this->assertNotEmpty( $id_parts['id'] );
$this->assertEquals( $actual['data']['createTag']['tag']['name'], $this->tag_name );
$this->assertEquals( $actual['data']['createTag']['tag']['description'], $this->description );
/**
* Try to update a Cagegory using a Tag ID, which should return errors
*/
$try_to_update_category = $this->updateCategoryMutation( $actual['data']['createTag']['tag']['id'] );
$this->assertNotEmpty( $try_to_update_category['errors'] );
/**
* Try to update the tag as a user with improper permissions
*/
wp_set_current_user( $this->subscriber );
$try_to_delete_category = $this->updateTagMutation( $actual['data']['createTag']['tag']['id'] );
$this->assertNotEmpty( $try_to_delete_category['errors'] );
wp_set_current_user( $this->admin );
/**
* Try to update a Category using a Tag ID, which should return errors
*/
$try_to_delete_category = $this->updateCategoryMutation( $actual['data']['createTag']['tag']['id'] );
$this->assertNotEmpty( $try_to_delete_category['errors'] );
/**
* Run the update mutation with the ID of the created tag
*/
$updated_tag = $this->updateTagMutation( $actual['data']['createTag']['tag']['id'] );
/**
* Make some assertions on the response
*/
$this->assertEquals( $updated_tag['data']['updateTag']['clientMutationId'], $this->client_mutation_id );
$this->assertNotEmpty( $updated_tag['data']['updateTag']['tag']['id'] );
$id_parts = \GraphQLRelay\Relay::fromGlobalId( $updated_tag['data']['updateTag']['tag']['id'] );
$this->assertEquals( $id_parts['type'], 'post_tag' );
$this->assertNotEmpty( $id_parts['id'] );
$this->assertEquals( $updated_tag['data']['updateTag']['tag']['name'], $this->tag_name );
$this->assertEquals( $updated_tag['data']['updateTag']['tag']['description'], $this->description_update );
/**
* Delete the tag
*/
$deleted_tag = $this->deleteTagMutation( $updated_tag['data']['updateTag']['tag']['id'] );
/**
* Make some assertions on the response
*/
$this->assertNotEmpty( $deleted_tag );
$this->assertEquals( $deleted_tag['data']['deleteTag']['clientMutationId'], $this->client_mutation_id );
$this->assertNotEmpty( $deleted_tag['data']['deleteTag']['deletedId'] );
$id_parts = \GraphQLRelay\Relay::fromGlobalId( $deleted_tag['data']['deleteTag']['tag']['id'] );
$this->assertEquals( $id_parts['type'], 'post_tag' );
$this->assertNotEmpty( $id_parts['id'] );
$this->assertEquals( $deleted_tag['data']['deleteTag']['tag']['name'], $this->tag_name );
}
/**
* Test creating a tag without proper capabilitites
*/
public function testCreateTagWithoutProperCapabilities() {
/**
* Set the current user as a subscriber, who deosn't have permission
* to create terms
*/
wp_set_current_user( $this->subscriber );
/**
* Run the mutation
*/
$actual = $this->createTagMutation();
/**
* We're asserting that this will properly return an error
* because this user doesn't have permissions to create a term as a
* subscriber
*/
$this->assertNotEmpty( $actual['errors'] );
}
/**
* Test creating a category without proper capabilitites
*/
public function testCreateCategoryWithoutProperCapabilities() {
/**
* Set the current user as a subscriber, who deosn't have permission
* to create terms
*/
wp_set_current_user( $this->subscriber );
/**
* Run the mutation
*/
$actual = $this->createCategoryMutation();
/**
* We're asserting that this will properly return an error
* because this user doesn't have permissions to create a term as a
* subscriber
*/
$this->assertNotEmpty( $actual['errors'] );
}
public function testUpdateCategoryParent() {
wp_set_current_user( $this->admin );
$parent_term_id = $this->factory()->term->create([
'taxonomy' => 'category',
'name' => 'Parent Category',
]);
$query = '
mutation createChildCategory($input: CreateCategoryInput!) {
createCategory(input: $input) {
category {
parent{
id
}
}
}
}
';
$parent_id = \GraphQLRelay\Relay::toGlobalId( 'category', $parent_term_id );
$variables = [
'input' => [
'clientMutationId' => 'someId',
'name' => 'Child Category',
'parentId' => $parent_id,
],
];
$actual = do_graphql_request( $query, 'createChildCategory', $variables );
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertEquals( $parent_id, $actual['data']['createCategory']['category']['parent']['id'] );
}
}

View File

@@ -0,0 +1,408 @@
<?php
class TermObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
public function createTermObject( $args = [] ) {
/**
* Create the term
*/
$term_id = $this->factory->term->create( $args );
/**
* Return the $id of the term_object that was created
*/
return $term_id;
}
public function testTermObjectConnectionQuery() {
$term_id1 = $this->createTermObject( [
'name' => 'AAA1 Term',
'taxonomy' => 'category',
'description' => 'just a description',
] );
$term_id2 = $this->createTermObject( [
'name' => 'AAA2 Term',
'taxonomy' => 'category',
'description' => 'just a description',
] );
$term_id3 = $this->createTermObject( [
'name' => 'AAA3 Term',
'taxonomy' => 'category',
'description' => 'just a description',
] );
$query = '
{
categories(where:{hideEmpty:false}) {
edges {
node {
id
categoryId
name
}
}
}
}
';
$actual = do_graphql_request( $query );
$this->assertNotEmpty( $actual['data']['categories']['edges'][0]['node'] );
$this->assertNotEmpty( $actual['data']['categories']['edges'][0]['node']['categoryId'], $term_id1 );
$query = '
query getCategoriesBefore($beforeCursor:String){
categories(last:1 before:$beforeCursor where:{hideEmpty:false}){
edges{
node{
id
categoryId
name
}
}
}
}
';
/**
* Create a cursor for the first term ID
*/
$cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $term_id2 );
/**
* Use the cursor in our variables
*/
$variables = wp_json_encode( [
'beforeCursor' => $cursor,
] );
/**
* Do the request
*/
$actual = do_graphql_request( $query, 'getCategoriesBefore', $variables );
/**
* Assert that we should have received just 1 node, $term_id2
*/
$this->assertCount( 1, $actual['data']['categories']['edges'] );
$this->assertEquals( $actual['data']['categories']['edges'][0]['node']['categoryId'], $term_id1 );
$query = '
query getCategoriesAfter($afterCursor:String){
categories(first:1 after:$afterCursor where:{hideEmpty:false}){
edges{
node{
id
categoryId
name
}
}
}
}
';
/**
* Create a cursor for the first term ID
*/
$cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $term_id2 );
/**
* Use the cursor in our variables
*/
$variables = wp_json_encode( [
'afterCursor' => $cursor,
] );
/**
* Do the request
*/
$actual = do_graphql_request( $query, 'getCategoriesAfter', $variables );
/**
* Assert that we should have received just 1 node, $term_id2
*/
$this->assertCount( 1, $actual['data']['categories']['edges'] );
$this->assertEquals( $actual['data']['categories']['edges'][0]['node']['categoryId'], $term_id3 );
}
/**
* testTermQuery
*
* This tests creating a single term with data and retrieving said term via a GraphQL query
*
* @since 0.0.5
*/
public function testTermQuery() {
/**
* Create a term
*/
$term_id = $this->createTermObject( [
'name' => 'A Category',
'taxonomy' => 'category',
'description' => 'just a description',
] );
$taxonomy = 'category';
/**
* Create the global ID based on the term_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( $taxonomy, $term_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
category(id: \"{$global_id}\") {
categoryId
count
description
id
link
name
posts {
edges {
node {
postId
}
}
}
slug
taxonomy {
name
}
termGroupId
termTaxonomyId
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'category' => [
'categoryId' => $term_id,
'count' => null,
'description' => 'just a description',
'id' => $global_id,
'link' => "http://wpgraphql.test/?cat={$term_id}",
'name' => 'A Category',
'posts' => [
'edges' => [],
],
'slug' => 'a-category',
'taxonomy' => [
'name' => 'category',
],
'termGroupId' => null,
'termTaxonomyId' => $term_id,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testTermQueryWithAssociatedPostObjects
*
* Tests a term with associated post objects.
*
* @since 0.0.5
*/
public function testTermQueryWithAssociatedPostObjects() {
/**
* Create a term
*/
$term_id = $this->createTermObject( [ 'name' => 'A category', 'taxonomy' => 'category' ] );
// Create a comment and assign it to term.
$post_id = $this->factory->post->create( [ 'post_type' => 'post' ] );
$page_id = $this->factory->post->create( [ 'post_type' => 'page' ] );
$media_id = $this->factory->post->create( [ 'post_type' => 'attachment' ] );
wp_set_object_terms( $post_id, $term_id, 'category' );
wp_set_object_terms( $page_id, $term_id, 'category' );
wp_set_object_terms( $media_id, $term_id, 'category' );
$taxonomy = 'category';
/**
* Create the global ID based on the term_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( $taxonomy, $term_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
category(id: \"{$global_id}\") {
posts {
edges {
node {
postId
}
}
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'category' => [
'posts' => [
'edges' => [
[
'node' => [
'postId' => $post_id,
],
],
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
public function testTermQueryWithParentTerm() {
$parent_id = $this->createTermObject( [
'name' => 'Parent Category',
'taxonomy' => 'category',
] );
$child_id = $this->createTermObject( [
'name' => 'Child category',
'taxonomy' => 'category',
'parent' => $parent_id,
] );
$global_parent_id = \GraphQLRelay\Relay::toGlobalId( 'category', $parent_id );
$global_child_id = \GraphQLRelay\Relay::toGlobalId( 'category', $child_id );
$query = "
query {
category(id: \"{$global_child_id}\"){
id
categoryId
ancestors{
id
categoryId
}
}
}
";
$actual = do_graphql_request( $query );
$expected = [
'data' => [
'category' => [
'id' => $global_child_id,
'categoryId' => $child_id,
'ancestors' => [
[
'id' => $global_parent_id,
'categoryId' => $parent_id,
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testTermQueryWhereTermDoesNotExist
*
* Tests a query for non existant term.
*
* @since 0.0.5
*/
public function testTermQueryWhereTermDoesNotExist() {
$taxonomy = 'category';
/**
* Create the global ID based on the term_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( $taxonomy, 'doesNotExist' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
category(id: \"{$global_id}\") {
categoryId
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'category' => null,
],
'errors' => [
[
'message' => 'No category was found with the ID: doesNotExist',
'locations' => [
[
'line' => 3,
'column' => 4,
],
],
'path' => [
'category',
],
'category' => 'user',
],
],
];
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,68 @@
<?php
class ThemeConnectionQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public $current_date_gmt;
public $admin;
public function setUp() {
// before
parent::setUp();
$this->current_time = strtotime( 'now' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
$this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time );
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* testThemesQuery
* This tests querying for themes to ensure that we're getting back a proper connection
*/
public function testThemesQuery() {
$query = '
{
themes{
edges{
node{
id
name
}
}
nodes {
id
}
}
}
';
$actual = do_graphql_request( $query );
/**
* We don't really care what the specifics are because the default theme could change at any time
* and we don't care to maintain the exact match, we just want to make sure we are
* properly getting a theme back in the query
*/
$this->assertNotEmpty( $actual['data']['themes']['edges'] );
$this->assertNotEmpty( $actual['data']['themes']['edges'][0]['node']['id'] );
$this->assertNotEmpty( $actual['data']['themes']['edges'][0]['node']['name'] );
$this->assertNotEmpty( $actual['data']['themes']['nodes'][0]['id'] );
$this->assertEquals( $actual['data']['themes']['nodes'][0]['id'], $actual['data']['themes']['edges'][0]['node']['id'] );
foreach ( $actual['data']['themes']['edges'] as $key => $edge ) {
$this->assertEquals( $actual['data']['themes']['nodes'][ $key ]['id'], $edge['node']['id'] );
}
}
}

View File

@@ -0,0 +1,137 @@
<?php
class ThemeObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
/**
* testThemeQuery
*
* This tests creating a single theme with data and retrieving said theme via a GraphQL query
*
* @since 0.0.5
*/
public function testThemeQuery() {
/**
* Create a theme
*/
$theme_slug = 'twentyseventeen';
/**
* Create the global ID based on the theme_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'theme', $theme_slug );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
theme(id: \"{$global_id}\") {
author
authorUri
description
id
name
screenshot
slug
tags
themeUri
version
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
$screenshot = $actual['data']['theme']['screenshot'];
$this->assertTrue( is_string( $screenshot ) || null === $screenshot );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'theme' => [
'author' => null,
'authorUri' => 'https://wordpress.org/',
'description' => null,
'id' => $global_id,
'name' => 'Twenty Seventeen',
'screenshot' => $screenshot,
'slug' => 'twentyseventeen',
'tags' => null,
'themeUri' => 'https://wordpress.org/themes/twentyseventeen/',
'version' => null,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testThemeQueryWhereThemeDoesNotExist
*
* Tests a query for non existant theme.
*
* @since 0.0.5
*/
public function testThemeQueryWhereThemeDoesNotExist() {
/**
* Create the global ID based on the theme_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'theme', 'doesNotExist' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
theme(id: \"{$global_id}\") {
slug
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'theme' => null,
],
'errors' => [
[
'message' => 'No theme was found with the stylesheet: doesNotExist',
'locations' => [
[
'line' => 3,
'column' => 4,
],
],
'path' => [
'theme',
],
'category' => 'user',
],
],
];
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,70 @@
<?php
class TypesTest extends \Codeception\TestCase\WPTestCase
{
public function setUp()
{
// before
parent::setUp();
// your set up methods here
}
public function tearDown()
{
// your tear down methods here
// then
parent::tearDown();
}
public function testMapInput() {
/**
* Testing with invalid input
*/
$actual = \WPGraphQL\Types::map_input( 'string', 'another string' );
$this->assertEquals( [], $actual );
/**
* Setup some args
*/
$map = [
'stringInput' => 'string_input',
'intInput' => 'int_input',
'boolInput' => 'bool_input',
'inputObject' => 'input_object',
];
$input_args = [
'stringInput' => 'value 2',
'intInput' => 2,
'boolInput' => false,
];
$args = [
'stringInput' => 'value',
'intInput' => 1,
'boolInput' => true,
'inputObject' => \WPGraphQL\Types::map_input( $input_args, $map ),
];
$expected = [
'string_input' => 'value',
'int_input' => 1,
'bool_input' => true,
'input_object' => [
'string_input' => 'value 2',
'int_input' => 2,
'bool_input' => false,
],
];
$actual = \WPGraphQL\Types::map_input( $args, $map );
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,577 @@
<?php
class UserObjectMutationsTest extends \Codeception\TestCase\WPTestCase {
public $first_name;
public $last_name;
public $client_mutation_id;
public $author;
public $admin;
public $subscriber;
public function setUp() {
// before
parent::setUp();
// Allow new users to be created for multisite tests
update_option( 'add_new_users', true );
add_filter( 'map_meta_cap', [ $this, 'filter_multisite_edit_user_capabilities' ], 1, 4 );
remove_all_filters( 'enable_edit_any_user_configuration' );
add_filter( 'enable_edit_any_user_configuration', '__return_true' );
$this->client_mutation_id = 'someUniqueId';
$this->first_name = 'Test';
$this->last_name = 'User';
$this->author = $this->factory->user->create( [
'role' => 'author',
] );
$this->admin = $this->factory->user->create( [
'role' => 'administrator',
] );
$this->subscriber = $this->factory->user->create( [
'role' => 'subscriber',
] );
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* This filters the capabilities so that our test user can create/edit/delete users in multisite.
*
* @param $caps
* @param $cap
* @param $user_id
* @param $args
*
* @return mixed
*/
function filter_multisite_edit_user_capabilities( $caps, $cap, $user_id, $args ) {
foreach ( $caps as $key => $capability ) {
if ( $capability != 'do_not_allow' ) {
continue;
}
switch ( $cap ) {
case 'edit_user':
case 'edit_users':
$caps[ $key ] = 'edit_users';
break;
case 'delete_user':
case 'delete_users':
$caps[ $key ] = 'delete_users';
break;
case 'create_users':
$caps[ $key ] = $cap;
break;
}
}
return $caps;
}
public function createUserMutation( $args ) {
$mutation = '
mutation createUser($input:CreateUserInput!) {
createUser(input:$input){
clientMutationId
user{
firstName
lastName
roles
email
username
}
}
}';
$variables = [
'input' => [
'clientMutationId' => $this->client_mutation_id,
'username' => $args['username'],
'email' => $args['email'],
'firstName' => $this->first_name,
'lastName' => $this->last_name,
'roles' => [
'administrator',
]
]
];
$actual = do_graphql_request( $mutation, 'createUser', $variables );
return $actual;
}
public function testCreateUserObjectWithoutProperCapabilities() {
/**
* Set the current user as the subscriber role so we
* can test the mutation and make sure they cannot create a post
* since they don't have proper permissions
*/
wp_set_current_user( $this->subscriber );
/**
* Run the mutation.
*/
$actual = $this->createUserMutation( [
'username' => 'userDoesNotExist',
'email' => 'emailDoesNotExist@test.com',
] );
/**
* We're asserting that this will properly return an error
* because this user doesn't have permissions to create a user as a
* subscriber
*/
$this->assertNotEmpty( $actual['errors'] );
}
public function testCreateUserObjectWithProperCapabilities() {
wp_set_current_user( $this->admin );
$username = 'rusercreatedbyadmin';
$email = 'UserCreatedByAdmin@test.com';
$actual = $this->createUserMutation( [
'username' => $username,
'email' => $email,
] );
$expected = [
'data' => [
'createUser' => [
'clientMutationId' => $this->client_mutation_id,
'user' => [
'firstName' => $this->first_name,
'lastName' => $this->last_name,
'roles' => [
'administrator',
],
'email' => $email,
'username' => $username,
]
]
]
];
$this->assertEquals( $expected, $actual );
}
public function testPreventDuplicateUsernames() {
wp_set_current_user( $this->admin );
$username = 'duplicateUsername';
$this->factory->user->create( [
'user_login' => $username
] );
$second_user = $this->createUserMutation( [
'username' => $username,
'email' => 'secondUsername@test.com',
] );
$this->assertEquals( $second_user['errors'][0]['message'], 'Sorry, that username already exists!' );
}
public function testPreventDuplicateEmails() {
wp_set_current_user( $this->admin );
$email = 'duplicateEmailAddress@test.com';
$this->factory->user->create( [
'user_email' => $email,
] );
$second_user = $this->createUserMutation( [
'username' => 'testDuplicateEmail2',
'email' => $email,
] );
$this->assertEquals( $second_user['errors'][0]['message'], 'Sorry, that email address is already used!' );
}
public function testInvalidEmailAddress() {
wp_set_current_user( $this->admin );
$user = $this->createUserMutation( [
'username' => 'testInvalidEmail',
'email' => 'notanemail',
] );
$this->assertEquals( $user['errors'][0]['message'], 'The email address you are trying to use is invalid' );
}
public function testUpdateUser() {
wp_set_current_user( $this->admin );
$user_login = 'test_user_update';
$user_email = 'testUserUpdate@test.com';
$user_role = 'editor';
$first_name = 'Test';
$last_name = 'User';
$args = [
'user_pass' => null,
'user_login' => $user_login,
'user_email' => $user_email,
'first_name' => $first_name,
'last_name' => $last_name,
'role' => $user_role,
];
$user_id = $this->factory->user->create( $args );
$guid = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
$user_object = get_user_by( 'ID', $user_id );
$this->assertEquals( $user_object->user_login, $user_login );
$this->assertEquals( $user_object->user_email, $user_email );
$this->assertEquals( $user_object->roles[0], $user_role );
$this->assertEquals( $user_object->first_name, $first_name );
$this->assertEquals( $user_object->last_name, $last_name );
$mutation = '
mutation updateUser($input:UpdateUserInput!) {
updateUser(input:$input){
clientMutationId
user{
firstName
lastName
roles
username
email
userId
id
}
}
}
';
$updated_email = 'testUserUpdated@test.com';
$updated_firstname = 'Testupdate';
$updated_lastname = 'Updatetest';
$variables = [
'input' => [
'id' => $guid,
'clientMutationId' => $this->client_mutation_id,
'email' => $updated_email,
'firstName' => $updated_firstname,
'lastName' => $updated_lastname,
'roles' => [
'administrator',
]
]
];
$actual = do_graphql_request( $mutation, 'updateUser', $variables );
$expected = [
'data' => [
'updateUser' => [
'clientMutationId' => $this->client_mutation_id,
'user' => [
'firstName' => $updated_firstname,
'lastName' => $updated_lastname,
'roles' => [
'administrator',
],
'username' => $user_login,
'email' => $updated_email,
'userId' => $user_id,
'id' => $guid,
]
]
]
];
$this->assertEquals( $expected, $actual );
}
public function testDeleteUserWithCapability() {
wp_set_current_user( $this->admin );
$username = 'user_to_delete_with_capability';
$user_id = $this->factory->user->create( [
'role' => 'subscriber',
'user_login' => $username,
] );
$guid = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
$mutation = '
mutation deleteUser($input:DeleteUserInput!) {
deleteUser(input:$input){
clientMutationId
user{
username
userId
id
}
}
}
';
$variables = [
'input' => [
'id' => $guid,
'clientMutationId' => $this->client_mutation_id,
]
];
$actual = do_graphql_request( $mutation, 'deleteUser', $variables );
$expected = [
'data' => [
'deleteUser' => [
'clientMutationId' => $this->client_mutation_id,
'user' => [
'username' => $username,
'userId' => $user_id,
'id' => $guid,
]
]
]
];
$this->assertEquals( $expected, $actual );
$user_obj_after_delete = get_user_by( 'id', $user_id );
/**
* Make sure the user actually got deleted.
*/
$this->assertEquals( false, $user_obj_after_delete );
}
public function testDeleteUserWithoutCapability() {
$username = 'user_to_delete_without_capability';
$user_id = $this->factory->user->create( [
'role' => 'subscriber',
'user_login' => $username,
] );
$guid = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
$mutation = '
mutation deleteUser($input:DeleteUserInput!) {
deleteUser(input:$input){
clientMutationId
user{
username
userId
id
}
}
}
';
$variables = [
'input' => [
'id' => $guid,
'clientMutationId' => $this->client_mutation_id,
]
];
$actual = do_graphql_request( $mutation, 'deleteUser', $variables );
$this->assertEquals( 'Sorry, you are not allowed to delete users.', $actual['errors'][0]['message'] );
$user_obj_after_delete = get_user_by( 'id', $user_id );
/**
* Make sure the user didn't actually get deleted.
*/
$this->assertNotEquals( false, $user_obj_after_delete );
}
public function testCreateUserWithExtraFields() {
$username = 'userwithextrafields';
$email = 'userWithExtraFields@test.com';
$nicename = 'user NiceName';
$url = 'http://wpgraphql.com';
$date = date( "Y-m-d H:i:s" );
$displayName = 'User Display Name';
$nickname = 'User Nickname';
$description = 'User Description';
$locale = 'en';
wp_set_current_user( $this->admin );
$variables = [
'input' => [
'firstName' => $this->first_name,
'lastName' => $this->last_name,
'clientMutationId' => $this->client_mutation_id,
'username' => $username,
'email' => $email,
'password' => 'somePassword',
'websiteUrl' => $url,
'nicename' => $nicename,
'displayName' => $displayName,
'nickname' => $nickname,
'description' => $description,
'registered' => $date,
'locale' => $locale,
'roles' => [
'administrator',
],
],
];
$mutation = '
mutation createAndGetUser( $input:CreateUserInput! ) {
createUser( input: $input ) {
clientMutationId
user {
firstName
lastName
email
username
nicename
name
nickname
description
locale
}
}
}
';
$actual = do_graphql_request( $mutation, 'createAndGetUser', $variables );
$expected = [
'data' => [
'createUser' => [
'clientMutationId' => $this->client_mutation_id,
'user' => [
'firstName' => $this->first_name,
'lastName' => $this->last_name,
'email' => $email,
'username' => $username,
'nicename' => strtolower( str_ireplace( ' ', '-', $nicename ) ),
'name' => $displayName,
'nickname' => $nickname,
'description' => $description,
'locale' => $locale
]
]
]
];
$this->assertEquals( $expected, $actual );
}
public function testCreateUserWithoutRoles() {
$mutation = '
mutation createUserWithoutRoles( $input:CreateUserInput! ) {
createUser( input: $input ) {
clientMutationId
user {
firstName
lastName
username
}
}
}
';
$variables = [
'input' => [
'firstName' => $this->first_name,
'lastName' => $this->last_name,
'username' => 'createuserwithoutroles',
'clientMutationId' => $this->client_mutation_id,
],
];
wp_set_current_user( $this->admin );
$actual = do_graphql_request( $mutation, 'createUserWithoutRoles', $variables );
$expected = [
'data' => [
'createUser' => [
'clientMutationId' => $this->client_mutation_id,
'user' => [
'firstName' => $this->first_name,
'lastName' => $this->last_name,
'username' => 'createuserwithoutroles',
],
],
],
];
$this->assertEquals( $actual, $expected );
}
public function testUpdateUserWithInvalidRole() {
$mutation = '
mutation updateUserWithInvalidRole( $input:UpdateUserInput! ) {
updateUser( input: $input ) {
clientMutationId
user {
id
name
}
}
}
';
$variables = [
'input' => [
'clientMutationId' => $this->client_mutation_id,
'id' => \GraphQLRelay\Relay::toGlobalId( 'user', $this->author ),
'roles' => [
'invalidRole'
],
],
];
wp_set_current_user( $this->admin );
$actual = do_graphql_request( $mutation, 'updateUserWithInvalidRole', $variables );
$this->assertEquals( 'Sorry, you are not allowed to give this the following role: invalidRole.', $actual['errors'][0]['message'] );
}
}

View File

@@ -0,0 +1,611 @@
<?php
class UserObjectQueriesTest extends \Codeception\TestCase\WPTestCase {
public $current_time;
public $current_date;
public function setUp() {
parent::setUp();
$this->current_time = strtotime( '- 1 day' );
$this->current_date = date( 'Y-m-d H:i:s', $this->current_time );
}
public function tearDown() {
parent::tearDown();
}
public function createUserObject( $args = [] ) {
/**
* Set up the $defaults
*/
$defaults = [
'role' => 'subscriber',
];
/**
* Combine the defaults with the $args that were
* passed through
*/
$args = array_merge( $defaults, $args );
/**
* Create the page
*/
$user_id = $this->factory->user->create( $args );
/**
* Return the $id of the post_object that was created
*/
return $user_id;
}
/**
* testUserQuery
*
* This tests creating a single user with data and retrieving said user via a GraphQL query
*
* @since 0.0.5
*/
public function testUserQuery() {
/**
* Create a user
*/
$user_id = $this->createUserObject(
[
'user_email' => 'test@test.com',
]
);
$user = get_user_by( 'id', $user_id );
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
avatar {
size
}
capKey
capabilities
comments {
edges {
node {
commentId
}
}
}
description
email
extraCapabilities
firstName
id
lastName
locale
mediaItems {
edges {
node {
mediaItemId
}
}
}
name
nickname
pages {
edges {
node {
pageId
}
}
}
posts {
edges {
node {
postId
}
}
}
registeredDate
roles
slug
url
userId
username
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'avatar' => [
'size' => 96,
],
'capKey' => 'wp_capabilities',
'capabilities' => [ 'read', 'level_0', 'subscriber' ],
'comments' => [
'edges' => [],
],
'description' => null,
'email' => 'test@test.com',
'extraCapabilities' => [ 'read', 'level_0', 'subscriber' ],
'firstName' => null,
'id' => $global_id,
'lastName' => null,
'locale' => 'en_US',
'mediaItems' => [
'edges' => [],
],
'name' => $user->data->display_name,
'nickname' => $user->nickname,
'pages' => [
'edges' => [],
],
'posts' => [
'edges' => [],
],
'registeredDate' => date( 'c', strtotime( $user->user_registered ) ),
'roles' => [ 'subscriber' ],
'slug' => $user->data->user_nicename,
'url' => null,
'userId' => $user_id,
'username' => $user->data->user_login,
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testUserQueryWithComments
*
* This tests a single user with comments connection.
*
* @since 0.0.5
*/
public function testUserQueryWithComments() {
/**
* Create a user
*/
$user_id = $this->createUserObject();
$comment_id = $this->factory->comment->create( [ 'user_id' => $user_id ] );
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
comments {
edges {
node {
commentId
}
}
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'comments' => [
'edges' => [
[
'node' => [
'commentId' => $comment_id,
],
],
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testUserQueryWithPosts
*
* This tests a single user with posts connection.
*
* @since 0.0.5
*/
public function testUserQueryWithPosts() {
/**
* Create a user
*/
$user_id = $this->createUserObject();
$post_id = $this->factory->post->create( [ 'post_author' => $user_id ] );
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
posts {
edges {
node {
postId
}
}
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'posts' => [
'edges' => [
[
'node' => [
'postId' => $post_id,
],
],
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testUserQueryWithPages
*
* This tests a single user with pages connection.
*
* @since 0.0.5
*/
public function testUserQueryWithPages() {
/**
* Create a user
*/
$user_id = $this->createUserObject();
$post_id = $this->factory->post->create( [ 'post_author' => $user_id, 'post_type' => 'page' ] );
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
pages {
edges {
node {
pageId
}
}
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'pages' => [
'edges' => [
[
'node' => [
'pageId' => $post_id,
],
],
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testUserQueryWithMedia
*
* This tests a single user with mediaItems connection.
*
* @since 0.0.5
*/
public function testUserQueryWithMedia() {
/**
* Create a user
*/
$user_id = $this->createUserObject();
$post_id = $this->factory->post->create( [ 'post_author' => $user_id, 'post_type' => 'attachment' ] );
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
mediaItems {
edges {
node {
mediaItemId
}
}
}
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => [
'mediaItems' => [
'edges' => [
[
'node' => [
'mediaItemId' => $post_id,
],
],
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
/**
* testUserQueryWhereUserDoesNotExist
*
* Tests a query for non existant user.
*
* @since 0.0.5
*/
public function testUserQueryWhereUserDoesNotExist() {
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', 'doesNotExist' );
/**
* Create the query string to pass to the $query
*/
$query = "
query {
user(id: \"{$global_id}\") {
userId
}
}";
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'user' => null,
],
'errors' => [
[
'message' => 'No user was found with the provided ID',
'locations' => [
[
'line' => 3,
'column' => 4,
],
],
'path' => [
'user',
],
'category' => 'user',
],
],
];
$this->assertEquals( $expected, $actual );
}
public function testUsersQuery() {
/**
* Create a user
*/
$user_id = $this->createUserObject(
[
'user_email' => 'test@test.com',
]
);
/**
* Create the global ID based on the user_type and the created $id
*/
$global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id );
/**
* Create the query string to pass to the $query
*/
$query = '
query {
users(first:1) {
edges{
node{
id
userId
}
}
}
}';
/**
* Run the GraphQL query
*/
$actual = do_graphql_request( $query );
/**
* Establish the expectation for the output of the query
*/
$expected = [
'data' => [
'users' => [
'edges' => [
[
'node' => [
'id' => $global_id,
'userId' => $user_id,
],
],
],
],
],
];
$this->assertEquals( $expected, $actual );
}
public function testPageInfoQuery() {
/**
* Let's create 2 admins and 1 subscriber so we can test our "where" arg is working
*/
$this->factory->user->create([
'role' => 'administrator',
]);
$this->factory->user->create([
'role' => 'administrator',
]);
$this->factory->user->create([
'role' => 'subscriber',
]);
$query = '
query{
users(first:2 where: {role:ADMINISTRATOR}){
pageInfo{
hasNextPage
}
edges{
node{
id
}
}
}
}
';
$actual = do_graphql_request( $query );
$this->assertNotEmpty( $actual['data']['users']['pageInfo'] );
$this->assertNotEmpty( $actual['data']['users']['edges'] );
$this->assertCount( 2, $actual['data']['users']['edges'] );
$query = '
query{
users(first:1 where: {role:SUBSCRIBER}){
pageInfo{
hasNextPage
}
edges{
node{
id
}
}
}
}
';
$actual = do_graphql_request( $query );
/**
* Now let's make sure the subscriber role query worked
*/
$this->assertNotEmpty( $actual['data']['users']['pageInfo'] );
$this->assertNotEmpty( $actual['data']['users']['edges'] );
$this->assertCount( 1, $actual['data']['users']['edges'] );
}
}

View File

@@ -0,0 +1,48 @@
<?php
class ViewerQueryTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
public function testViewerQuery() {
$user_id = $this->factory->user->create( [
'role' => 'administrator',
] );
$query = '
{
viewer{
userId
roles
}
}
';
$actual = do_graphql_request( $query );
/**
* We should get an error because no user is logged in right now
*/
$this->assertArrayHasKey( 'errors', $actual );
/**
* Set the current user so we can properly test the viewer query
*/
wp_set_current_user( $user_id );
$actual = do_graphql_request( $query );
$this->assertNotEmpty( $actual );
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertEquals( $user_id, $actual['data']['viewer']['userId'] );
$this->assertContains( 'administrator', $actual['data']['viewer']['roles'] );
}
}

View File

@@ -0,0 +1,25 @@
<?php
class WPGraphQLAccessFunctionsTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
parent::setUp();
}
public function tearDown() {
parent::tearDown();
}
/**
* Tests the access function that is available to format strings to GraphQL friendly format
*/
public function testGraphQLFormatFieldName() {
$actual = graphql_format_field_name( 'This is some field name' );
$expected = 'thisIsSomeFieldName';
$this->assertEquals( $expected, $actual );
}
}

View File

@@ -0,0 +1,78 @@
<?php
class WPGraphQLTest extends \Codeception\TestCase\WPTestCase {
public $instance;
public function setUp() {
parent::setUp();
$this->instance = graphql_init();
}
public function tearDown() {
// your tear down methods here
// then
parent::tearDown();
}
/**
* Ensure that graphql_init() returns an instance of WPGraphQL
*
* @covers WPGraphQL::instance()
*/
public function testInstance() {
$this->assertTrue( $this->instance instanceof WPGraphQL );
}
/**
* @covers WPGraphQL::__wakeup()
* @covers WPGraphQL::__clone()
*/
public function testCloneWPGraphQL() {
$rc = new ReflectionClass( $this->instance );
$this->assertTrue( $rc->hasMethod( '__clone' ) );
$this->assertTrue( $rc->hasMethod( '__wakeup' ) );
}
/**
* @covers WPGraphQL::setup_constants()
*/
public function testSetupConstants() {
$this->assertTrue( defined( 'WPGRAPHQL_VERSION' ) );
$this->assertTrue( defined( 'WPGRAPHQL_PLUGIN_DIR' ) );
$this->assertTrue( defined( 'WPGRAPHQL_PLUGIN_URL' ) );
$this->assertTrue( defined( 'WPGRAPHQL_PLUGIN_FILE' ) );
}
/**
* @covers WPGraphQL::filters()
*/
public function testFilters() {
global $wp_filter;
graphql_init();
$this->assertTrue( isset( $wp_filter['graphql_schema']->callbacks ) );
$this->assertTrue( isset( $wp_filter['graphql_mediaItem_fields']->callbacks ) );
}
/**
* @covers WPGraphQL::get_static_schema()
*/
public function testGetStaticSchema() {
/**
* Set the file path for where to save the static schema
*/
$file_path = WPGRAPHQL_PLUGIN_DIR . 'schema.graphql';
$contents = 'test';
file_put_contents( $file_path, $contents );
$this->assertFileExists( $file_path );
$static_schema = WPGraphQL::get_static_schema();
$this->assertEquals( $contents, $static_schema );
}
}