2020-04-24 21:10:24 +08:00
< ? php
/*
* This file is part of Flarum .
*
* For detailed copyright and license information , please view the
* LICENSE file that was distributed with this source code .
*/
namespace Flarum\Tests\integration\extenders ;
use Carbon\Carbon ;
use Flarum\Discussion\Discussion ;
use Flarum\Extend ;
use Flarum\Group\Group ;
2020-04-25 03:17:31 +08:00
use Flarum\Post\AbstractEventPost ;
2020-04-24 23:54:30 +08:00
use Flarum\Post\CommentPost ;
2020-04-25 03:17:31 +08:00
use Flarum\Post\DiscussionRenamedPost ;
2020-04-24 21:10:24 +08:00
use Flarum\Post\Post ;
2021-03-08 05:32:41 +08:00
use Flarum\Testing\integration\RetrievesAuthorizedUsers ;
use Flarum\Testing\integration\TestCase ;
2020-04-24 21:10:24 +08:00
use Flarum\User\User ;
class ModelTest extends TestCase
{
use RetrievesAuthorizedUsers ;
2021-01-07 11:34:32 +08:00
/**
* @ inheritDoc
*/
protected function setUp () : void
2020-04-24 21:10:24 +08:00
{
2021-01-07 11:34:32 +08:00
parent :: setUp ();
2020-04-24 21:10:24 +08:00
$this -> prepareDatabase ([
'users' => [
$this -> normalUser (),
],
]);
}
2020-04-25 03:17:31 +08:00
protected function prepPostsHierarchy ()
{
$this -> prepareDatabase ([
'discussions' => [
[ 'id' => 1 , 'title' => 'Discussion with post' , 'created_at' => Carbon :: now () -> toDateTimeString (), 'user_id' => 2 , 'first_post_id' => 1 , 'comment_count' => 1 , 'is_private' => 0 ],
],
'posts' => [
[ 'id' => 1 , 'discussion_id' => 1 , 'created_at' => Carbon :: now () -> toDateTimeString (), 'user_id' => 2 , 'type' => 'discussionRenamed' , 'content' => '<t><p>can i haz relationz?</p></t>' ],
],
]);
}
2020-04-24 21:10:24 +08:00
/**
* @ test
*/
public function custom_relationship_does_not_exist_by_default ()
{
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
$user = User :: find ( 1 );
$this -> expectException ( \BadMethodCallException :: class );
$user -> customRelation ();
}
/**
* @ test
*/
2020-04-24 22:55:04 +08:00
public function custom_hasOne_relationship_exists_if_added ()
2020-04-24 21:10:24 +08:00
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( User :: class ))
2020-04-24 23:31:08 +08:00
-> hasOne ( 'customRelation' , Discussion :: class , 'user_id' )
2020-04-24 22:55:04 +08:00
);
2020-04-24 21:10:24 +08:00
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
$user = User :: find ( 1 );
$this -> assertEquals ([], $user -> customRelation () -> get () -> toArray ());
}
/**
* @ test
*/
2020-04-24 22:55:04 +08:00
public function custom_hasMany_relationship_exists_if_added ()
2020-04-24 21:10:24 +08:00
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( User :: class ))
-> hasMany ( 'customRelation' , Discussion :: class , 'user_id' )
);
2020-04-24 21:10:24 +08:00
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
$user = User :: find ( 1 );
2020-04-24 22:55:04 +08:00
$this -> assertEquals ([], $user -> customRelation () -> get () -> toArray ());
2020-04-24 21:10:24 +08:00
}
/**
* @ test
*/
2020-04-24 22:55:04 +08:00
public function custom_belongsTo_relationship_exists_if_added ()
2020-04-24 21:10:24 +08:00
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( User :: class ))
-> belongsTo ( 'customRelation' , Discussion :: class , 'user_id' )
);
2020-04-24 21:10:24 +08:00
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
2020-04-24 22:55:04 +08:00
$user = User :: find ( 1 );
2020-04-24 21:10:24 +08:00
2020-04-24 22:55:04 +08:00
$this -> assertEquals ([], $user -> customRelation () -> get () -> toArray ());
2020-04-24 21:10:24 +08:00
}
/**
* @ test
*/
2020-04-24 22:55:04 +08:00
public function custom_relationship_exists_if_added ()
2020-04-24 21:10:24 +08:00
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( User :: class ))
-> relationship ( 'customRelation' , function ( User $user ) {
return $user -> hasMany ( Discussion :: class , 'user_id' );
})
);
2020-04-24 21:10:24 +08:00
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
$user = User :: find ( 1 );
$this -> assertEquals ([], $user -> customRelation () -> get () -> toArray ());
}
2020-11-09 10:36:38 +08:00
/**
* @ test
*/
public function custom_relationship_can_be_invokable_class ()
{
$this -> extend (
( new Extend\Model ( User :: class ))
-> relationship ( 'customRelation' , CustomRelationClass :: class )
);
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-11-09 10:36:38 +08:00
$user = User :: find ( 1 );
$this -> assertEquals ([], $user -> customRelation () -> get () -> toArray ());
}
2020-04-24 21:10:24 +08:00
/**
* @ test
*/
2020-04-24 22:55:04 +08:00
public function custom_relationship_exists_and_can_return_instances_if_added ()
2020-04-24 21:10:24 +08:00
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( User :: class ))
-> relationship ( 'customRelation' , function ( User $user ) {
return $user -> hasMany ( Discussion :: class , 'user_id' );
})
);
2020-04-24 21:10:24 +08:00
2020-04-24 22:55:04 +08:00
$this -> prepareDatabase ([
'discussions' => [
[ 'id' => 1 , 'title' => __CLASS__ , 'created_at' => Carbon :: now () -> toDateTimeString (), 'user_id' => 1 , 'first_post_id' => 1 , 'comment_count' => 1 ]
]
]);
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
$user = User :: find ( 1 );
2020-04-24 22:55:04 +08:00
$this -> assertNotEquals ([], $user -> customRelation () -> get () -> toArray ());
2021-01-27 06:53:28 +08:00
$this -> assertStringContainsString ( json_encode ( __CLASS__ ), json_encode ( $user -> customRelation () -> get ()));
2020-04-24 21:10:24 +08:00
}
2020-04-24 23:54:30 +08:00
/**
* @ test
*/
public function custom_relationship_is_inherited_to_child_classes ()
{
$this -> extend (
( new Extend\Model ( Post :: class ))
-> belongsTo ( 'ancestor' , Discussion :: class , 'discussion_id' )
);
2020-04-25 03:17:31 +08:00
$this -> prepPostsHierarchy ();
2020-04-24 23:54:30 +08:00
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 23:54:30 +08:00
$post = CommentPost :: find ( 1 );
$this -> assertInstanceOf ( Discussion :: class , $post -> ancestor );
$this -> assertEquals ( 1 , $post -> ancestor -> id );
}
2020-04-25 03:17:31 +08:00
/**
* @ test
*/
public function custom_relationship_prioritizes_child_classes_within_2_parent_classes ()
{
$this -> extend (
( new Extend\Model ( Post :: class ))
-> belongsTo ( 'ancestor' , User :: class , 'user_id' ),
( new Extend\Model ( AbstractEventPost :: class ))
-> belongsTo ( 'ancestor' , Discussion :: class , 'discussion_id' )
);
$this -> prepPostsHierarchy ();
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-25 03:17:31 +08:00
$post = DiscussionRenamedPost :: find ( 1 );
$this -> assertInstanceOf ( Discussion :: class , $post -> ancestor );
$this -> assertEquals ( 1 , $post -> ancestor -> id );
}
/**
* @ test
*/
public function custom_relationship_prioritizes_child_classes_within_child_class_and_immediate_parent ()
{
$this -> extend (
( new Extend\Model ( AbstractEventPost :: class ))
-> belongsTo ( 'ancestor' , Discussion :: class , 'discussion_id' ),
( new Extend\Model ( DiscussionRenamedPost :: class ))
-> belongsTo ( 'ancestor' , User :: class , 'user_id' )
);
$this -> prepPostsHierarchy ();
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-25 03:17:31 +08:00
$post = DiscussionRenamedPost :: find ( 1 );
$this -> assertInstanceOf ( User :: class , $post -> ancestor );
$this -> assertEquals ( 2 , $post -> ancestor -> id );
}
2020-04-24 21:10:24 +08:00
/**
* @ test
*/
2020-04-24 22:55:04 +08:00
public function custom_relationship_does_not_exist_if_added_to_unrelated_model ()
2020-04-24 21:10:24 +08:00
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( User :: class ))
-> relationship ( 'customRelation' , function ( User $user ) {
return $user -> hasMany ( Discussion :: class , 'user_id' );
})
);
2020-04-24 21:10:24 +08:00
2021-01-07 11:34:32 +08:00
$this -> app ();
2020-04-24 21:10:24 +08:00
2020-04-24 22:55:04 +08:00
$group = Group :: find ( 1 );
2020-04-24 21:10:24 +08:00
2020-04-24 22:55:04 +08:00
$this -> expectException ( \BadMethodCallException :: class );
$group -> customRelation ();
2020-04-24 21:10:24 +08:00
}
/**
* @ test
*/
public function custom_default_attribute_doesnt_exist_if_not_set ()
{
$group = new Group ;
$this -> app ();
$this -> assertNotEquals ( 'Custom Default' , $group -> name_singular );
}
/**
* @ test
*/
public function custom_default_attribute_works_if_set ()
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( Group :: class ))
-> default ( 'name_singular' , 'Custom Default' )
);
2020-04-24 21:10:24 +08:00
$this -> app ();
$group = new Group ;
$this -> assertEquals ( 'Custom Default' , $group -> name_singular );
}
/**
* @ test
*/
public function custom_default_attribute_evaluated_at_runtime_if_callable ()
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( Group :: class ))
2020-10-07 17:38:52 +08:00
-> default ( 'counter' , function ( Group $group ) {
2020-04-24 22:55:04 +08:00
static $counter = 0 ;
2020-04-24 22:56:37 +08:00
2020-04-24 22:55:04 +08:00
return ++ $counter ;
})
);
2020-04-24 21:10:24 +08:00
$this -> app ();
2020-04-24 22:55:04 +08:00
$group1 = new Group ;
$group2 = new Group ;
2020-04-24 21:10:24 +08:00
2020-04-24 22:55:04 +08:00
$this -> assertEquals ( 1 , $group1 -> counter );
$this -> assertEquals ( 2 , $group2 -> counter );
2020-04-24 21:10:24 +08:00
}
2020-04-24 23:54:30 +08:00
/**
* @ test
*/
public function custom_default_attribute_is_inherited_to_child_classes ()
{
$this -> extend (
( new Extend\Model ( Post :: class ))
-> default ( 'answer' , 42 )
);
$this -> app ();
$post = new CommentPost ;
$this -> assertEquals ( 42 , $post -> answer );
}
2020-04-25 03:17:31 +08:00
/**
* @ test
*/
public function custom_default_attribute_inheritance_prioritizes_child_class ()
{
$this -> extend (
( new Extend\Model ( Post :: class ))
-> default ( 'answer' , 'dont do this' ),
( new Extend\Model ( AbstractEventPost :: class ))
-> default ( 'answer' , 42 ),
( new Extend\Model ( DiscussionRenamedPost :: class ))
-> default ( 'answer' , 'ni!' )
);
$this -> app ();
2020-11-03 23:43:49 +08:00
$post = new ModelTestCustomPost ;
2020-04-25 03:17:31 +08:00
$this -> assertEquals ( 42 , $post -> answer );
$commentPost = new DiscussionRenamedPost ;
$this -> assertEquals ( 'ni!' , $commentPost -> answer );
}
2020-04-24 21:10:24 +08:00
/**
* @ test
*/
public function custom_default_attribute_doesnt_work_if_set_on_unrelated_model ()
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( Group :: class ))
-> default ( 'name_singular' , 'Custom Default' )
);
2020-04-24 21:10:24 +08:00
$this -> app ();
$user = new User ;
$this -> assertNotEquals ( 'Custom Default' , $user -> name_singular );
}
/**
* @ test
*/
public function custom_date_attribute_doesnt_exist_by_default ()
{
$post = new Post ;
$this -> app ();
$this -> assertNotContains ( 'custom' , $post -> getDates ());
}
/**
* @ test
*/
public function custom_date_attribute_can_be_set ()
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( Post :: class ))
-> dateAttribute ( 'custom' )
);
2020-04-24 21:10:24 +08:00
$this -> app ();
$post = new Post ;
$this -> assertContains ( 'custom' , $post -> getDates ());
}
2020-04-24 23:54:30 +08:00
/**
* @ test
*/
public function custom_date_attribute_is_inherited_to_child_classes ()
{
$this -> extend (
( new Extend\Model ( Post :: class ))
-> dateAttribute ( 'custom' )
);
$this -> app ();
$post = new CommentPost ;
$this -> assertContains ( 'custom' , $post -> getDates ());
}
2020-04-24 21:10:24 +08:00
/**
* @ test
*/
public function custom_date_attribute_doesnt_work_if_set_on_unrelated_model ()
{
2020-04-24 22:55:04 +08:00
$this -> extend (
( new Extend\Model ( Post :: class ))
-> dateAttribute ( 'custom' )
);
2020-04-24 21:10:24 +08:00
$this -> app ();
$discussion = new Discussion ;
$this -> assertNotContains ( 'custom' , $discussion -> getDates ());
}
}
2020-04-25 03:17:31 +08:00
2020-11-03 23:43:49 +08:00
class ModelTestCustomPost extends AbstractEventPost
2020-04-25 03:17:31 +08:00
{
/**
* { @ inheritdoc }
*/
public static $type = 'customPost' ;
}
2020-11-09 10:36:38 +08:00
class CustomRelationClass
{
public function __invoke ( User $user )
{
return $user -> hasMany ( Discussion :: class , 'user_id' );
}
}