Skip to content

Commit

Permalink
Fixing issue with custom post type/taxonomies and factories (#450)
Browse files Browse the repository at this point in the history
* Fixing issue with custom post type/taxonomies and factories

* Fixing other test

* Adding return type to ::factory()
  • Loading branch information
srtfisher authored Sep 7, 2023
1 parent db200e9 commit 33d3edc
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 18 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v0.12.6 - 2023-09-06

### Fixed

- Fix issue with custom post types/taxonomies and factories not resuming the
correct post type/taxonomy after creation.

## v0.12.5 - 2023-09-01

### Fixed
Expand Down
11 changes: 4 additions & 7 deletions src/mantle/database/factory/class-post-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Post_Factory extends Factory {
* @param Generator $faker Faker generator.
* @param string $post_type Post type to use.
*/
public function __construct( Generator $faker, protected string $post_type = 'post' ) {
public function __construct( Generator $faker, public string $post_type = 'post' ) {
parent::__construct( $faker );
}

Expand Down Expand Up @@ -80,12 +80,9 @@ public function with_thumbnail(): static {
* @return static
*/
public function with_post_type( string $post_type ): static {
return $this->with_middleware(
function ( array $args, Closure $next ) use ( $post_type ) {
$args['post_type'] = $post_type;

return $next( $args );
}
return tap(
clone $this,
fn ( Post_Factory $factory ) => $factory->post_type = $post_type,
);
}

Expand Down
31 changes: 25 additions & 6 deletions src/mantle/database/factory/class-term-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Term_Factory extends Factory {
* @param Generator $faker Faker generator.
* @param string $taxonomy Taxonomy name.
*/
public function __construct( Generator $faker, protected string $taxonomy ) {
public function __construct( Generator $faker, protected string $taxonomy = 'post_tag' ) {
parent::__construct( $faker );
}

Expand Down Expand Up @@ -91,12 +91,31 @@ function ( array $args, Closure $next ) use ( $posts ) {
* @return \WP_Term|Term|null
*/
public function get_object_by_id( int $object_id ) {
$term = get_term_object( $object_id );
return $this->as_models
? $this->model::find( $object_id )
: get_term_object( $object_id );
}

if ( $term && $this->as_models ) {
return Term::new_from_existing( (array) $term );
}
/**
* Create a new factory instance to create posts for a specific taxonomy.
*
* @param string $taxonomy Post type to use.
* @return static
*/
public function with_taxonomy( string $taxonomy ): static {
return tap(
clone $this,
fn ( Term_Factory $factory ) => $factory->taxonomy = $taxonomy,
);
}

return $term;
/**
* Alias for {@see Term_Factory::with_taxonomy()}.
*
* @param string $taxonomy Taxonomy to use.
* @return static
*/
public function for( string $taxonomy ): static {
return $this->with_taxonomy( $taxonomy );
}
}
3 changes: 1 addition & 2 deletions src/mantle/database/model/class-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ public static function find( $object ) {
}

// Verify the object type matches the model type.
$object_name = static::get_object_name();
if ( $post->post_type !== $object_name ) {
if ( static::get_object_name() !== $post->post_type ) {
return null;
}

Expand Down
12 changes: 11 additions & 1 deletion src/mantle/database/model/concerns/trait-has-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
namespace Mantle\Database\Model\Concerns;

use Mantle\Database\Factory\Factory;
use Mantle\Database\Factory\Post_Factory;
use Mantle\Database\Factory\Term_Factory;

/**
* Model Database Factory
Expand All @@ -19,12 +21,20 @@ trait Has_Factory {
* @param array|callable $state Default state array or callable that will be invoked to set state.
* @return \Mantle\Database\Factory\Factory<static>
*/
public static function factory( array|callable|null $state = null ) {
public static function factory( array|callable|null $state = null ): Factory {
$factory = static::new_factory() ?: Factory::factory_for_model( static::class );

return $factory
->as_models()
->with_model( static::class )
->when(
$factory instanceof Post_Factory,
fn ( Post_Factory $factory ) => $factory->with_post_type( static::get_object_name() ), // @phpstan-ignore-line expects
)
->when(
$factory instanceof Term_Factory,
fn ( Term_Factory $factory ) => $factory->with_taxonomy( static::get_object_name() ), // @phpstan-ignore-line expects
)
->when( is_array( $state ) || is_callable( $state ), fn ( Factory $factory ) => $factory->state( $state ) );
}

Expand Down
40 changes: 40 additions & 0 deletions tests/database/factory/test-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,38 @@ public function test_create_multiple_fluently_with_scopes() {
$posts[0]->title,
);
}

public function test_create_custom_post_type_model() {
register_post_type(
'custom_post_type',
[
'public' => true,
]
);

$post = Testable_Custom_Post_Type::factory()->create_and_get();

$this->assertInstanceOf( Testable_Custom_Post_Type::class, $post );
$this->assertEquals( 'custom_post_type', $post->post_type );
$this->assertNotEmpty( $post->title );
$this->assertNotEmpty( $post->content );
}

public function test_create_custom_taxonomy_model() {
register_taxonomy(
'custom_taxonomy',
'post',
[
'public' => true,
]
);

$post = Testable_Custom_Taxonomy::factory()->create_and_get();

$this->assertInstanceOf( Testable_Custom_Taxonomy::class, $post );
$this->assertEquals( 'custom_taxonomy', $post->taxonomy );
$this->assertNotEmpty( $post->name );
}
}

class Testable_Post extends Model\Post {
Expand Down Expand Up @@ -152,3 +184,11 @@ public function custom_state()
);
}
}

class Testable_Custom_Post_Type extends Model\Post {
public static $object_name = 'custom_post_type';
}

class Testable_Custom_Taxonomy extends Model\Term {
public static $object_name = 'custom_taxonomy';
}
8 changes: 6 additions & 2 deletions tests/database/factory/test-unit-testing-factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ public function test_comment_factory() {

public function test_as_models() {
$post = static::factory()->post->as_models()->create_and_get();
$term = static::factory()->term->as_models()->create_and_get();
$term = static::factory()->term->as_models()->with_model( Testable_Post_Tag::class )->create_and_get();

$this->assertInstanceOf( Post::class, $post );
$this->assertInstanceOf( Term::class, $term );
$this->assertInstanceOf( Testable_Post_Tag::class, $term );
}

public function test_factory_middleware() {
Expand Down Expand Up @@ -272,3 +272,7 @@ protected function shim_test( string $class_name, string $property ) {
$this->assertCount( 10, $object_ids );
}
}

class Testable_Post_Tag extends Term {
public static $object_name = 'post_tag';
}

0 comments on commit 33d3edc

Please sign in to comment.