helper = new ObjectManager($this);
$this->scope = $this->getMockBuilder(ScopeConfigInterface::class)
->disableOriginalConstructor()
->getMock();
$this->scope->method('getValue')
->willReturnCallback([$this, 'scopeConfigGetValue']);
$this->error = $this->getMockBuilder(Error::class)
->setMethods(['setCarrier', 'setCarrierTitle', 'setErrorMessage'])
->getMock();
$this->errorFactory = $this->getMockBuilder(ErrorFactory::class)
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
$this->errorFactory->method('create')
->willReturn($this->error);
$rateFactory = $this->getRateFactory();
$this->country = $this->getMockBuilder(Country::class)
->disableOriginalConstructor()
->setMethods(['load', 'getData'])
->getMock();
$this->abstractModel = $this->getMockBuilder(AbstractModel::class)
->disableOriginalConstructor()
->setMethods(['getData'])
->getMock();
$this->country->method('load')
->willReturn($this->abstractModel);
$this->countryFactory = $this->getMockBuilder(CountryFactory::class)
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
$this->countryFactory->method('create')
->willReturn($this->country);
$xmlFactory = $this->getXmlFactory();
$httpClientFactory = $this->getHttpClientFactory();
$this->logger = $this->getMockForAbstractClass(LoggerInterface::class);
$this->model = $this->helper->getObject(
Carrier::class,
[
'scopeConfig' => $this->scope,
'rateErrorFactory' => $this->errorFactory,
'countryFactory' => $this->countryFactory,
'rateFactory' => $rateFactory,
'xmlElFactory' => $xmlFactory,
'logger' => $this->logger,
'httpClientFactory' => $httpClientFactory,
]
);
}
/**
* Callback function, emulates getValue function.
*
* @param string $path
* @return null|string
*/
public function scopeConfigGetValue(string $path)
{
$pathMap = [
'carriers/ups/free_method' => 'free_method',
'carriers/ups/free_shipping_subtotal' => 5,
'carriers/ups/showmethod' => 1,
'carriers/ups/title' => 'ups Title',
'carriers/ups/specificerrmsg' => 'ups error message',
'carriers/ups/min_package_weight' => 2,
'carriers/ups/type' => 'UPS',
'carriers/ups/debug' => 1,
'carriers/ups/username' => 'user',
'carriers/ups/password' => 'pass',
'carriers/ups/access_license_number' => 'acn',
];
return isset($pathMap[$path]) ? $pathMap[$path] : null;
}
/**
* @dataProvider getMethodPriceProvider
* @param int $cost
* @param string $shippingMethod
* @param bool $freeShippingEnabled
* @param int $requestSubtotal
* @param int $expectedPrice
*/
public function testGetMethodPrice(
$cost,
$shippingMethod,
$freeShippingEnabled,
$requestSubtotal,
$expectedPrice
) {
$path = 'carriers/' . $this->model->getCarrierCode() . '/';
$this->scope->method('isSetFlag')
->with($path . 'free_shipping_enable')
->willReturn($freeShippingEnabled);
$request = new RateRequest();
$request->setBaseSubtotalInclTax($requestSubtotal);
$this->model->setRawRequest($request);
$price = $this->model->getMethodPrice($cost, $shippingMethod);
$this->assertEquals($expectedPrice, $price);
}
/**
* Data provider for testGenerate method
*
* @return array
*/
public function getMethodPriceProvider()
{
return [
[3, self::FREE_METHOD_NAME, true, 6, 0],
[3, self::FREE_METHOD_NAME, true, 4, 3],
[3, self::FREE_METHOD_NAME, false, 6, 3],
[3, self::FREE_METHOD_NAME, false, 4, 3],
[3, self::PAID_METHOD_NAME, true, 6, 3],
[3, self::PAID_METHOD_NAME, true, 4, 3],
[3, self::PAID_METHOD_NAME, false, 6, 3],
[3, self::PAID_METHOD_NAME, false, 4, 3],
[7, self::FREE_METHOD_NAME, true, 6, 0],
[7, self::FREE_METHOD_NAME, true, 4, 7],
[7, self::FREE_METHOD_NAME, false, 6, 7],
[7, self::FREE_METHOD_NAME, false, 4, 7],
[7, self::PAID_METHOD_NAME, true, 6, 7],
[7, self::PAID_METHOD_NAME, true, 4, 7],
[7, self::PAID_METHOD_NAME, false, 6, 7],
[7, self::PAID_METHOD_NAME, false, 4, 7],
[3, self::FREE_METHOD_NAME, true, 0, 3],
[3, self::FREE_METHOD_NAME, true, 0, 3],
[3, self::FREE_METHOD_NAME, false, 0, 3],
[3, self::FREE_METHOD_NAME, false, 0, 3],
[3, self::PAID_METHOD_NAME, true, 0, 3],
[3, self::PAID_METHOD_NAME, true, 0, 3],
[3, self::PAID_METHOD_NAME, false, 0, 3],
[3, self::PAID_METHOD_NAME, false, 0, 3]
];
}
public function testCollectRatesErrorMessage()
{
$this->scope->method('isSetFlag')
->willReturn(false);
$this->error->method('setCarrier')
->with('ups');
$this->error->method('setCarrierTitle');
$this->error->method('setErrorMessage');
$request = new RateRequest();
$request->setPackageWeight(1);
$this->assertSame($this->error, $this->model->collectRates($request));
}
public function testCollectRatesFail()
{
$this->scope->method('isSetFlag')
->willReturn(true);
$request = new RateRequest();
$request->setPackageWeight(1);
$this->assertSame($this->rate, $this->model->collectRates($request));
}
/**
* @param string $data
* @param array $maskFields
* @param string $expected
* @dataProvider logDataProvider
*/
public function testFilterDebugData($data, array $maskFields, $expected)
{
$refClass = new \ReflectionClass(Carrier::class);
$property = $refClass->getProperty('_debugReplacePrivateDataKeys');
$property->setAccessible(true);
$property->setValue($this->model, $maskFields);
$refMethod = $refClass->getMethod('filterDebugData');
$refMethod->setAccessible(true);
$result = $refMethod->invoke($this->model, $data);
$expectedXml = new \SimpleXMLElement($expected);
$resultXml = new \SimpleXMLElement($result);
$this->assertEquals($expectedXml->asXML(), $resultXml->asXML());
}
/**
* Get list of variations
*/
public function logDataProvider()
{
return [
[
'
42121
TestPassword
ALL
',
['UserId', 'Password'],
'
****
****
ALL
',
],
[
'
1231
ALL
',
['UserId'],
'
****
ALL
',
]
];
}
/**
* @param string $countryCode
* @param string $foundCountryCode
* @dataProvider countryDataProvider
*/
public function testSetRequest($countryCode, $foundCountryCode)
{
/** @var RateRequest $request */
$request = $this->helper->getObject(RateRequest::class);
$request->setData([
'orig_country' => 'USA',
'orig_region_code' => 'CA',
'orig_post_code' => 90230,
'orig_city' => 'Culver City',
'dest_country_id' => $countryCode,
]);
$this->country->expects($this->at(1))
->method('load')
->with($countryCode)
->willReturnSelf();
$this->country->method('getData')
->with('iso2_code')
->willReturn($foundCountryCode);
$this->model->setRequest($request);
}
/**
* Get list of country variations
* @return array
*/
public function countryDataProvider()
{
return [
['countryCode' => 'PR', 'foundCountryCode' => null],
['countryCode' => 'US', 'foundCountryCode' => 'US'],
];
}
/**
* Checks a case when UPS processes request to create shipment.
*
* @return void
*/
public function testRequestToShipment()
{
// the same tracking number is specified in the fixtures XML file.
$trackingNumber = '1Z207W886698856557';
$packages = $this->getPackages();
$request = new DataObject(['packages' => $packages]);
$shipmentResponse = simplexml_load_file(__DIR__ . '/../Fixtures/ShipmentConfirmResponse.xml');
$acceptResponse = simplexml_load_file(__DIR__ . '/../Fixtures/ShipmentAcceptResponse.xml');
$this->httpClient->method('getBody')
->willReturnOnConsecutiveCalls($shipmentResponse->asXML(), $acceptResponse->asXML());
$this->logger->expects($this->atLeastOnce())
->method('debug')
->with($this->stringContains('****'));
$result = $this->model->requestToShipment($request);
$this->assertEmpty($result->getErrors());
$info = $result->getInfo()[0];
$this->assertEquals($trackingNumber, $info['tracking_number'], 'Tracking Number must match.');
}
/**
* Creates mock for XML factory.
*
* @return ElementFactory|MockObject
*/
private function getXmlFactory(): MockObject
{
$xmlElFactory = $this->getMockBuilder(ElementFactory::class)
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
$xmlElFactory->method('create')
->willReturnCallback(
function ($data) {
$helper = new ObjectManager($this);
return $helper->getObject(
Element::class,
['data' => $data['data']]
);
}
);
return $xmlElFactory;
}
/**
* @return array
*/
private function getPackages(): array
{
$packages = [
'package' => [
'params' => [
'width' => '3',
'length' => '3',
'height' => '3',
'dimension_units' => 'INCH',
'weight_units' => 'POUND',
'weight' => '0.454000000001',
'customs_value' => '10.00',
'container' => 'Small Express Box',
],
'items' => [
'item1' => [
'name' => 'item_name',
],
],
],
];
return $packages;
}
/**
* Creates mocks for http client factory and client.
*
* @return ClientFactory|MockObject
*/
private function getHttpClientFactory(): MockObject
{
$httpClientFactory = $this->getMockBuilder(ClientFactory::class)
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
$this->httpClient = $this->getMockForAbstractClass(ClientInterface::class);
$httpClientFactory->method('create')
->willReturn($this->httpClient);
return $httpClientFactory;
}
/**
* @return MockObject
*/
private function getRateFactory(): MockObject
{
$this->rate = $this->createPartialMock(Result::class, ['getError']);
$rateFactory = $this->createPartialMock(ResultFactory::class, ['create']);
$rateFactory->method('create')
->willReturn($this->rate);
return $rateFactory;
}
}