Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance: Product category rest api extending wc product category #2554

Open
wants to merge 15 commits into
base: update/introduce-product-store
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions includes/REST/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
*
* @return void
*/
public function prepeare_product_response( $response, $object, $request ) {

Check warning on line 77 in includes/REST/Manager.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

The method parameter $object is never used

Check warning on line 77 in includes/REST/Manager.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

The method parameter $request is never used

Check warning on line 77 in includes/REST/Manager.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

It is recommended not to use reserved keyword "object" as function parameter name. Found: $object
$data = $response->get_data();
$author_id = get_post_field( 'post_author', $data['id'] );

Expand Down Expand Up @@ -136,7 +136,7 @@
*
* @return void
*/
public function on_dokan_rest_insert_product( $object, $request, $creating ) {

Check warning on line 139 in includes/REST/Manager.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

It is recommended not to use reserved keyword "object" as function parameter name. Found: $object
// if not creating, meaning product is updating. So return early
if ( ! $creating ) {
return;
Expand Down Expand Up @@ -205,6 +205,7 @@
DOKAN_DIR . '/includes/REST/DokanDataCountriesController.php' => '\WeDevs\Dokan\REST\DokanDataCountriesController',
DOKAN_DIR . '/includes/REST/DokanDataContinentsController.php' => '\WeDevs\Dokan\REST\DokanDataContinentsController',
DOKAN_DIR . '/includes/REST/OrderControllerV3.php' => '\WeDevs\Dokan\REST\OrderControllerV3',
DOKAN_DIR . '/includes/REST/VendorProductCategoriesController.php' => '\WeDevs\Dokan\REST\VendorProductCategoriesController',
)
);
}
Expand Down
106 changes: 106 additions & 0 deletions includes/REST/VendorProductCategoriesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace WeDevs\Dokan\REST;

use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WC_REST_Product_Categories_Controller;
use WP_REST_Server;

