2

I need help modelling a unit test class for my around plugin for graphql resolver method. The plugin intercept error messages so that we can customize.

namespace...applyCouponToCartplugin.php

    class ApplyCouponToCartPlugin
{
    public function __construct(CouponValidator $couponValidator, ConfigData $configData) {
        $this->_couponValidator = $couponValidator;
        $this->_configData = $configData;
    }

    public function aroundResolve(ApplyCouponToCart $subject, Closure $proceed, Field $field, $context, ResolveInfo $info, $value, $inputData) {
        $result = false;
        try {
            $result = $proceed($field, $context, $info, array($inputData['input']['coupon_code']), $inputData);
        } catch (\Exception $e) {
            if ($this->_configData->isEnabled()) {
                $msg = $this->_couponValidator->validate($inputData['input']['coupon_code'], $inputData['input']['cart_id'],$context);
                if (!empty($msg)) {
                    throw new GraphQlInputException(__($msg));
                }
            }
            throw $e;
        }
        return $result;
    }
}
  • After reading magento docs, and stack cant find solid examples to guide me where use cases for aroundplugin for unit tests

1 Answer 1

2

Not sure what $couponValidator and $configData does, but let's say these are the classes for it:

namespace Vendor\Module\Plugin;

class CouponValidator
{
    const COUPON_CODE = 'TESTCOUP';
    const EXPIRED_MESSAGE = 'TESTCOUP has expired.';
    
    public function validate($couponCode, $cartId, $context){
        if ($couponCode  == self::COUPON_CODE){
            return self::EXPIRED_MESSAGE;
        }
    }
}

class ConfigData
{
    public function isEnabled(){
        return true;
    }
}

Then a unit test for your around plugin may look something like this:

<?php

namespace Vendor\Module\Test\Unit\Plugin;

use Vendor\Module\Plugin\ApplyCouponToCartPlugin;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\GraphQl\Model\Query\Context;
use Magento\GraphQl\Model\Query\ContextExtension;
use Magento\Quote\Api\CouponManagementInterface;
use Magento\QuoteGraphQl\Model\Resolver\ApplyCouponToCart;
use Magento\Store\Model\Store;

use Vendor\Module\Plugin\CouponValidator;
use Vendor\Module\Plugin\ConfigData;

class ApplyCouponToCartPluginTest extends \PHPUnit\Framework\TestCase
{
    protected $objectManager;
    protected $plugin;
    protected $resolver;
    
    protected function setUp(): void
    {
        $this->objectManager = new ObjectManager($this);
        
        $couponValidator = new CouponValidator();
        $configData = new ConfigData();
        
        $this->plugin = $this->objectManager->getObject(ApplyCouponToCartPlugin::class, [
            'couponValidator' => $couponValidator,
            'configData' => $configData,
        ]);
    }
    
    public function testAroundResolve() : void
    {
        $couponCode = CouponValidator::COUPON_CODE;
        $field = $this->objectManager->getObject(Field::class, [
            'name' => 'applyCouponToCart',
            'type' => 'ApplyCouponToCartOutput',
            'required' => false,
            'isList' => false
        ]);
        
        $context = $this->createMock(Context::class);
        $context->method('getUserId')->willReturn(1);
        $extensionAttributes = $this->objectManager->getObject(ContextExtension::class, []);
        $store = $this->objectManager->getObject(Store::class, []);
        $store->setStoreId(1);
        $extensionAttributes->setStore($store);
        $context->method('getExtensionAttributes')->willReturn($extensionAttributes);
        
        $info = $this->createMock(ResolveInfo::class);
        $value = [$couponCode];
        $args = [
            'input' => [
                'cart_id' => 'Ew3n4lL7PelSva0SVgjKLXRz5gV6LSVs',
                'coupon_code' => $couponCode
            ]
        ];

        $couponManagement = $this->createMock(CouponManagementInterface::class);
        $couponManagement->method('set')->willReturnCallback(function($cartId, $couponCode){
            if ($couponCode == CouponValidator::COUPON_CODE){
                throw new LocalizedException(__("The coupon code isn't valid. Verify the code and try again."));
            }
        });
        
        $this->resolver = $this->objectManager->getObject(ApplyCouponToCart::class, [
            'couponManagement' => $couponManagement,
        ]);
        
        $proceed = function($field, $context, $info, $value, $args){
            return $this->resolver->resolve($field, $context, $info, $value, $args);
        };
        
        try {
            $result = $this->plugin->aroundResolve($this->resolver, $proceed, $field, $context, $info, $value, $args);
            $this->assertIsArray($result);
            
        }catch (GraphQlInputException $e){
            $expected = CouponValidator::EXPIRED_MESSAGE;
            $actual = $e->getMessage();
            $this->assertEquals($expected, $actual);
        }
        
        $couponCode = 'VALIDCOUP';
        $value = [$couponCode];
        $args['input']['coupon_code'] = $couponCode;
        
        $result = $this->plugin->aroundResolve($this->resolver, $proceed, $field, $context, $info, $value, $args);
        $this->assertIsArray($result);
    }
}
1
  • thanks, will test and adise.
    – Kbee
    Commented Sep 14, 2022 at 7:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.