/**
  * @expectedException \Magento\Framework\Exception\InputException
  * @expectedExceptionMessage regionId is a required field.
  */
 public function testSaveWithInvalidRegionId()
 {
     $customerId = 34;
     $addressId = 53;
     $customerAddress = $this->getMockForAbstractClass('Magento\\Customer\\Api\\Data\\AddressInterface', [], '', false);
     $customerAddress->expects($this->atLeastOnce())->method('getCustomerId')->willReturn($customerId);
     $customerAddress->expects($this->atLeastOnce())->method('getId')->willReturn($addressId);
     $this->customerRegistry->expects($this->once())->method('retrieve')->with($customerId)->willReturn($this->customer);
     $this->addressRegistry->expects($this->once())->method('retrieve')->with($addressId)->willReturn($this->address);
     $this->address->expects($this->once())->method('updateData')->with($customerAddress);
     $countryModel = $this->getMock('Magento\\Directory\\Model\\Country', [], [], '', false);
     $regionCollection = $this->getMock('Magento\\Directory\\Model\\ResourceModel\\Region\\Collection', [], [], '', false);
     $this->address->expects($this->once())->method('getShouldIgnoreValidation')->willReturn(false);
     $this->address->expects($this->atLeastOnce())->method('getCountryId')->willReturn(1);
     $this->address->expects($this->once())->method('getFirstname')->willReturn('firstname');
     $this->address->expects($this->once())->method('getLastname')->willReturn('lastname');
     $this->address->expects($this->once())->method('getStreetLine')->with(1)->willReturn('street line');
     $this->address->expects($this->once())->method('getCity')->willReturn('city');
     $this->address->expects($this->once())->method('getTelephone')->willReturn('23423423423');
     $this->address->expects($this->once())->method('getRegionId')->willReturn(2);
     $this->directoryData->expects($this->once())->method('getCountriesWithOptionalZip')->willReturn([1]);
     $this->address->expects($this->once())->method('getCountryModel')->willReturn($countryModel);
     $countryModel->expects($this->once())->method('getRegionCollection')->willReturn($regionCollection);
     $regionCollection->expects($this->atLeastOnce())->method('count')->willReturn(2);
     $regionCollection->expects($this->once())->method('getData')->willReturn([5, 6, 7, 8, 9]);
     $this->directoryData->expects($this->once())->method('isRegionRequired')->with(1)->willReturn(true);
     $this->address->expects($this->never())->method('getRegion')->willReturn('');
     $this->repository->save($customerAddress);
 }
 /**
  * @expectedException \Magento\Framework\Exception\InputException
  */
 public function testSaveWithException()
 {
     $customerId = 34;
     $addressId = 53;
     $customerAddress = $this->getMockForAbstractClass('Magento\\Customer\\Api\\Data\\AddressInterface', [], '', false);
     $customerAddress->expects($this->atLeastOnce())->method('getCustomerId')->willReturn($customerId);
     $customerAddress->expects($this->atLeastOnce())->method('getId')->willReturn($addressId);
     $this->customerRegistry->expects($this->once())->method('retrieve')->with($customerId)->willReturn($this->customer);
     $this->addressRegistry->expects($this->once())->method('retrieve')->with($addressId)->willReturn($this->address);
     $this->address->expects($this->once())->method('updateData')->with($customerAddress);
     $this->prepareMocksForInvalidAddressValidation();
     $this->repository->save($customerAddress);
 }
 /**
  * {@inheritdoc}
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash = null)
 {
     $this->validate($customer);
     $prevCustomerData = null;
     if ($customer->getId()) {
         $prevCustomerData = $this->getById($customer->getId());
     }
     $customer = $this->imageProcessor->save($customer, CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, $prevCustomerData);
     $origAddresses = $customer->getAddresses();
     $customer->setAddresses([]);
     $customerData = $this->extensibleDataObjectConverter->toNestedArray($customer, [], '\\Magento\\Customer\\Api\\Data\\CustomerInterface');
     $customer->setAddresses($origAddresses);
     $customerModel = $this->customerFactory->create(['data' => $customerData]);
     $storeId = $customerModel->getStoreId();
     if ($storeId === null) {
         $customerModel->setStoreId($this->storeManager->getStore()->getId());
     }
     $customerModel->setId($customer->getId());
     // Need to use attribute set or future updates can cause data loss
     if (!$customerModel->getAttributeSetId()) {
         $customerModel->setAttributeSetId(\Magento\Customer\Api\CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER);
     }
     // Populate model with secure data
     if ($customer->getId()) {
         $customerSecure = $this->customerRegistry->retrieveSecureData($customer->getId());
         $customerModel->setRpToken($customerSecure->getRpToken());
         $customerModel->setRpTokenCreatedAt($customerSecure->getRpTokenCreatedAt());
         $customerModel->setPasswordHash($customerSecure->getPasswordHash());
     } else {
         if ($passwordHash) {
             $customerModel->setPasswordHash($passwordHash);
         }
     }
     // If customer email was changed, reset RpToken info
     if ($prevCustomerData && $prevCustomerData->getEmail() !== $customerModel->getEmail()) {
         $customerModel->setRpToken(null);
         $customerModel->setRpTokenCreatedAt(null);
     }
     $this->customerResourceModel->save($customerModel);
     $this->customerRegistry->push($customerModel);
     $customerId = $customerModel->getId();
     if ($customer->getAddresses() !== null) {
         if ($customer->getId()) {
             $existingAddresses = $this->getById($customer->getId())->getAddresses();
             $getIdFunc = function ($address) {
                 return $address->getId();
             };
             $existingAddressIds = array_map($getIdFunc, $existingAddresses);
         } else {
             $existingAddressIds = [];
         }
         $savedAddressIds = [];
         foreach ($customer->getAddresses() as $address) {
             $address->setCustomerId($customerId)->setRegion($address->getRegion());
             $this->addressRepository->save($address);
             if ($address->getId()) {
                 $savedAddressIds[] = $address->getId();
             }
         }
         $addressIdsToDelete = array_diff($existingAddressIds, $savedAddressIds);
         foreach ($addressIdsToDelete as $addressId) {
             $this->addressRepository->deleteById($addressId);
         }
     }
     $savedCustomer = $this->get($customer->getEmail(), $customer->getWebsiteId());
     $this->eventManager->dispatch('customer_save_after_data_object', ['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $customer]);
     return $savedCustomer;
 }