Beispiel #1
0
    def test_concurrent_import_lock(self):
        """ A 2nd concurrent transaction must retry """
        # the lock is based on a string, a second transaction trying
        # to acquire the same lock won't be able to acquire it
        lock = 'import_record({}, {}, {}, {})'.format(
            'backend.name',
            1,
            'res.partner',
            '999999',
        )

        backend = mock.MagicMock()
        backend.env = self.env
        work = WorkContext(model_name='res.partner',
                           collection=backend)
        # we test the function through a Component instance
        component = work.component_by_name('base.connector')
        # acquire the lock
        component.advisory_lock_or_retry(lock)

        # instanciate another component using a different odoo env
        # hence another PG transaction
        backend2 = mock.MagicMock()
        backend2.env = self.env2
        work2 = WorkContext(model_name='res.partner',
                            collection=backend2)
        component2 = work2.component_by_name('base.connector')
        with self.assertRaises(RetryableJobError) as cm:
            component2.advisory_lock_or_retry(lock, retry_seconds=3)
            self.assertEqual(cm.exception.seconds, 3)
Beispiel #2
0
    def test_lock(self):
        """Lock a record"""
        main_partner = self.env.ref('base.main_partner')
        work = WorkContext(model_name='res.partner', collection=self.backend)
        locker = work.component_by_name('infor.record.locker')
        locker.lock(main_partner)

        main_partner2 = self.env2.ref('base.main_partner')
        work2 = WorkContext(model_name='res.partner', collection=self.backend2)
        locker2 = work2.component_by_name('infor.record.locker')
        with self.assertRaises(RetryableJobError):
            locker2.lock(main_partner2)
 def _get_provider(self, provider_name=None):
     if not provider_name:
         if self:
             provider_name = self.payment_mode_id.provider
         else:
             raise UserError(_('Provider name is missing'))
     work = WorkContext(model_name=self._name, collection=self)
     yield work.component_by_name('payment.service.%s' % provider_name)
Beispiel #4
0
    def test_concurrent_import(self):
        api_client = mock.MagicMock(name='Magento API')
        api_client.call.return_value = {
            'name': 'Root',
            'description': '',
            'level': '1',
        }
        work = WorkContext(model_name='magento.product.category',
                           collection=self.backend,
                           magento_api=api_client)
        importer = work.component_by_name('magento.product.category.importer')
        importer.run(1)

        work2 = WorkContext(model_name='magento.product.category',
                            collection=self.backend2,
                            magento_api=api_client)
        importer2 = work2.component_by_name(
            'magento.product.category.importer')
        with self.assertRaises(RetryableJobError):
            importer2.run(1)
