diff --git a/app/code/Magento/Integration/Model/AdminTokenService.php b/app/code/Magento/Integration/Model/AdminTokenService.php
index 140c3ddc97791..0627007f329a8 100644
--- a/app/code/Magento/Integration/Model/AdminTokenService.php
+++ b/app/code/Magento/Integration/Model/AdminTokenService.php
@@ -95,7 +95,13 @@ public function createAdminAccessToken($username, $password)
}
/**
- * {@inheritdoc}
+ * Revoke token by admin id.
+ *
+ * The function will delete the token from the oauth_token table.
+ *
+ * @param int $adminId
+ * @return bool
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function revokeAdminAccessToken($adminId)
{
@@ -105,7 +111,7 @@ public function revokeAdminAccessToken($adminId)
}
try {
foreach ($tokenCollection as $token) {
- $token->setRevoked(1)->save();
+ $token->delete();
}
} catch (\Exception $e) {
throw new LocalizedException(__('The tokens could not be revoked.'));
diff --git a/app/code/Magento/Integration/Model/CustomerTokenService.php b/app/code/Magento/Integration/Model/CustomerTokenService.php
index 5278907192983..97fd8c557c30c 100644
--- a/app/code/Magento/Integration/Model/CustomerTokenService.php
+++ b/app/code/Magento/Integration/Model/CustomerTokenService.php
@@ -88,7 +88,13 @@ public function createCustomerAccessToken($username, $password)
}
/**
- * {@inheritdoc}
+ * Revoke token by customer id.
+ *
+ * The function will delete the token from the oauth_token table.
+ *
+ * @param int $customerId
+ * @return bool
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
public function revokeCustomerAccessToken($customerId)
{
@@ -98,7 +104,7 @@ public function revokeCustomerAccessToken($customerId)
}
try {
foreach ($tokenCollection as $token) {
- $token->setRevoked(1)->save();
+ $token->delete();
}
} catch (\Exception $e) {
throw new LocalizedException(__('The tokens could not be revoked.'));
diff --git a/app/code/Magento/Integration/Plugin/Model/AdminUser.php b/app/code/Magento/Integration/Plugin/Model/AdminUser.php
new file mode 100644
index 0000000000000..df3766250caa7
--- /dev/null
+++ b/app/code/Magento/Integration/Plugin/Model/AdminUser.php
@@ -0,0 +1,46 @@
+adminTokenService = $adminTokenService;
+ }
+
+ /**
+ * Check if admin is inactive - if so, invalidate their tokens
+ *
+ * @param \Magento\User\Model\User $subject
+ * @param \Magento\Framework\DataObject $object
+ * @return $this
+ */
+ public function afterSave(
+ \Magento\User\Model\User $subject,
+ \Magento\Framework\DataObject $object
+ ) {
+ $isActive = $object->getIsActive();
+ if (isset($isActive) && $isActive == 0) {
+ $this->adminTokenService->revokeAdminAccessToken($object->getId());
+ }
+ return $subject;
+ }
+}
diff --git a/app/code/Magento/Integration/Plugin/Model/CustomerUser.php b/app/code/Magento/Integration/Plugin/Model/CustomerUser.php
new file mode 100644
index 0000000000000..537b66402397f
--- /dev/null
+++ b/app/code/Magento/Integration/Plugin/Model/CustomerUser.php
@@ -0,0 +1,46 @@
+customerTokenService = $customerTokenService;
+ }
+
+ /**
+ * Check if customer is inactive - if so, invalidate their tokens
+ *
+ * @param \Magento\Customer\Model\Customer $subject
+ * @param \Magento\Framework\DataObject $object
+ * @return $this
+ */
+ public function afterSave(
+ \Magento\Customer\Model\Customer $subject,
+ \Magento\Framework\DataObject $object
+ ) {
+ $isActive = $object->getIsActive();
+ if (isset($isActive) && $isActive == 0) {
+ $this->customerTokenService->revokeCustomerAccessToken($object->getId());
+ }
+ return $subject;
+ }
+}
diff --git a/app/code/Magento/Integration/Setup/UpgradeData.php b/app/code/Magento/Integration/Setup/UpgradeData.php
new file mode 100644
index 0000000000000..b376d6a2b8b1e
--- /dev/null
+++ b/app/code/Magento/Integration/Setup/UpgradeData.php
@@ -0,0 +1,96 @@
+startSetup();
+
+ if (version_compare($context->getVersion(), '2.2.0', '<')) {
+ $this->removeRevokedTokens($setup);
+ $this->removeTokensFromInactiveAdmins($setup);
+ $this->removeTokensFromInactiveCustomers($setup);
+ }
+
+ $setup->endSetup();
+ }
+
+ /**
+ * Remove any revoked tokens from oauth_token table
+ *
+ * @param ModuleDataSetupInterface $setup
+ * @return void
+ */
+ private function removeRevokedTokens($setup)
+ {
+ $oauthTokenTable = $setup->getTable('oauth_token');
+
+ $where = ['revoked = ?' => 1];
+ $setup->getConnection()->delete($oauthTokenTable, $where);
+ }
+
+ /**
+ * Remove any tokens from oauth_token table where admin is inactive
+ *
+ * @param ModuleDataSetupInterface $setup
+ * @return void
+ */
+ private function removeTokensFromInactiveAdmins($setup)
+ {
+ $oauthTokenTable = $setup->getTable('oauth_token');
+ $adminUserTable = $setup->getTable('admin_user');
+
+ $select = $setup->getConnection()->select()->from(
+ $adminUserTable,
+ ['user_id', 'is_active']
+ );
+
+ $admins = $setup->getConnection()->fetchAll($select);
+ foreach ($admins as $admin) {
+ if ($admin['is_active'] == 0) {
+ $where = ['admin_id = ?' => (int)$admin['user_id']];
+ $setup->getConnection()->delete($oauthTokenTable, $where);
+ }
+ }
+ }
+
+ /**
+ * Remove any tokens from oauth_token table where customer is inactive
+ *
+ * @param ModuleDataSetupInterface $setup
+ * @return void
+ */
+ private function removeTokensFromInactiveCustomers($setup)
+ {
+ $oauthTokenTable = $setup->getTable('oauth_token');
+ $adminUserTable = $setup->getTable('customer_entity');
+
+ $select = $setup->getConnection()->select()->from(
+ $adminUserTable,
+ ['entity_id', 'is_active']
+ );
+
+ $admins = $setup->getConnection()->fetchAll($select);
+ foreach ($admins as $admin) {
+ if ($admin['is_active'] == 0) {
+ $where = ['customer_id = ?' => (int)$admin['entity_id']];
+ $setup->getConnection()->delete($oauthTokenTable, $where);
+ }
+ }
+ }
+}
diff --git a/app/code/Magento/Integration/Test/Unit/Model/AdminTokenServiceTest.php b/app/code/Magento/Integration/Test/Unit/Model/AdminTokenServiceTest.php
index 9a29c647d2295..52bff9ca06864 100644
--- a/app/code/Magento/Integration/Test/Unit/Model/AdminTokenServiceTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Model/AdminTokenServiceTest.php
@@ -13,6 +13,9 @@
use Magento\Integration\Model\Integration;
use Magento\Integration\Model\Oauth\Token;
+/**
+ * Test for \Magento\Integration\Model\AdminTokenService
+ */
class AdminTokenServiceTest extends \PHPUnit_Framework_TestCase
{
/** \Magento\Integration\Model\AdminTokenService */
@@ -50,7 +53,7 @@ protected function setUp()
$this->_tokenMock = $this->getMockBuilder(\Magento\Integration\Model\Oauth\Token::class)
->disableOriginalConstructor()
- ->setMethods(['getToken', 'loadByAdminId', 'setRevoked', 'save', '__wakeup'])->getMock();
+ ->setMethods(['getToken', 'loadByAdminId', 'delete', '__wakeup'])->getMock();
$this->_tokenModelCollectionMock = $this->getMockBuilder(
\Magento\Integration\Model\ResourceModel\Oauth\Token\Collection::class
@@ -97,10 +100,8 @@ public function testRevokeAdminAccessToken()
->with(null)
->will($this->returnValue(1));
$this->_tokenMock->expects($this->once())
- ->method('setRevoked')
+ ->method('delete')
->will($this->returnValue($this->_tokenMock));
- $this->_tokenMock->expects($this->once())
- ->method('save');
$this->assertTrue($this->_tokenService->revokeAdminAccessToken($adminId));
}
@@ -116,9 +117,7 @@ public function testRevokeAdminAccessTokenWithoutAdminId()
->with(null)
->will($this->returnValue($this->_tokenModelCollectionMock));
$this->_tokenMock->expects($this->never())
- ->method('save');
- $this->_tokenMock->expects($this->never())
- ->method('setRevoked')
+ ->method('delete')
->will($this->returnValue($this->_tokenMock));
$this->_tokenService->revokeAdminAccessToken(null);
}
@@ -142,10 +141,8 @@ public function testRevokeAdminAccessTokenCannotRevoked()
->method('getIterator')
->will($this->returnValue(new \ArrayIterator([$this->_tokenMock])));
- $this->_tokenMock->expects($this->never())
- ->method('save');
$this->_tokenMock->expects($this->once())
- ->method('setRevoked')
+ ->method('delete')
->will($this->throwException($exception));
$this->_tokenService->revokeAdminAccessToken($adminId);
}
diff --git a/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php b/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php
index 26e6c29f3be65..9bfe334cd7a99 100644
--- a/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Model/CustomerTokenServiceTest.php
@@ -11,6 +11,9 @@
use Magento\Integration\Model\Integration;
use Magento\Integration\Model\Oauth\Token;
+/**
+ * Test for \Magento\Integration\Model\CustomerTokenService
+ */
class CustomerTokenServiceTest extends \PHPUnit_Framework_TestCase
{
/** \Magento\Integration\Model\CustomerTokenService */
@@ -49,7 +52,7 @@ protected function setUp()
$this->_tokenMock = $this->getMockBuilder(\Magento\Integration\Model\Oauth\Token::class)
->disableOriginalConstructor()
- ->setMethods(['getToken', 'loadByCustomerId', 'setRevoked', 'save', '__wakeup'])->getMock();
+ ->setMethods(['getToken', 'loadByCustomerId', 'delete', '__wakeup'])->getMock();
$this->_tokenModelCollectionMock = $this->getMockBuilder(
\Magento\Integration\Model\ResourceModel\Oauth\Token\Collection::class
@@ -95,10 +98,8 @@ public function testRevokeCustomerAccessToken()
->method('_fetchAll')
->will($this->returnValue(1));
$this->_tokenMock->expects($this->once())
- ->method('setRevoked')
+ ->method('delete')
->will($this->returnValue($this->_tokenMock));
- $this->_tokenMock->expects($this->once())
- ->method('save');
$this->assertTrue($this->_tokenService->revokeCustomerAccessToken($customerId));
}
@@ -114,9 +115,7 @@ public function testRevokeCustomerAccessTokenWithoutCustomerId()
->with(null)
->will($this->returnValue($this->_tokenModelCollectionMock));
$this->_tokenMock->expects($this->never())
- ->method('save');
- $this->_tokenMock->expects($this->never())
- ->method('setRevoked')
+ ->method('delete')
->will($this->returnValue($this->_tokenMock));
$this->_tokenService->revokeCustomerAccessToken(null);
}
@@ -140,10 +139,8 @@ public function testRevokeCustomerAccessTokenCannotRevoked()
->method('getIterator')
->will($this->returnValue(new \ArrayIterator([$this->_tokenMock])));
- $this->_tokenMock->expects($this->never())
- ->method('save');
$this->_tokenMock->expects($this->once())
- ->method('setRevoked')
+ ->method('delete')
->will($this->throwException($exception));
$this->_tokenService->revokeCustomerAccessToken($customerId);
}
diff --git a/app/code/Magento/Integration/etc/di.xml b/app/code/Magento/Integration/etc/di.xml
index f1c1e5b4fb7de..387770909bda6 100644
--- a/app/code/Magento/Integration/etc/di.xml
+++ b/app/code/Magento/Integration/etc/di.xml
@@ -29,4 +29,10 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Integration/etc/module.xml b/app/code/Magento/Integration/etc/module.xml
index 076aaeb22afb5..c5e2aa75a8d05 100644
--- a/app/code/Magento/Integration/etc/module.xml
+++ b/app/code/Magento/Integration/etc/module.xml
@@ -6,7 +6,7 @@
*/
-->
-
+
diff --git a/dev/tests/api-functional/testsuite/Magento/Integration/Model/AdminTokenServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Integration/Model/AdminTokenServiceTest.php
index 4285b76bba772..3fb7b3417b679 100644
--- a/dev/tests/api-functional/testsuite/Magento/Integration/Model/AdminTokenServiceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Integration/Model/AdminTokenServiceTest.php
@@ -79,6 +79,19 @@ public function testCreateAdminAccessToken()
$this->assertToken($adminUserNameFromFixture, $accessToken);
}
+ /**
+ * Provider to test input validation
+ *
+ * @return array
+ */
+ public function validationDataProvider()
+ {
+ return [
+ 'Check for empty credentials' => ['', ''],
+ 'Check for null credentials' => [null, null]
+ ];
+ }
+
/**
* @dataProvider validationDataProvider
*/
@@ -95,8 +108,8 @@ public function testCreateAdminAccessTokenEmptyOrNullCredentials()
$requestData = ['username' => '', 'password' => ''];
$this->_webApiCall($serviceInfo, $requestData);
$noExceptionOccurred = true;
- } catch (\Exception $e) {
- $this->assertInputExceptionMessages($e);
+ } catch (\Exception $exception) {
+ $this->assertInputExceptionMessages($exception);
}
if ($noExceptionOccurred) {
$this->fail("Exception was expected to be thrown when provided credentials are invalid.");
@@ -118,8 +131,8 @@ public function testCreateAdminAccessTokenInvalidCredentials()
$requestData = ['username' => $customerUserName, 'password' => $password];
$this->_webApiCall($serviceInfo, $requestData);
$noExceptionOccurred = true;
- } catch (\Exception $e) {
- $this->assertInvalidCredentialsException($e);
+ } catch (\Exception $exception) {
+ $this->assertInvalidCredentialsException($exception);
}
if ($noExceptionOccurred) {
$this->fail("Exception was expected to be thrown when provided credentials are invalid.");
@@ -127,16 +140,63 @@ public function testCreateAdminAccessTokenInvalidCredentials()
}
/**
- * Provider to test input validation
- *
- * @return array
+ * @magentoApiDataFixture Magento/Webapi/_files/webapi_user.php
*/
- public function validationDataProvider()
+ public function testUseAdminAccessTokenInactiveAdmin()
{
- return [
- 'Check for empty credentials' => ['', ''],
- 'Check for null credentials' => [null, null]
+ $adminUserNameFromFixture = 'webapi_user';
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+ ],
+ ];
+ $requestData = [
+ 'username' => $adminUserNameFromFixture,
+ 'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
];
+ $accessToken = $this->_webApiCall($serviceInfo, $requestData);
+ $this->assertToken($adminUserNameFromFixture, $accessToken);
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => '/V1/store/storeConfigs',
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ 'token' => $accessToken
+ ]
+ ];
+ $requestData = [
+ 'storeCodes' => ['default'],
+ ];
+ $storeConfigs = $this->_webApiCall($serviceInfo, $requestData);
+ $this->assertNotNull($storeConfigs);
+
+ $adminUser = $this->userModel->loadByUsername($adminUserNameFromFixture);
+ $adminUser->setData("is_active", 0);
+ $adminUser->save();
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => '/V1/store/storeConfigs',
+ 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ 'token' => $accessToken
+ ]
+ ];
+ $requestData = [
+ 'storeCodes' => ['default'],
+ ];
+
+ $noExceptionOccurred = false;
+ try {
+ $this->_webApiCall($serviceInfo, $requestData);
+ $noExceptionOccurred = true;
+ } catch (\Exception $exception) {
+ $this->assertUnauthorizedAccessException($exception);
+ }
+ if ($noExceptionOccurred) {
+ $this->fail("Exception was expected to be thrown when provided token is expired.");
+ }
}
/**
@@ -167,7 +227,7 @@ public function testThrottlingMaxAttempts()
try {
$this->_webApiCall($serviceInfo, $invalidCredentials);
$noExceptionOccurred = true;
- } catch (\Exception $e) {
+ } catch (\Exception $exception) {
}
}
if ($noExceptionOccurred) {
@@ -209,8 +269,8 @@ public function testThrottlingAccountLockout()
try {
$this->_webApiCall($serviceInfo, $invalidCredentials);
$noExceptionOccurred = true;
- } catch (\Exception $e) {
- $this->assertInvalidCredentialsException($e);
+ } catch (\Exception $exception) {
+ $this->assertInvalidCredentialsException($exception);
}
if ($noExceptionOccurred) {
$this->fail("Exception was expected to be thrown when provided credentials are invalid.");
@@ -221,8 +281,8 @@ public function testThrottlingAccountLockout()
try {
$this->_webApiCall($serviceInfo, $validCredentials);
$noExceptionOccurred = true;
- } catch (\Exception $e) {
- $this->assertInvalidCredentialsException($e);
+ } catch (\Exception $exception) {
+ $this->assertInvalidCredentialsException($exception);
}
if ($noExceptionOccurred) {
$this->fail("Exception was expected to be thrown because account should have been locked at this point.");
@@ -232,12 +292,12 @@ public function testThrottlingAccountLockout()
/**
* Assert for presence of Input exception messages
*
- * @param \Exception $e
+ * @param \Exception $exception
*/
- private function assertInputExceptionMessages($e)
+ private function assertInputExceptionMessages($exception)
{
- $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
- $exceptionData = $this->processRestExceptionResult($e);
+ $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $exception->getCode());
+ $exceptionData = $this->processRestExceptionResult($exception);
$expectedExceptionData = [
'message' => 'One or more input exceptions have occurred.',
'errors' => [
@@ -261,18 +321,44 @@ private function assertInputExceptionMessages($e)
/**
* Make sure that status code and message are correct in case of authentication failure.
*
- * @param \Exception $e
+ * @param \Exception $exception
*/
- private function assertInvalidCredentialsException($e)
+ private function assertInvalidCredentialsException($exception)
{
- $this->assertEquals(HTTPExceptionCodes::HTTP_UNAUTHORIZED, $e->getCode(), "Response HTTP code is invalid.");
- $exceptionData = $this->processRestExceptionResult($e);
+ $this->assertEquals(
+ HTTPExceptionCodes::HTTP_UNAUTHORIZED,
+ $exception->getCode(),
+ "Response HTTP code is invalid."
+ );
+ $exceptionData = $this->processRestExceptionResult($exception);
$expectedExceptionData = [
'message' => 'You did not sign in correctly or your account is temporarily disabled.'
];
$this->assertEquals($expectedExceptionData, $exceptionData, "Exception message is invalid.");
}
+ /**
+ * Make sure that status code and message are correct in case of authentication failure.
+ *
+ * @param \Exception $exception
+ */
+ private function assertUnauthorizedAccessException($exception)
+ {
+ $this->assertEquals(
+ HTTPExceptionCodes::HTTP_UNAUTHORIZED,
+ $exception->getCode(),
+ "Response HTTP code is invalid."
+ );
+ $exceptionData = $this->processRestExceptionResult($exception);
+ $expectedExceptionData = [
+ 'message' => 'Consumer is not authorized to access %resources',
+ 'parameters' => [
+ 'resources' => 'Magento_Backend::store'
+ ]
+ ];
+ $this->assertEquals($expectedExceptionData, $exceptionData, "Exception message is invalid.");
+ }
+
/**
* Make sure provided token is valid and belongs to the specified user.
*
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/InvalidateTokenTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/InvalidateTokenTest.php
index 56fa848930862..fefb0dad0f319 100644
--- a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/InvalidateTokenTest.php
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/InvalidateTokenTest.php
@@ -39,7 +39,7 @@ public function testInvalidateSingleToken()
$this->getRequest()->setParam('user_id', $adminUserId);
$this->dispatch('backend/admin/user/invalidateToken');
$token = $tokenModel->loadByAdminId($adminUserId);
- $this->assertEquals(1, $token->getRevoked());
+ $this->assertEquals(null, $token->getId());
}
/**
diff --git a/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php b/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php
index 32d6f4c352a59..14bbf8af826f4 100644
--- a/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php
+++ b/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php
@@ -231,6 +231,7 @@ public function testAuthenticateCaseInsensitive()
}
/**
+ * @expectedException \Magento\Framework\Exception\LocalizedException
* @expectedException \Magento\Framework\Exception\AuthenticationException
* @magentoDbIsolation enabled
*/
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/_files/webapi_user.php b/dev/tests/integration/testsuite/Magento/Webapi/_files/webapi_user.php
index 68962bb2478cb..8aa089f929e65 100644
--- a/dev/tests/integration/testsuite/Magento/Webapi/_files/webapi_user.php
+++ b/dev/tests/integration/testsuite/Magento/Webapi/_files/webapi_user.php
@@ -19,6 +19,6 @@
->setResourceId('Magento_Backend::all')
->setPrivileges("")
->setAssertId(0)
- ->setRoleId(1)
+ ->setRoleId(2)
->setPermission('allow');
$model->save();
diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx
index aa7a160ebe72f..d9b1a94b12e2d 100644
--- a/setup/performance-toolkit/benchmark.jmx
+++ b/setup/performance-toolkit/benchmark.jmx
@@ -2305,6 +2305,56 @@ vars.put("testLabel", "CatProdBrows");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -2343,6 +2393,56 @@ vars.put("testLabel", "CatProdBrows");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -2679,6 +2779,56 @@ vars.put("loadType", "Guest");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -2865,6 +3015,56 @@ vars.put("loadType", "Guest");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -3508,6 +3708,56 @@ vars.put("loadType", "Guest");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -3694,6 +3944,56 @@ vars.put("loadType", "Guest");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -4879,6 +5179,56 @@ vars.put("loadType", "Customer");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+
@@ -5065,6 +5415,56 @@ vars.put("loadType", "Customer");
2
+
+
+ product_id
+ .//input[@type="hidden" and @name="product"]/@value
+ false
+ true
+ false
+
+
+
+
+ ^\d+$
+
+ Assertion.response_data
+ false
+ 1
+ variable
+ product_id
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${base_path}review/product/listAjax/id/${product_id}/
+ GET
+ true
+ false
+ true
+ false
+ false
+
+
+
+
+
+ 200
+
+ Assertion.response_code
+ false
+ 2
+
+