Fix OOTB integration test locale error

OOTB hybris ant modulegen generates accelerator with integration tests, which fails if default language of host operation system is not english.

CheckoutWithExternalTaxesIntegrationTest, DefaultSimpleSuggestionServiceIntegrationTest, DefaultSimpleSuggestionFacadeIntegrationTest tests will fail while impex import, with errors like:

1
2
3
4
5
6
7
 [yunitint] junit.framework.TestListener: addFailure(testReferencesForPurchasedInCategory, Import has 2+unresolved lines, first lines are:
 [yunitint] 
 [yunitint] INSERT_UPDATE OrderEntry;order(Order.code)[unique=true];creationTime[dateformat=yyyy-MM-dd HH:mm:ss];product(code,catalogversion(catalog(id[default='photoCatalog']),version[default='Online'])[unique=true,default='photoCatalog:Online'])[unique=true];quantity;unit(code)
 [yunitint] ,,,,Exception : line 81: cannot create OrderEntry with values ItemAttributeMap[ registry:  null, type: <null>, data: {product=Product 'camera1' (8796191358977), order=orderRefdejol(8796191359021), creationtime=Wed Apr 27 18:54:00 EEST 2011, quantity=1, unit=Unit 'pieces' type 'pieces' (8796191358986)} ] due to [de.hybris.platform.order.interceptors.DefaultAbstractOrderEntryPreparer@3e88bc58]: 
 unexpected preparer error: No matching DataLocale for ru_UA ( tried [ru_UA, ru] on available locales {de=de->de, en=en->en} ), 
 Exception : line 6: cannot create OrderEntry with values ItemAttributeMap[ registry:  null, type: <null>, data: {product=Product 'camera1' (8796191358977), order=orderRefdejol(8796191359021), creationtime=Wed Apr 27 18:54:00 EEST 2011, quantity=1, unit=Unit 'pieces' type 'pieces' (8796191358986)} ] due to [de.hybris.platform.order.interceptors.DefaultAbstractOrderEntryPreparer@3e88bc58]: unexpected preparer error: No matching DataLocale for ru_UA ( tried [ru_UA, ru] on available locales {de=de->de, en=en->en} ), Exception : line 3: cannot create OrderEntry with values ItemAttributeMap[ registry:  null, type: <null>, data: {product=Product 'camera1' (8796191358977), order=orderRefdejol(8796191359021), creationtime=Wed Apr 27 18:54:00 EEST 2011, quantity=1, unit=Unit 'pieces' type 'pieces' (8796191358986)} ] due to [de.hybris.platform.order.interceptors.DefaultAbstractOrderEntryPreparer@3e88bc58]: unexpected preparer error: No matching DataLocale for ru_UA ( tried [ru_UA, ru] on available locales {de=de->de, en=en->en} );orderRefdejol;2011-04-27 18:54:00;camera1;1;pieces
 [yunitint] )

The problem is that MasterTenant and SlaveTenant uses different approaches to set default locale. SlaveTenant gets locale from current operation system settings and MasterTenant uses Locale.getDefault() to get locale. There is no direct way to say SlaveTenant which language to use, the only available way is to use Reflection to put desired value. To resolve issue with default integration tests was created ServicelayerLocaleFreeTest interface.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.blog.core.servicelayer;

import de.hybris.platform.core.AbstractTenant;
import de.hybris.platform.core.Registry;
import de.hybris.platform.core.SlaveTenant;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Locale;

public interface ServicelayerLocaleFreeTest {

    default void changeJunitTenantDefaultLocale(Locale newLocale) throws NoSuchFieldException, IllegalAccessException {
        AbstractTenant tenant = Registry.getCurrentTenant();
        if (tenant instanceof SlaveTenant && tenant.getTenantID().equalsIgnoreCase("junit")) {
            // Change private modifier to public
            Field locale = tenant.getClass().getDeclaredField("locale");
            locale.setAccessible(true);
            // Remove final modifier
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(locale, locale.getModifiers() & ~Modifier.FINAL);
            // Set new field value
            locale.set(tenant, newLocale);
        }
    }

}

To fix OOTB integration tests just add to test ServicelayerLocaleFreeTest interface and in setUp() method change locale to english with method changeJunitTenantDefaultLocale(Locale.ENGLISH).

For example, DefaultSimpleSuggestionServiceIntegrationTest after changes will look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.blog.core.suggestion;

import com.blog.core.servicelayer.ServicelayerLocaleFreeTest;
import de.hybris.bootstrap.annotations.IntegrationTest;
import de.hybris.platform.catalog.enums.ProductReferenceTypeEnum;
import de.hybris.platform.category.CategoryService;
import de.hybris.platform.category.model.CategoryModel;
import de.hybris.platform.core.model.product.ProductModel;
import de.hybris.platform.core.model.user.UserModel;
import de.hybris.platform.servicelayer.ServicelayerTransactionalTest;
import de.hybris.platform.servicelayer.user.UserService;
import com.blog.core.suggestion.impl.DefaultSimpleSuggestionService;

import java.util.List;
import java.util.Locale;

import javax.annotation.Resource;

import junit.framework.Assert;

import org.apache.commons.lang.math.NumberUtils;
import org.junit.Before;
import org.junit.Test;


/**
 * Integration test suite for {@link DefaultSimpleSuggestionService}
 */
@IntegrationTest
public class DefaultSimpleSuggestionServiceIntegrationTest extends ServicelayerTransactionalTest implements ServicelayerLocaleFreeTest
{

	@Resource
	private SimpleSuggestionService simpleSuggestionService;

	@Resource
	private UserService userService;

	@Resource
	private CategoryService categoryService;

	@Before
	public void setUp() throws Exception
	{
        changeJunitTenantDefaultLocale(Locale.ENGLISH);
		importCsv("/blogcore/test/testSimpleSuggestionService.csv", "utf-8");
	}

	@Test
	public void testReferencesForPurchasedInCategory()
	{
		final UserModel user = userService.getUserForUID("dejol");
		final CategoryModel category = categoryService.getCategoryForCode("cameras");

		List<ProductModel> result = simpleSuggestionService.getReferencesForPurchasedInCategory(category, user, null, false, null);
		Assert.assertEquals(4, result.size());
		result = simpleSuggestionService.getReferencesForPurchasedInCategory(category, user, null, false, NumberUtils.INTEGER_ONE);
		Assert.assertEquals(1, result.size());
		result = simpleSuggestionService.getReferencesForPurchasedInCategory(category, user, ProductReferenceTypeEnum.SIMILAR,
				false, null);
		Assert.assertEquals(1, result.size());
		result = simpleSuggestionService.getReferencesForPurchasedInCategory(category, user, ProductReferenceTypeEnum.ACCESSORIES,
				false, null);
		Assert.assertEquals(2, result.size());
		result = simpleSuggestionService.getReferencesForPurchasedInCategory(category, user, ProductReferenceTypeEnum.ACCESSORIES,
				true, null);
		Assert.assertEquals(1, result.size());
		final ProductModel product = result.get(0);
		Assert.assertEquals("adapterDC", product.getCode());
		Assert.assertEquals("adapter", product.getName());
	}
}
comments powered by Disqus