WordPressのカスタム投稿タイプを作ってユーザーの種類ごとに権限をいろいろ割り当てたとしますよね。
その時にそれがちゃんと意図した通りに機能しているかをチェックしたいわけですが、ユーザーを作って何回もログインしたりログアウトしたりっていうのは、めんどくさい上に修正を繰り返すうちに怪しいことになってくることもあるわけで、この確認作業はなんとしても自動化すべきです。
カスタム投稿タイプをつくる
今回は以下のような感じでカスタム投稿タイプをつくりました。
register_post_type( 'log', array(
'labels' => array(
'name' => "Logs",
),
'public' => false,
'show_ui' => true,
'menu_icon' => 'dashicons-list-view',
'show_in_rest' => false,
'rest_base' => 'log',
'rest_controller_class' => 'WP_REST_Posts_Controller',
'capability_type' => 'page',
'capabilities' => array(
'create_posts' => 'do_not_allow',
'delete_posts' => 'do_not_allow',
),
'map_meta_cap' => false,
) );
上の例で今回重要なのは以下の部分です。
'capability_type' => 'page',
'capabilities' => array(
'create_posts' => 'do_not_allow',
'delete_posts' => 'do_not_allow',
),
'map_meta_cap' => false,
今回やりたいのは、
-
log
というカスタム投稿タイプを作る。 - ベースの権限は、固定ページと同じにする。
- ただし、記事の新規追加と削除、編集はさせたくない。
このユースケースでは実際の記事は自動的に放り込まれることを想定していて、それを管理画面の表で見れるだけでいいっていう感じです。
管理画面の表というのは以下のようなよくみるやつです。
要はこれ以外は誰にも見せたくないし、この表を見れるのも administrator
と editor
だけに限定したいということです。
この例では administrator
でも編集画面に行くと以下のようになります。
map_meta_cap
の値を true
にすると編集画面が表示されます。
PHPUnit で確認
これを実際にユニットテストで確認するには以下のような感じです。
<?php
class Posttype_Test extends WP_UnitTestCase
{
public function test_log_post_type_should_exist()
{
$this->assertTrue( in_array( 'log', get_post_types() ) );
}
public function test_log_capabilities()
{
$post_type_object = get_post_type_object( 'log' );
$this->set_current_user( 'administrator' );
$this->assertTrue( current_user_can( $post_type_object->cap->edit_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->create_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->delete_posts ) );
$this->set_current_user( 'editor' );
$this->assertTrue( current_user_can( $post_type_object->cap->edit_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->create_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->delete_posts ) );
$this->set_current_user( 'author' );
$this->assertTrue( ! current_user_can( $post_type_object->cap->edit_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->create_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->delete_posts ) );
$this->set_current_user( 'contributor' );
$this->assertTrue( ! current_user_can( $post_type_object->cap->edit_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->create_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->delete_posts ) );
$this->set_current_user( 'subscriber' );
$this->assertTrue( ! current_user_can( $post_type_object->cap->edit_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->create_posts ) );
$this->assertTrue( ! current_user_can( $post_type_object->cap->delete_posts ) );
}
/**
* Add user and set the user as current user.
*
* @param string $role administrator, editor, author, contributor ...
* @return none
*/
private function set_current_user( $role )
{
$user = $this->factory()->user->create_and_get( array(
'role' => $role,
) );
/*
* Set $user as the current user
*/
wp_set_current_user( $user->ID, $user->user_login );
}
}
まず1つ目の関数で、目的のカスタム投稿タイプが存在しているかどうかを確認します。
WP-CLI で生成したユニットテスト用環境であれば、そのプラグインが bootstrap.php
で有効化されていますので、このファイルを tests
ディレクトリ直下において phpunit
と叩くだけです。
2つ目の関数では、WordPressの各ロールごとに、意図した通りに権限が割り当てられているかどうかを確認しています。
!
がついてるやつは、その権限がないはずということを確認しています。
だらだらと全部をわざわざ書いてるのは、毎回いちいち調べるのがめんどうなので、これをコピペして !
をつけたり消したりするからです。
2つ目の関数で使っている set_current_user()
というメソッドは、PHPUnitの中でランダムなユーザーを作ってそれをログインユーザーとしてテストしてねという関数で、3つ目に定義されている関数がそれです。