From a5462e0b2a9cd143a5008f9f1cd882d19d78b180 Mon Sep 17 00:00:00 2001 From: Kocmonavtik <61938582+Kocmonavtik@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:15:30 +0300 Subject: [PATCH] ref #95034 Validator for loyalty program (#330) --- resources/pot/retailcrm-es_ES.pot | 24 +++ resources/pot/retailcrm-ru_RU.pot | 24 +++ .../class-wc-retailcrm-loyalty-constraint.php | 33 +++++ .../class-wc-retailcrm-loyalty-validator.php | 117 +++++++++++++++ src/languages/retailcrm-es_ES.mo | Bin 14660 -> 15486 bytes src/languages/retailcrm-ru_RU.mo | Bin 21307 -> 22336 bytes src/retailcrm.php | 2 + tests/datasets/data-loyalty-retailcrm.php | 78 ++++++++++ .../test-wc-retailcrm-loyalty-validator.php | 140 ++++++++++++++++++ 9 files changed, 418 insertions(+) create mode 100644 src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-constraint.php create mode 100644 src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php create mode 100644 tests/validators/test-wc-retailcrm-loyalty-validator.php diff --git a/resources/pot/retailcrm-es_ES.pot b/resources/pot/retailcrm-es_ES.pot index e859fd0..b794686 100644 --- a/resources/pot/retailcrm-es_ES.pot +++ b/resources/pot/retailcrm-es_ES.pot @@ -474,3 +474,27 @@ msgstr "Descarga de servicios" msgid "Goods with the 'virtual' option enabled will be uploaded to Simla as services" msgstr "Los bienes con la opción 'virtual' activada se cargarán en Simla como servicios" + +msgid "User not found in the system" +msgstr "Usuario no encontrado en el sistema" + +msgid "Error when searching for participation in loyalty programs" +msgstr "Error al buscar la participación en programas de fidelización" + +msgid "No active participation in the loyalty program was detected" +msgstr "No se detectó ninguna participación activa en el programa de fidelización" + +msgid "No bonuses for debiting" +msgstr "Sin bonificaciones por adeudo" + +msgid "Loyalty program not found" +msgstr "Programa de fidelización no encontrado" + +msgid "Loyalty program is not active" +msgstr "El programa de fidelización no está activo" + +msgid "Loyalty program blocked" +msgstr "Programa de fidelización bloqueado" + +msgid "This user is a corporate person" +msgstr "Este usuario es una persona jurídica" diff --git a/resources/pot/retailcrm-ru_RU.pot b/resources/pot/retailcrm-ru_RU.pot index f19b664..d75fdfc 100644 --- a/resources/pot/retailcrm-ru_RU.pot +++ b/resources/pot/retailcrm-ru_RU.pot @@ -564,3 +564,27 @@ msgstr "Выгрузка услуг" msgid "Goods with the 'virtual' option enabled will be uploaded to Simla as services" msgstr "Товары с включенной опцией 'виртуальные' будут выгружаться в CRM как услуги" + +msgid "User not found in the system" +msgstr "Пользователь не найден в системе" + +msgid "Error when searching for participation in loyalty programs" +msgstr "Ошибка при поиске участия в программах лояльности" + +msgid "No active participation in the loyalty program was detected" +msgstr "Активного участия в программе лояльности не обнаружено" + +msgid "No bonuses for debiting" +msgstr "Бонусы на списание отсутствуют" + +msgid "Loyalty program not found" +msgstr "Программа лояльности не найдена" + +msgid "Loyalty program is not active" +msgstr "Программа лояльности не активна" + +msgid "Loyalty program blocked" +msgstr "Программа лояльности заблокирована" + +msgid "This user is a corporate person" +msgstr "Данный пользователь является корпоратиным лицом" diff --git a/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-constraint.php b/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-constraint.php new file mode 100644 index 0000000..838bae9 --- /dev/null +++ b/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-constraint.php @@ -0,0 +1,33 @@ + + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ + class WC_Retailcrm_Loyalty_Constraint + { + public $notFoundCrmUser = 'User not found in the system'; + + public $errorFoundLoyalty = 'Error when searching for participation in loyalty programs'; + + public $notFoundActiveParticipation = 'No active participation in the loyalty program was detected'; + + public $notExistBonuses = 'No bonuses for debiting'; + + public $notFoundLoyalty = 'Loyalty program not found'; + + public $loyaltyInactive = 'Loyalty program is not active'; + + public $loyaltyBlocked = 'Loyalty program blocked'; + + public $isCorporateUser = 'This user is a corporate person'; + } +endif; diff --git a/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php b/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php new file mode 100644 index 0000000..6c46155 --- /dev/null +++ b/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php @@ -0,0 +1,117 @@ + + * @license http://retailcrm.ru Proprietary + * @link http://retailcrm.ru + * @see http://help.retailcrm.ru + */ + class WC_Retailcrm_Loyalty_Validator extends WC_Retailcrm_Loyalty_Constraint + { + /** @var WC_Retailcrm_Client_V5 */ + protected $apiClient; + protected $crmUser; + protected $loyaltyAccount; + protected $isActiveCorp; + + public function __construct($apiClient, $isActiveCorp) + { + $this->apiClient = $apiClient; + $this->isActiveCorp = $isActiveCorp; + } + + public function checkAccount(int $userId): bool + { + try { + $this->checkUser($userId); + $this->checkLoyaltyAccount($this->crmUser['id']); + $this->checkActiveLoyalty($this->loyaltyAccount['loyalty']['id']); + + return true; + } catch (ValidatorException $exception) { + WC_Admin_Settings::add_error((esc_html__($exception->getMessage(), 'retailcrm')) . "userId: $userId"); + } catch (Throwable $exception) { + WC_Admin_Settings::add_error($exception->getMessage()); + } + + return false; + } + + /** + * @throws ValidatorException + */ + private function checkUser($userId) + { + $responseUser = $this->apiClient->customersGet($userId); + + if (!isset($responseUser['customer']['id'])) { + throw new ValidatorException($this->notFoundCrmUser, 400); + } + + $customer = new WC_Customer($userId); + + if ($this->isActiveCorp && !empty($customer->get_shipping_company())) { + throw new ValidatorException($this->isCorporateUser, 400); + } + + $this->crmUser = $responseUser['customer']; + } + + /** + * @throws ValidatorException + */ + private function checkLoyaltyAccount($crmUserId) + { + $filter['customerId'] = $crmUserId; + $responseLoyalty = $this->apiClient->getLoyaltyAccountList($filter); + + if (!$responseLoyalty->isSuccessful() || !$responseLoyalty->offsetExists('loyaltyAccounts')) { + throw new ValidatorException($this->errorFoundLoyalty, 400); + } + + $actualAccount = null; + + foreach ($responseLoyalty['loyaltyAccounts'] as $loyaltyAccount) { + if ($loyaltyAccount['active'] === true) { + $actualAccount = $loyaltyAccount; + } + } + + if (!isset($actualAccount)) { + throw new ValidatorException($this->notFoundActiveParticipation, 400); + } + + if ($actualAccount['amount'] === 0 && $actualAccount['level']['type'] !== 'discount') { + throw new ValidatorException($this->notExistBonuses, 400); + } + + $this->loyaltyAccount = $actualAccount; + } + + /** + * @throws ValidatorException + */ + private function checkActiveLoyalty($idLoyalty) + { + $responseLoyalty = $this->apiClient->getLoyalty($idLoyalty); + + if (!$responseLoyalty->isSuccessful() || !$responseLoyalty->offsetExists('loyalty')) { + throw new ValidatorException($this->notFoundLoyalty, 400); + } + + if ($responseLoyalty['loyalty']['active'] !== true) { + throw new ValidatorException($this->loyaltyInactive, 400); + } + + if ($responseLoyalty['loyalty']['blocked'] === true) { + throw new ValidatorException($this->loyaltyBlocked, 400); + } + } + } +endif; diff --git a/src/languages/retailcrm-es_ES.mo b/src/languages/retailcrm-es_ES.mo index d0b0ad65c37a3ddb0253207f16b12647b1c22ea4..3ba889666ffdf2741e5eb96e07736c4d79a53ec8 100644 GIT binary patch delta 4156 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 RS=Ej}OWu``Kx2MH=>Ie*MH2u3 diff --git a/src/languages/retailcrm-ru_RU.mo b/src/languages/retailcrm-ru_RU.mo index 80f48494c886b7ea5105c933370c0eff08976a67..6f819beb1983b4c7202ce61308a0a72b37670e92 100644 GIT binary patch delta 4815 zcmZYB3s6+o9mny5qKKm43m^En5L6UJMMV)s(W)U83dWiyMsbA|R)s}&)%eOPRE+^O zipDlEnre-jCKg4EFHmQiwv#sF-A+518f%-Hwl;0XnKsEZNu&M#_TD&Ya)$qY&N=t) zJ?H$-xjS5XCF<&_sL-t*(fbYMDltIO(U_g~BJL(HZaWGy+4SW;3;@_|* zevG;=wudouF$HY7i?9!_z*ww9EodidB2B1_TtnUeE+#U*`Gg9SH(h%5YM7k(w>jW znB=+ur_tVn8Yqlf**#Py;>o`Wpl4ukS^^Vvh7>|COSP?u9>K0qqZQ z1m-ZiCAbXp@E52D$C5viW{OamDns2LKyBqAoPuv+7Pcd8x<4B;umH7yjY;HR6F5mn zCjJ_=g8Qf$#`8)H#9^pR%|flT1aq(wb>B(Uz}HYKzJt2&Qyh;mJftH|L7kl41H=t&^A2~PYAS5E*@2upa|93I1!NJXnEe@r)kspzAsmL6QQvzXmANl)0cMg8 zosk`=t+A1{nLGG2c48J2a61lUeA7y$9UbqYe!*^`_V5GbndWoU3J3ACr#&2onrH@c zzRWDteM?XS)uB>-6txBCkYix(q7G{u2ZiHhk}!ku%|t4C;4&=5O<0WYp;A7Mm z)C8l`oV`mxrFbB!KOL3YiP!<>pth(0HKE5)r+zth!UGu6054O~%+8^{_$Ef8_c#adU@nf~=ypawvM942Ej)(I$^0C(=l@2nu;&=(7ji02rM(ID+)Fqa z-@*j!!0a`l#1Iw6GLuoM_MskBk6KX+YJltbDBeX2XJ$IT;br(N?c=xtGf7)59>Rr~ z%&Tz-H{nbiz|q$PmLPv7w2IG4D#ww@nci8>3TERb+S^bokLK6KkE8KPJdA7bzo;`1 z;Hc|u_$Bti+o%P6j@shh+0N_hLC&!WA@_yMaVpxgD_D$oP^pVZHyisc6qfPIFcs#31dn zs0R<9?xeaH8Qbi0wNYCZm&dD%8OYqte)QpW)IzdnIGJ69+M-<;ho50OZMj04~ zItx#tW?YX-@%z{l7k@FOJ>^EpY&a1U~z&3{m@;i$Pzil4wL+VxnE zpWznVR^Vi)Q=u_W&>o8K;Fd!2Ury!m?>MLY8n&bTPwb6%F$FsmIWtc~o$ghrjO;*7 ze%ggSgLqOO08V=*%{&pBje$RtezX5bCf3}YYV-!psq$8x($yLU%YDymJyqX7$TNvQLf^ss9Yp6iRr`=B7rzWsJ!kF`Cs^_)b|m3fe#Wd z5-R724#YGyC>Spl!7rnJIWRcDaM(lY<*sxnjHVW@yN7-Sv+Q|NcU@y+Q3E4)mpaYaJcA=X+?z$)_w zy`@1$<~vLMRjUKuKx7?d-laZ0tT{hvc+8**=E0>J3q4k;zoyz>;|Y4LYHv-zU)5Zl z@?lisgUM*s8YZwV5cD=LNIls-&c0%|+2_Ms?2C3wW95|8_D$ifjjKlVX)Mj^*?fP( zj82XHa)%~a_8WGSecHan%@?_SGoGQR)oyC+lbhDdqSj*3aWPzLpXbuoF3_|u*k|pQ z$c1USsokIZ%B^j7v)#tvljpn7X=5n965brHv(H7o)Mo5GjM*Bl3vUV6>$WC~NneRf zUGq4v@!P_+T&|0J*4k&N?F!d6dvX`X#p#~baJ_xOvad9HG7=|Q;oZ#h5}z%R`*&Nc ztc{hC5I&nC3(+?&TP*v0cpJlCHuk>8(_{NKPRLAezW2zS_NnfKzp_5dKBJkDQl8La QUnZ@KGpy#hg?FR>2Xv|NTmS$7 delta 4074 zcmZwJc~F&A9LDhjUPTlTP(TG)6j4MlQ3+QBaYI2|GFM!1BN9X0Q?H?kOQvA%W-ev! zn%6a_w2g^!rd){0ajY4gbky8+vc>89-1lXsKRV-cKks(m_nhB3@5OV6JkIR)a9#^^ ztTVJzB#d0GY0O`^wJsmDW%Z2l!{z9O8?iZV$2wS!K6nB3m21d9bDNJw_@{lmfxj^U z>_=ilOvHF&oTi_BU@kW0L>YF(;~0wf?elf{b_Dy;s0XK`FAl)^I2v{1LhO$#kgu95 z48mK;*vt$2xFb;ePEN8B!--JT1Jke;=Aa%h5&36|_|SuvqDHtGb$%Z<##0!Am(UyU zpa%35)scpLSrv&zUEc$PdA`YEgHD;5sF9VRN?wLhxWhjG6{>@k*aIJ;D%GKZG08X$ zTjL(g!%B?96o#*<%SW9r!Zh5DPW9+I8{zm5W?@*cHIjVn#QtJT!Ou}Qc!3&G9K%%w zx}YkOfxU19>iiD$!K3#1v&cX510Sl)%@FFZFVcZK$)ZpM(iG4>f?js1E$pnEEHO@tgzdNNeir9uew>8K{vI z+Q*BrJ^O307Jh?FuQ`uY+x&u&_yl!b5U-R5mVvr%BkKP9QH$}klMVIkEUKsXuo-$b zG3I5A!EDUIWIT-O&@I#rpJQM2Vg6L=p|~1z(SeVVTbe(xHU>pl9Suij+c?{?p~cr1 zwQ5JAE}V$!P=UQ)jOzJHY=fIH8Y@thyN9~|1u|PEFp|}cakv4~kUp3z7?019zB^3| zmUs&e^hAAeDyno#aVVZa&3zyfro}TH7h)lHzz4{UObli7#B|gTQEybG1|yf438;aU zpr&pO2J8Lbzy{NA4xuirKn7v%qDt(;Fje{p)S?@POs|=Yn!3fPksifdtiXX7&(Ea0 z#P})u>rfrbW?^ZnMxigyH+gL6#B5Y47o!%(TGW(mLUm*pYW1E#jpRD&0e4Xy^Q4UW zUI02U1Sy^g!xanxUn?-&PoWlcHK7xODdqBp}W!dA#^ zm~E(%e~G%`L)4UcvZ7Rh=GYtCV>g_Sb?^+*2UCub_z?N32~42=n(Gwq${@@bOu^;Y z6)VsWy;$;{Fc|gVfv66RM=mi-QI$H5x=$5qKprny_YcLv?03dUT#adX#L31AHXdU> zE~GBScpFFJ)I>&&71#r(P*;CEfLi^Z;Z%H#+`^3G)zJXTZ~{++D{B;zZb7>a%H01m^aI2^OOSf$;AI)4#0*P+alMx2W?a2Kkh z4Osx1lJ1y?<53+vkE+xI%-8!L#kYMpunJjsW;1GJ<*2#6kLpNxcdK->u|E6vFcdvg ztu+#kJ=u>(Rjde^HB*YC@N1lhQA~UxZbg458-7e|6h>efrrP_L@e2FTFc2@KTZ`}p zYCnRfsRN1F46`r-r=vHPp*p(NK7RzYm@nI2N2f~phz*Urb1$pJlWj|pWnj)=Q(cD_ zFo?QSeRC5hVKg^kotc%W*XkUq#J^(!hWF(huEMvlQHE8aEg96miUX%PFd0i(aayg< z(G#QlTfcBEP#x%s+|!K35ZsHZ#22UzT*lVuooRJ22`Qc_LRIP{YAsztUN94%Mg6r{ z#$;K4r%Nz_{Yq5F90Pb|@G1u3ux#E04@QM`*gwnC_rdRMt5C;pU~{~WwJ>OqWf-c% z%}^apaHO*~x)3oK20OBGmNC8n>MJ5u8 zV78KvNG{RaaFFo2I?YiwRHFZDd;W829J$FZA063G%$-BhAf@`in&1dotxvVds5hY~ftZts#4+OgYGoI>>D zmPd++7WZ7zN;mIJW|I%dCUTf`C2D&u+@EXtOeWjxW4mz&Z;gkf;qKdcOM|mc8{s)2pPGLq-$UocsT9;BJTb9Aa;K*^2GlnY;U*5S=Do-WBbVfvV$a%>ek5B#6Q)`wJBtl!#8tWUO{Bh#2GX43MLo1 s&V|K#xxAzAc(?*$b_TfolhbOi^-XQ+`Z0C5k84TR@*1v;LC+lj0==HADgXcg diff --git a/src/retailcrm.php b/src/retailcrm.php index 0a5b3ba..5445b72 100644 --- a/src/retailcrm.php +++ b/src/retailcrm.php @@ -134,6 +134,8 @@ if (!class_exists( 'WC_Integration_Retailcrm')) : require_once(self::checkCustomFile('include/validators/url-validator/class-wc-retailcrm-url-validator.php')); require_once(self::checkCustomFile('include/validators/class-wc-retailcrm-validator-exception.php')); require_once(self::checkCustomFile('include/components/class-wc-retailcrm-loyalty-form.php')); + require_once(self::checkCustomFile('include/validators/loyalty-validator/class-wc-retailcrm-loyalty-constraint.php')); + require_once(self::checkCustomFile('include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php')); } /** diff --git a/tests/datasets/data-loyalty-retailcrm.php b/tests/datasets/data-loyalty-retailcrm.php index ef9044f..ec44910 100644 --- a/tests/datasets/data-loyalty-retailcrm.php +++ b/tests/datasets/data-loyalty-retailcrm.php @@ -73,4 +73,82 @@ class DataLoyaltyRetailCrm ], ]; } + + public static function dataCheckUser() + { + return [ + [ + 'responseApiMethod' => [], + 'wcUserType' => 'individual', + 'throwMessage' => 'User not found in the system', + 'isCorpActive' => false + ], + [ + 'responseApiMethod' => ['customer' => ['id' => 1]], + 'wcUserType' => 'corp', + 'throwMessage' => 'This user is a corporate person', + 'isCorpActive' => true, + ], + [ + 'responseApiMethod' => ['customer' => ['id' => 1]], + 'wcUserType' => 'corp', + 'throwMessage' => null, + 'isCorpActive' => false, + ], + [ + 'responseApiMethod' => ['customer' => ['id' => 1]], + 'wcUserType' => 'individual', + 'throwMessage' => null, + 'isCorpActive' => true, + ], + ]; + } + + public static function dataLoyaltyAccount() + { + return [ + [ + 'responseMock' => ['success' => true], + 'throwMessage' => 'Error when searching for participation in loyalty programs' + ], + [ + 'responseMock' => ['success' => true, 'loyaltyAccounts' => []], + 'throwMessage' => 'No active participation in the loyalty program was detected' + ], + [ + 'responseMock' => ['success' => true, 'loyaltyAccounts' => [['active' => true, 'amount' => 0, 'level' => ['type' => 'bonus_converting']]]], + 'throwMessage' => 'No bonuses for debiting' + ], + [ + 'responseMock' => ['success' => true, 'loyaltyAccounts' => [['active' => true, 'amount' => 0, 'level' => ['type' => 'discount']]]], + 'throwMessage' => null + ], + [ + 'responseMock' => ['success' => true, 'loyaltyAccounts' => [['active' => true, 'amount' => 100, 'level' => ['type' => 'bonus_converting']]]], + 'throwMessage' => null + ], + ]; + } + + public static function dataCheckActiveLoyalty() + { + return [ + [ + 'responseMock' => ['success' => true], + 'throwMessage' => 'Loyalty program not found' + ], + [ + 'responseMock' => ['success' => true, 'loyalty' => ['active' => false]], + 'throwMessage' => 'Loyalty program is not active' + ], + [ + 'responseMock' => ['success' => true, 'loyalty' => ['active' => true, 'blocked' => true]], + 'throwMessage' => 'Loyalty program blocked' + ], + [ + 'responseMock' => ['success' => true, 'loyalty' => ['active' => true, 'blocked' => false]], + 'throwMessage' => null + ] + ]; + } } diff --git a/tests/validators/test-wc-retailcrm-loyalty-validator.php b/tests/validators/test-wc-retailcrm-loyalty-validator.php new file mode 100644 index 0000000..f25694f --- /dev/null +++ b/tests/validators/test-wc-retailcrm-loyalty-validator.php @@ -0,0 +1,140 @@ +individualClient = new WC_Customer(); + $this->individualClient->set_first_name('Test'); + $this->individualClient->set_last_name('Test'); + $this->individualClient->set_email(uniqid(md5(date('Y-m-d H:i:s'))) . '@mail.com'); + $this->individualClient->set_billing_email( $this->individualClient->get_email()); + $this->individualClient->set_password('password'); + $this->individualClient->set_billing_phone('89000000000'); + $this->individualClient->set_date_created(date('Y-m-d H:i:s')); + $this->individualClient->save(); + + $this->corpClient = new WC_Customer(); + $this->corpClient->set_first_name('Test'); + $this->corpClient->set_last_name('Test'); + $this->corpClient->set_email(uniqid(md5(date('Y-m-d H:i:s'))) . '@mail.com'); + $this->corpClient->set_billing_email($this->corpClient->get_email()); + $this->corpClient->set_password('password'); + $this->corpClient->set_billing_phone('89000000000'); + $this->corpClient->set_date_created(date('Y-m-d H:i:s')); + $this->corpClient->set_shipping_company('TEST COMPANY'); + $this->corpClient->save(); + } + + /** @dataProvider datasets\DataLoyaltyRetailCrm::dataCheckUser() */ + public function testCheckUser($responseApiMethod, $wcUserType, $throwMessage, $isCorpActive) + { + $this->setResponseMock(); + $this->setApiMock('customersGet', $responseApiMethod); + + $validator = new WC_Retailcrm_Loyalty_Validator($this->apiMock, $isCorpActive); + $method = $this->getPrivateMethod('checkUser', $validator); + + $wcUserId = $wcUserType === 'individual' ? $this->individualClient->get_id() : $this->corpClient->get_id(); + + try { + $method->invokeArgs($validator, [$wcUserId]); + + if ($throwMessage) { + $this->fail('ValidatorException was not thrown'); + } else { + $this->assertTrue(true); + } + } catch (ValidatorException $exception) { + $this->assertEquals($throwMessage, $exception->getMessage()); + } + } + + /** @dataProvider datasets\DataLoyaltyRetailCrm::dataLoyaltyAccount() */ + public function testGetLoyaltyAccount($responseMock, $throwMessage) + { + $this->setResponseMock($responseMock); + $this->setApiMock('getLoyaltyAccountList', $this->responseMock); + + $validator = new WC_Retailcrm_Loyalty_Validator($this->apiMock, true); + $method = $this->getPrivateMethod('checkLoyaltyAccount', $validator); + + try { + $method->invokeArgs($validator, [777]); + + if ($throwMessage) { + $this->fail('ValidatorException was not thrown'); + } else { + $this->assertTrue(true); + } + } catch (ValidatorException $exception) { + $this->assertEquals($throwMessage, $exception->getMessage()); + } + } + + /** @dataProvider datasets\DataLoyaltyRetailCrm::dataCheckActiveLoyalty() */ + public function testCheckActivateLoyalty($responseMock, $throwMessage) + { + $this->setResponseMock($responseMock); + $this->setApiMock('getLoyalty', $this->responseMock); + + $validator = new WC_Retailcrm_Loyalty_Validator($this->apiMock, true); + $method = $this->getPrivateMethod('checkActiveLoyalty', $validator); + + try { + $method->invokeArgs($validator, [1]); + + if ($throwMessage) { + $this->fail('ValidatorException was not thrown'); + } else { + $this->assertTrue(true); + } + } catch (ValidatorException $exception) { + $this->assertEquals($throwMessage, $exception->getMessage()); + } + } + + private function setResponseMock($response = ['success' => true]) + { + $this->responseMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper') + ->disableOriginalConstructor() + ->setMethods(['isSuccessful']) + ->getMock() + ; + + $this->responseMock->setResponse($response); + $this->setMockResponse($this->responseMock, 'isSuccessful', true); + } + + private function setApiMock($method, $response) + { + $this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Client_V5') + ->disableOriginalConstructor() + ->setMethods([$method]) + ->getMock() + ; + $this->setMockResponse($this->apiMock, $method, $response); + } + + private function getPrivateMethod($method, $class) + { + $reflection = new ReflectionClass($class); + $method = $reflection->getMethod($method); + $method->setAccessible(true); + + return $method; + } + + public function tearDown() + { + $this->individualClient->delete(); + $this->corpClient->delete(); + } +}