class TestImportProductImage(TransactionComponentRegistryCase):
    """ Test the imports of the image of the products. """
    def setUp(self):
        super(TestImportProductImage, self).setUp()
        self.backend_model = self.env['magento.backend']
        warehouse = self.env.ref('stock.warehouse0')
        self.backend = self.backend_model.create({
            'name': 'Test Magento',
            'version': '1.7',
            'location': 'http://magento',
            'username': '******',
            'warehouse_id': warehouse.id,
            'password': '******'
        })

        category_model = self.env['product.category']
        existing_category = category_model.create({'name': 'all'})
        self.create_binding_no_export('magento.product.category',
                                      existing_category, 1)
        self.product_model = self.env['magento.product.product']

        # Use a stub for the product adapter, which is called
        # during the tests by the image importer
        class StubProductAdapter(Component):
            _name = 'stub.product.adapter'
            _collection = 'magento.backend'
            _usage = 'backend.adapter'
            _apply_on = 'magento.product.product'

            def get_images(self, external_id, storeview_id=None, data=None):
                return [
                    {
                        'exclude':
                        '1',
                        'file':
                        '/i/n/ink-eater-krylon-bombear-destroyed-tee-2.jpg',  # noqa
                        'label':
                        '',
                        'position':
                        '0',
                        'types': ['thumbnail'],
                        'url':
                        'http://localhost:9100/media/catalog/product/i/n/ink-eater-krylon-bombear-destroyed-tee-2.jpg'
                    },  # noqa
                    {
                        'exclude':
                        '0',
                        'file':
                        '/i/n/ink-eater-krylon-bombear-destroyed-tee-1.jpg',  # noqa
                        'label':
                        '',
                        'position':
                        '3',
                        'types': ['small_image'],
                        'url':
                        'http://localhost:9100/media/catalog/product/i/n/ink-eater-krylon-bombear-destroyed-tee-1.jpg'
                    },  # noqa
                    {
                        'exclude':
                        '0',
                        'file':
                        '/m/a/connector_magento_1.png',
                        'label':
                        '',
                        'position':
                        '4',
                        'types': [],
                        'url':
                        'http://localhost:9100/media/catalog/product/m/a/connector_magento_1.png'
                    },  # noqa
                ]

        # build the Stub and the component we want to test
        self._build_components(StubProductAdapter,
                               components.core.BaseMagentoConnectorComponent,
                               components.importer.MagentoImporter,
                               CatalogImageImporter)
        self.work = WorkContext(model_name='magento.product.product',
                                collection=self.backend,
                                components_registry=self.comp_registry)
        self.image_importer = self.work.component_by_name(
            'magento.product.image.importer')

    def create_binding_no_export(self,
                                 model_name,
                                 odoo_id,
                                 external_id=None,
                                 **cols):
        if isinstance(odoo_id, models.BaseModel):
            odoo_id = odoo_id.id
        values = {
            'backend_id': self.backend.id,
            'odoo_id': odoo_id,
            'external_id': external_id,
        }
        if cols:
            values.update(cols)
        return self.env[model_name].with_context(
            connector_no_export=True).create(values)

    def test_image_priority(self):
        """ Check if the images are sorted in the correct priority """
        file1 = {'file': 'file1', 'types': ['image'], 'position': '10'}
        file2 = {'file': 'file2', 'types': ['thumbnail'], 'position': '3'}
        file3 = {'file': 'file3', 'types': ['thumbnail'], 'position': '4'}
        file4 = {'file': 'file4', 'types': [], 'position': '10'}
        images = [file2, file1, file4, file3]
        self.assertEqual(self.image_importer._sort_images(images),
                         [file4, file3, file2, file1])

    def test_import_images_404(self):
        """ An image responds a 404 error, skip and take the first valid """
        url_tee1 = ('http://localhost:9100/media/catalog/product'
                    '/i/n/ink-eater-krylon-bombear-destroyed-tee-1.jpg')
        url_tee2 = ('http://localhost:9100/media/catalog/product/'
                    'i/n/ink-eater-krylon-bombear-destroyed-tee-2.jpg')

        binding = mock.Mock(name='magento.product.product,999')
        binding.id = 999
        binding_no_export = mock.MagicMock(
            name='magento.product.product,999:no_export')
        binding.with_context.return_value = binding_no_export

        with mock.patch('requests.get') as requests_get:

            def image_url_response(url, headers=None, verify=None):
                if url in (url_tee1, url_tee2):
                    return MockResponseImage('', code=404)
                else:
                    return MockResponseImage(PNG_IMG_4PX_GREEN)

            requests_get.side_effect = image_url_response

            self.image_importer.run(111, binding)

        binding.with_context.assert_called_with(connector_no_export=True)
        binding_no_export.write.assert_called_with(
            {'image': B64_PNG_IMG_4PX_GREEN})

    def test_import_images_403(self):
        """ Import a product when an image respond a 403 error, should fail """

        binding = mock.Mock(name='magento.product.product,999')
        binding.id = 999

        url_tee1 = ('http://localhost:9100/media/catalog/product'
                    '/i/n/ink-eater-krylon-bombear-destroyed-tee-1.jpg')
        url_tee2 = ('http://localhost:9100/media/catalog/product/'
                    'i/n/ink-eater-krylon-bombear-destroyed-tee-2.jpg')
        with mock.patch('requests.get') as requests_get:

            def image_url_response(url, headers=None, verify=None):
                if url == url_tee2:
                    raise urllib.error.HTTPError(url, 404, '404', None, None)
                elif url == url_tee1:
                    raise urllib.error.HTTPError(url, 403, '403', None, None)
                return MockResponseImage(PNG_IMG_4PX_GREEN)

            requests_get.side_effect = image_url_response
            with self.assertRaises(urllib.error.HTTPError):
                self.image_importer.run(122, binding)
Beispiel #6
0
 def get_provider(self):
     self.ensure_one()
     work = WorkContext(model_name=self._name, collection=self)
     return work.component_by_name("payment.service.%s" % self.provider)