class VendorProductCategoriesController extends WC_REST_Product_Categories_Controller {
/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'dokan/v1';

/**
* Register the routes for terms.
*/
public function register_routes() {
register_rest_route(
$this->namespace,
'/' . $this->rest_base,
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);

register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/(?P<id>[\d]+)',
array(
'args' => array(
'id' => array(
'description' => __( 'Unique identifier for the resource.', 'dokan-lite' ),
'type' => 'integer',
),
),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}
/**
* Check if a given request has access to read items.
*
* Override the get_items_permissions_check method
* @return boolean
*/
public function get_items_permissions_check( $request ): bool {
return current_user_can( 'dokandar' );
}

/**
* Check if a given request has access to read a single item.
*
* Override the get_item_permissions_check method
* @return boolean
*/

public function get_item_permissions_check( $request ): bool {
return current_user_can( 'dokandar' );
}
/**
* Get all product categories.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|WP_REST_Response
*/
public function get_items( $request ) {
$request = apply_filters( 'dokan_rest_product_categories_query', $request );

// Get categories using parent method
return parent::get_items( $request );
}

/**
* Get a single product category.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|WP_REST_Response
*/

public function get_item( $request ) {
$request = apply_filters( 'dokan_rest_product_category_query', $request );

// Get category using parent method
return parent::get_item( $request );
}

}

Check failure on line 106 in includes/REST/VendorProductCategoriesController.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

The closing brace for the class must go on the next line after the body
249 changes: 249 additions & 0 deletions tests/php/src/ProductCategory/VendorProductCategoriesApiTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<?php

namespace WeDevs\Dokan\Tests\REST;

use WeDevs\Dokan\Test\DokanTestCase;
use WP_REST_Request;

/**
* Vendor Product Categories Controller Test
*
* @covers \WeDevs\Dokan\REST\VendorProductCategoriesController
*/
class VendorProductCategoriesApiTest extends DokanTestCase {
/**
* Test REST API base
*
* @var string
*/
protected $base = '/products/categories';

/**
* Setup test environment
*/
protected function setUp(): void {
parent::setUp();

// Create test categories
$this->categories = $this->create_test_categories();
}

/**
* Create test categories with parent-child relationships
*/
protected function create_test_categories(): array {
$categories = [];

// Create parent categories
$categories['parent1'] = $this->factory()->term->create(
[
'taxonomy' => 'product_cat',
'name' => 'Parent Category 1',
]
);

$categories['parent2'] = $this->factory()->term->create(
[
'taxonomy' => 'product_cat',
'name' => 'Parent Category 2',
]
);

// Create child categories
$categories['child1'] = $this->factory()->term->create(
[
'taxonomy' => 'product_cat',
'name' => 'Child Category 1',
'parent' => $categories['parent1'],
]
);

return $categories;
}

/**
* Test that endpoint exists
*/
public function test_endpoint_exists(): void {
$routes = $this->server->get_routes();
$this->assertArrayHasKey( $this->get_route( $this->base ), $routes );
}

/**
* Test get_items permissions
*/
public function test_get_items_permissions(): void {
// Test as guest
wp_set_current_user( 0 );
$response = $this->get_request( $this->base );
$this->assertEquals( 401, $response->get_status() );

// Test as customer
wp_set_current_user( $this->customer_id );
$response = $this->get_request( $this->base );
$this->assertEquals( 403, $response->get_status() );

// Test as vendor
wp_set_current_user( $this->seller_id1 );
$response = $this->get_request( $this->base );
$this->assertEquals( 200, $response->get_status() );
}

/**
* Test get_item permissions
*/
public function test_get_item_permissions(): void {
$category_id = $this->categories['parent1'];

// Test as guest
wp_set_current_user( 0 );
$response = $this->get_request( "{$this->base}/{$category_id}" );
$this->assertEquals( 401, $response->get_status() );

// Test as customer
wp_set_current_user( $this->customer_id );
$response = $this->get_request( "{$this->base}/{$category_id}" );
$this->assertEquals( 403, $response->get_status() );

// Test as vendor
wp_set_current_user( $this->seller_id1 );
$response = $this->get_request( "{$this->base}/{$category_id}" );
$this->assertEquals( 200, $response->get_status() );
}

/**
* Test getting product categories list
*/
public function test_get_product_categories(): void {
wp_set_current_user( $this->seller_id1 );

$response = $this->get_request( $this->base );
$this->assertEquals( 200, $response->get_status() );

$data = $response->get_data();
$this->assertIsArray( $data );
$this->assertNotEmpty( $data );

// Check structure of first category
$first_category = $data[0];
$this->assertArrayHasKey( 'id', $first_category );
$this->assertArrayHasKey( 'name', $first_category );
$this->assertArrayHasKey( 'slug', $first_category );
$this->assertArrayHasKey( 'parent', $first_category );
$this->assertArrayHasKey( 'count', $first_category );
}

/**
* Test getting single product category
*/
public function test_get_single_product_category(): void {
wp_set_current_user( $this->seller_id1 );

$category_id = $this->categories['parent1'];
$response = $this->get_request( "{$this->base}/{$category_id}" );

$this->assertEquals( 200, $response->get_status() );
$data = $response->get_data();

$this->assertEquals( $category_id, $data['id'] );
$this->assertEquals( 'Parent Category 1', $data['name'] );
}

/**
* Test filtering categories by parent
*/
public function test_filter_categories_by_parent(): void {
wp_set_current_user( $this->seller_id1 );

$parent_id = $this->categories['parent1'];
$response = $this->get_request( $this->base, [ 'parent' => $parent_id ] );

$this->assertEquals( 200, $response->get_status() );
$data = $response->get_data();

foreach ( $data as $category ) {
$this->assertEquals( $parent_id, $category['parent'] );
}
}

/**
* Test category creation is disabled
*/
public function test_create_category_is_disabled(): void {
wp_set_current_user( $this->seller_id1 );

$response = $this->post_request(
$this->base, [
'name' => 'Test Category',
]
);

$this->assertEquals( 404, $response->get_status() );
}

/**
* Test category update is disabled
*/
public function test_update_category_is_disabled(): void {
wp_set_current_user( $this->seller_id1 );

$category_id = $this->categories['parent1'];
$response = $this->put_request(
"{$this->base}/{$category_id}", [
'name' => 'Updated Name',
]
);

$this->assertEquals( 404, $response->get_status() );
}

/**
* Test category deletion is disabled
*/
public function test_delete_category_is_disabled(): void {
wp_set_current_user( $this->seller_id1 );

$category_id = $this->categories['parent1'];
$response = $this->delete_request( "{$this->base}/{$category_id}" );

$this->assertEquals( 404, $response->get_status() );
}

/**
* Test batch operations are disabled
*/
public function test_batch_operations_are_disabled(): void {
wp_set_current_user( $this->seller_id1 );

$response = $this->post_request(
"{$this->base}/batch", [
'create' => [
[ 'name' => 'New Category' ],
],
'update' => [
[
'id' => $this->categories['parent1'],
'name' => 'Updated Name',
],
],
'delete' => [
$this->categories['child1'],
],
]
);

$this->assertEquals( 404, $response->get_status() );
}

/**
* Clean up after tests
*/
protected function tearDown(): void {
// Delete test categories
foreach ( $this->categories as $category_id ) {
wp_delete_term( $category_id, 'product_cat' );
}

parent::tearDown();
}
}
Loading