1- package com .commercetools .sync .integration . externalsource . products ;
1+ package com .commercetools .sync .products . templates . beforeupdatecallback ;
22
3- import com .commercetools .sync .commons .utils .TriFunction ;
43import com .commercetools .sync .products .ProductSync ;
54import com .commercetools .sync .products .ProductSyncOptions ;
65import com .commercetools .sync .products .ProductSyncOptionsBuilder ;
7- import com .commercetools .sync .products .helpers .ProductSyncStatistics ;
8- import io .sphere .sdk .categories .Category ;
6+ import io .sphere .sdk .client .SphereClient ;
97import io .sphere .sdk .commands .UpdateAction ;
108import io .sphere .sdk .models .LocalizedString ;
119import io .sphere .sdk .models .LocalizedStringEntry ;
12- import io .sphere .sdk .models .Reference ;
1310import io .sphere .sdk .products .Product ;
1411import io .sphere .sdk .products .ProductData ;
1512import io .sphere .sdk .products .ProductDraft ;
16- import io .sphere .sdk .products .commands .ProductCreateCommand ;
1713import io .sphere .sdk .products .commands .updateactions .ChangeName ;
1814import io .sphere .sdk .products .commands .updateactions .ChangeSlug ;
1915import io .sphere .sdk .products .commands .updateactions .SetDescription ;
2016import io .sphere .sdk .products .commands .updateactions .SetMetaDescription ;
2117import io .sphere .sdk .products .commands .updateactions .SetMetaKeywords ;
2218import io .sphere .sdk .products .commands .updateactions .SetMetaTitle ;
2319import io .sphere .sdk .producttypes .ProductType ;
24- import org .junit .AfterClass ;
25- import org .junit .Before ;
26- import org .junit .BeforeClass ;
27- import org .junit .Test ;
20+ import org .slf4j .Logger ;
2821
2922import javax .annotation .Nonnull ;
30- import java .util .ArrayList ;
3123import java .util .List ;
3224import java .util .Locale ;
3325import java .util .Objects ;
3426import java .util .Optional ;
35- import java .util .function .BiConsumer ;
36- import java .util .function .Consumer ;
3727import java .util .function .Function ;
3828
39- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .OLD_CATEGORY_CUSTOM_TYPE_KEY ;
40- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .OLD_CATEGORY_CUSTOM_TYPE_NAME ;
41- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .createCategories ;
42- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .createCategoriesCustomType ;
43- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .getCategoryDrafts ;
44- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .getReferencesWithIds ;
45- import static com .commercetools .sync .integration .commons .utils .CategoryITUtils .getReferencesWithKeys ;
46- import static com .commercetools .sync .integration .commons .utils .ProductITUtils .deleteAllProducts ;
47- import static com .commercetools .sync .integration .commons .utils .ProductITUtils .deleteProductSyncTestData ;
48- import static com .commercetools .sync .integration .commons .utils .ProductTypeITUtils .createProductType ;
49- import static com .commercetools .sync .integration .commons .utils .SphereClientUtils .CTP_TARGET_CLIENT ;
50- import static com .commercetools .sync .products .ProductSyncMockUtils .PRODUCT_KEY_1_FRENCH_LOCALIZATIONS_PATH ;
51- import static com .commercetools .sync .products .ProductSyncMockUtils .PRODUCT_KEY_1_RESOURCE_PATH ;
52- import static com .commercetools .sync .products .ProductSyncMockUtils .PRODUCT_TYPE_RESOURCE_PATH ;
53- import static com .commercetools .sync .products .ProductSyncMockUtils .createProductDraft ;
54- import static com .commercetools .sync .products .ProductSyncMockUtils .createRandomCategoryOrderHints ;
55- import static com .commercetools .tests .utils .CompletionStageUtil .executeBlocking ;
56- import static io .sphere .sdk .producttypes .ProductType .referenceOfId ;
57- import static java .util .Collections .singletonList ;
5829import static java .util .stream .Collectors .toList ;
5930import static java .util .stream .Collectors .toMap ;
60- import static org .assertj .core .api .Assertions .assertThat ;
6131
62- public class ProductSyncSingleLocalizationIT {
63- private static ProductType productType ;
64- private static List <Reference <Category >> categoryReferencesWithIds ;
65- private static List <Reference <Category >> categoryReferencesWithKeys ;
66- private ProductSyncOptionsBuilder syncOptionsBuilder ;
67- private List <String > errorCallBackMessages ;
68- private List <String > warningCallBackMessages ;
69- private List <Throwable > errorCallBackExceptions ;
70- private static List <UpdateAction <Product >> updateActionsFromSync ;
32+ final class SyncSingleLocale {
7133
72- /**
73- * Delete all product related test data from target project. Then create custom types for the categories and a
74- * productType for the products of the target CTP project.
75- */
76- @ BeforeClass
77- public static void setupAllTests () {
78- deleteProductSyncTestData (CTP_TARGET_CLIENT );
79- createCategoriesCustomType (OLD_CATEGORY_CUSTOM_TYPE_KEY , Locale .ENGLISH ,
80- OLD_CATEGORY_CUSTOM_TYPE_NAME , CTP_TARGET_CLIENT );
81- final List <Category > categories = createCategories (CTP_TARGET_CLIENT , getCategoryDrafts (null , 2 ));
82- categoryReferencesWithIds = getReferencesWithIds (categories );
83- categoryReferencesWithKeys = getReferencesWithKeys (categories );
84- productType = createProductType (PRODUCT_TYPE_RESOURCE_PATH , CTP_TARGET_CLIENT );
85- }
86-
87- /**
88- * 1. Deletes all products from target CTP project
89- * 2. Clears all sync collections used for test assertions.
90- * 3. Creates an instance for {@link ProductSyncOptionsBuilder} that will be used in the tests to build
91- * {@link ProductSyncOptions} instances.
92- * 4. Create a product in the target CTP project.
93- */
94- @ Before
95- public void setupPerTest () {
96- clearSyncTestCollections ();
97- deleteAllProducts (CTP_TARGET_CLIENT );
98- syncOptionsBuilder = getProductSyncOptionsBuilder ();
99- final ProductDraft productDraft = createProductDraft (PRODUCT_KEY_1_RESOURCE_PATH , productType .toReference (),
100- null , null , categoryReferencesWithIds , createRandomCategoryOrderHints (categoryReferencesWithIds ));
101- executeBlocking (CTP_TARGET_CLIENT .execute (ProductCreateCommand .of (productDraft )));
102- }
103-
104- private void clearSyncTestCollections () {
105- updateActionsFromSync = new ArrayList <>();
106- errorCallBackMessages = new ArrayList <>();
107- errorCallBackExceptions = new ArrayList <>();
108- warningCallBackMessages = new ArrayList <>();
109- }
110-
111- private ProductSyncOptionsBuilder getProductSyncOptionsBuilder () {
112- final BiConsumer <String , Throwable > errorCallBack = (errorMessage , exception ) -> {
113- errorCallBackMessages .add (errorMessage );
114- errorCallBackExceptions .add (exception );
115- };
116-
117- final Consumer <String > warningCallBack = warningMessage -> warningCallBackMessages .add (warningMessage );
118-
119- final TriFunction <List <UpdateAction <Product >>, ProductDraft , Product , List <UpdateAction <Product >>>
120- actionsCallBack = (updateActions , newDraft , oldProduct ) -> {
121- updateActionsFromSync .addAll (updateActions );
122- return updateActions ;
123- };
124-
125- return ProductSyncOptionsBuilder .of (CTP_TARGET_CLIENT )
126- .errorCallback (errorCallBack )
127- .warningCallback (warningCallBack )
128- .beforeUpdateCallback (actionsCallBack );
129- }
130-
131- @ AfterClass
132- public static void tearDown () {
133- deleteProductSyncTestData (CTP_TARGET_CLIENT );
134- }
135-
136- @ Test
137- public void sync_withFrenchLocalizationsFilter_shouldOnlySyncFrenchData () {
138- final ProductDraft productDraft =
139- createProductDraft (PRODUCT_KEY_1_FRENCH_LOCALIZATIONS_PATH , referenceOfId (productType .getKey ()), null ,
140- null , categoryReferencesWithKeys , createRandomCategoryOrderHints (categoryReferencesWithKeys ));
141-
142- final ProductSyncOptions syncOptions = syncOptionsBuilder
143- .beforeUpdateCallback (ProductSyncSingleLocalizationIT ::syncFrenchDataOnly )
144- .build ();
34+ private static void sync (@ Nonnull final SphereClient ctpClient ,
35+ @ Nonnull final Logger logger ,
36+ @ Nonnull final List <ProductDraft > newProductDrafts ) {
37+ final ProductSyncOptions syncOptions =
38+ ProductSyncOptionsBuilder .of (ctpClient )
39+ .errorCallback (logger ::error )
40+ .warningCallback (logger ::warn )
41+ .beforeUpdateCallback (SyncSingleLocale ::syncFrenchDataOnly )
42+ .build ();
14543
14644 final ProductSync productSync = new ProductSync (syncOptions );
147- final ProductSyncStatistics syncStatistics = executeBlocking (productSync .sync (singletonList (productDraft )));
148-
149- assertThat (syncStatistics .getProcessed ()).isEqualTo (1 );
150- assertThat (syncStatistics .getCreated ()).isEqualTo (0 );
151- assertThat (syncStatistics .getUpdated ()).isEqualTo (1 );
152- assertThat (syncStatistics .getFailed ()).isEqualTo (0 );
153- assertThat (updateActionsFromSync .stream ()
154- .filter (updateAction -> updateAction instanceof ChangeName )
155- .findFirst ()
156- .map (changeNameUpdateAction -> ((ChangeName )changeNameUpdateAction ).getName ()))
157- .contains (LocalizedString .of (Locale .ENGLISH , "english name" , Locale .FRENCH , "french name" ));
158-
159- assertThat (updateActionsFromSync .stream ()
160- .filter (updateAction -> updateAction instanceof SetDescription )
161- .findFirst ()
162- .map (setDescriptionAction -> ((SetDescription )setDescriptionAction )
163- .getDescription ()))
164- .contains (LocalizedString .of (Locale .ENGLISH , "english description." , Locale .FRENCH , "french description." ));
165-
166- assertThat (updateActionsFromSync .stream ()
167- .filter (updateAction -> updateAction instanceof ChangeSlug )
168- .findFirst ()
169- .map (changeSlugAction -> ((ChangeSlug )changeSlugAction ).getSlug ()))
170- .contains (LocalizedString .of (Locale .ENGLISH , "english-slug" , Locale .FRENCH , "french-slug" ));
171- assertThat (errorCallBackExceptions ).isEmpty ();
172- assertThat (errorCallBackMessages ).isEmpty ();
173- assertThat (warningCallBackMessages ).isEmpty ();
45+ productSync .sync (newProductDrafts ).toCompletableFuture ().join ();
17446 }
17547
176-
17748 /**
17849 * Takes in a {@link List} of product update actions that was built from comparing a {@code newDraft} and an
17950 * {@code oldProduct} and maps the update actions so that only localizations with value {@link Locale#FRENCH}
@@ -188,14 +59,14 @@ private static List<UpdateAction<Product>> syncFrenchDataOnly(
18859 @ Nonnull final List <UpdateAction <Product >> updateActions ,
18960 @ Nonnull final ProductDraft newDraft ,
19061 @ Nonnull final Product oldProduct ) {
191- final List < UpdateAction < Product >> filteredActions = updateActions . stream ()
192- . map ( action -> filterSingleLocalization ( action ,
193- newDraft , oldProduct , Locale . FRENCH ) )
194- . filter ( Optional :: isPresent )
195- . map ( Optional :: get )
196- . collect ( toList ());
197- updateActionsFromSync . addAll ( filteredActions );
198- return filteredActions ;
62+ final ProductType productType = oldProduct . getProductType (). getObj ();
63+ assert productType != null ;
64+ return updateActions . stream ( )
65+ . map ( action ->
66+ filterSingleLocalization ( action , newDraft , oldProduct , productType , Locale . FRENCH ) )
67+ . filter ( Optional :: isPresent )
68+ . map ( Optional :: get )
69+ . collect ( toList ()) ;
19970 }
20071
20172 /**
@@ -226,6 +97,8 @@ private static Optional<UpdateAction<Product>> filterSingleLocalization(
22697 @ Nonnull final UpdateAction <Product > updateAction ,
22798 @ Nonnull final ProductDraft newDraft ,
22899 @ Nonnull final Product oldProduct ,
100+ @ Nonnull final ProductType productType ,
101+ //TODO: RIGHT NOW NOT USED BUT WILL BE EXTENDED LATER WITH USAGE AND TESTS. GITHUB ISSUE #189
229102 @ Nonnull final Locale locale ) {
230103 if (updateAction instanceof ChangeName ) {
231104 return filterLocalizedField (newDraft , oldProduct , locale , ProductDraft ::getName , ProductData ::getName ,
0 commit comments