Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
[Store Customization MVP] Verticals API client (#10687)
Browse files Browse the repository at this point in the history
* Add the Verticals API client

* Add tests

* Refactor error handling
  • Loading branch information
albarin authored Aug 29, 2023
1 parent 4eba538 commit 7b36b32
Show file tree
Hide file tree
Showing 2 changed files with 255 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/Verticals/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Automattic\WooCommerce\Blocks\Verticals;

/**
* Verticals API client.
*/
class Client {
const ENDPOINT = 'https://public-api.wordpress.com/wpcom/v2/site-verticals';

/**
* Make a request to the Verticals API.
*
* @param string $url The endpoint URL.
*
* @return array|\WP_Error The response body, or WP_Error if the request failed.
*/
private function request( string $url ) {
$response = wp_remote_get( $url );

$response_code = wp_remote_retrieve_response_code( $response );
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );

$error_data = array();
if ( is_wp_error( $response ) ) {
$error_data['code'] = $response->get_error_code();
$error_data['message'] = $response->get_error_message();
}

if ( 200 !== $response_code ) {
$error_data['status'] = $response_code;
if ( isset( $response_body['message'] ) ) {
$error_data['message'] = $response_body['message'];
}
if ( isset( $response_body['code'] ) ) {
$error_data['code'] = $response_body['code'];
}
}

if ( ! empty( $error_data ) ) {
return new \WP_Error( 'verticals_api_error', __( 'Request to the Verticals API failed.', 'woo-gutenberg-products-block' ), $error_data );
}

return $response_body;
}

/**
* Returns a list of verticals that have images.
*
* @return array|\WP_Error Array of verticals, or WP_Error if the request failed.
*/
public function get_verticals() {
$response = $this->request( self::ENDPOINT );
if ( is_wp_error( $response ) ) {
return $response;
}

return array_filter(
$response,
function ( $vertical ) {
return $vertical['has_vertical_images'];
}
);
}

/**
* Returns the list of images for the given vertical ID.
*
* @param int $vertical_id The vertical ID.
*
* @return array|\WP_Error Array of images, or WP_Error if the request failed.
*/
public function get_vertical_images( int $vertical_id ) {
return $this->request( self::ENDPOINT . '/' . $vertical_id . '/images' );
}
}
179 changes: 179 additions & 0 deletions tests/php/Verticals/ClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<?php
/**
* Unit tests for the Verticals API client.
*
* @package WooCommerce\Verticals\Tests
*/

namespace Automattic\WooCommerce\Blocks\Tests\Verticals;

use Automattic\WooCommerce\Blocks\Verticals\Client;
use \WP_UnitTestCase;

/**
* Class Client_Test.
*/
class ClientTest extends WP_UnitTestCase {
/**
* The client instance.
*
* @var Client $client
*/
private $client;

/**
* Initialize the client instance.
*
* @return void
*/
protected function setUp(): void {
parent::setUp();
$this->client = new Client();
}

/**
* Test get_verticals returns an error when the request fails.
*/
public function test_get_verticals_returns_an_error_when_the_request_fails() {
add_filter( 'pre_http_request', array( $this, 'return_wp_error' ), 10, 3 );

$response = $this->client->get_verticals();
$this->assertInstanceOf( 'WP_Error', $response );

$error_data = $response->get_error_data();
$this->assertEquals( 'error', $error_data['code'] );
$this->assertEquals( 'Request failed.', $error_data['message'] );

remove_filter( 'pre_http_request', array( $this, 'return_wp_error' ) );
}

/**
* Test get_verticals returns an error when the request is unsuccessful.
*/
public function test_get_verticals_returns_an_error_when_the_request_is_unsuccessful() {
add_filter( 'pre_http_request', array( $this, 'return_request_failed' ), 10, 3 );

$response = $this->client->get_verticals();
$this->assertInstanceOf( 'WP_Error', $response );

$error_data = $response->get_error_data();
$this->assertEquals( 500, $error_data['status'] );
$this->assertEquals( 'rest_error', $error_data['code'] );
$this->assertEquals( 'The request failed.', $error_data['message'] );

remove_filter( 'pre_http_request', array( $this, 'return_request_failed' ) );
}

/**
* Test get_verticals returns an array of verticals.
*/
public function test_get_verticals_returns_only_verticals_with_images() {
add_filter( 'pre_http_request', array( $this, 'return_verticals' ), 10, 3 );

$verticals = $this->client->get_verticals();
$this->assertIsArray( $verticals );

foreach ( $verticals as $vertical ) {
$this->assertTrue( $vertical['has_vertical_images'] );
}

remove_filter( 'pre_http_request', array( $this, 'return_verticals' ) );
}

/**
* Test get_vertical_images returns an error when the request fails.
*/
public function test_get_vertical_images_returns_an_error_when_the_request_fails() {
add_filter( 'pre_http_request', array( $this, 'return_wp_error' ), 10, 3 );

$response = $this->client->get_vertical_images( 1 );
$this->assertInstanceOf( 'WP_Error', $response );

$error_data = $response->get_error_data();
$this->assertEquals( 'error', $error_data['code'] );
$this->assertEquals( 'Request failed.', $error_data['message'] );

remove_filter( 'pre_http_request', array( $this, 'return_wp_error' ) );
}

/**
* Test get_vertical_images returns an error when the request is unsuccessful.
*/
public function test_get_vertical_images_returns_an_error_when_the_request_is_unsuccessful() {
add_filter( 'pre_http_request', array( $this, 'return_request_failed' ), 10, 3 );

$response = $this->client->get_vertical_images( 1 );
$this->assertInstanceOf( 'WP_Error', $response );

$error_data = $response->get_error_data();
$this->assertEquals( 500, $error_data['status'] );
$this->assertEquals( 'rest_error', $error_data['code'] );
$this->assertEquals( 'The request failed.', $error_data['message'] );

remove_filter( 'pre_http_request', array( $this, 'return_request_failed' ) );
}

/**
* Test get_vertical_images returns an array of images.
*/
public function test_get_vertical_images_returns_an_array_of_images() {
add_filter( 'pre_http_request', array( $this, 'return_vertical_images' ), 10, 3 );

$images = $this->client->get_vertical_images( 1 );
$this->assertIsArray( $images );
$this->assertCount( 2, $images );

remove_filter( 'pre_http_request', array( $this, 'return_vertical_images' ) );
}

/**
* Returns a failed request.
*/
public function return_request_failed() {
return array(
'body' => '{"code":"rest_error","message":"The request failed.","data":{"status":500}}',
'response' => array(
'code' => 500,
),
);
}

/**
* Returns a WP_Error.
*/
public function return_wp_error() {
return new \WP_Error( 'error', 'Request failed.' );
}

/**
* Returns a list of verticals.
*/
public function return_verticals() {
return array(
'body' => '[
{"id": "3","parent_id": "0","root_id": "3","name": "Arts & Entertainment","title": "Arts & Entertainment","has_vertical_images": true},
{"id": "184","parent_id": "3","root_id": "3","name": "Celebrities & Entertainment News","title": "Celebrities & Entertainment News","has_vertical_images": false},
{"id": "316","parent_id": "3","root_id": "3","name": "Comics & Animation","title": "Comics & Animation","has_vertical_images": true},
{"id": "317","parent_id": "316","root_id": "3","name": "Anime & Manga","title": "Anime & Manga","has_vertical_images": false}
]',
'response' => array(
'code' => 200,
),
);
}

/**
* Returns a list of images.
*/
public function return_vertical_images() {
return array(
'body' => '[
{"ID": 3536,"guid": "http://wpcomverticals.files.wordpress.com/2022/05/kyle-head-p6rntdapbuk-unsplash.jpg","post_title": "kyle-head-p6rNTdAPbuk-unsplash","post_excerpt": "","post_content": "","alt": "","width": 5096,"height": 3397,"size": "1.19 MB","filename": "kyle-head-p6rntdapbuk-unsplash.jpg","extension": "jpg","meta": {"vertical_id": "3","pexels_object": "","tag_names": [],"source_url": "","photographer": ""}},
{"ID": 3535,"guid": "http://wpcomverticals.files.wordpress.com/2022/05/nadim-merrikh-mbcwo39jvsi-unsplash.jpg","post_title": "nadim-merrikh-MBCWO39JVsI-unsplash","post_excerpt": "","post_content": "","alt": "","width": 6000,"height": 4000,"size": "1.36 MB","filename": "nadim-merrikh-mbcwo39jvsi-unsplash.jpg","extension": "jpg","meta": {"vertical_id": "3","pexels_object": "","tag_names": [],"source_url": "","photographer": ""}}
]',
'response' => array(
'code' => 200,
),
);
}
}

0 comments on commit 7b36b32

Please sign in to comment.