Skip to content

286 Add product type sync#296

Merged
heshamMassoud merged 45 commits intomasterfrom
286-add-product-type-sync
Sep 4, 2018
Merged

286 Add product type sync#296
heshamMassoud merged 45 commits intomasterfrom
286-add-product-type-sync

Conversation

@jortizsao
Copy link
Copy Markdown
Contributor

@jortizsao jortizsao commented Aug 1, 2018

Summary

This PR adds the ProductTypeSync class which is responsible for creating the batches from the product type drafts, and sync them accordingly:

  • if it is a new product type draft, creates the product type in commercetools
  • if it is an existing product type, updates the product type with the data coming from the product type draft.

Description

  • ProductTypeSync
    • Add process method
    • Add process batch method
    • Add update existing product type method
    • Add create product type method
    • Update product type service
    • Add integration tests
    • Add documentation

Todo

  • Tests
    • Unit
    • Integration

@jortizsao jortizsao changed the title 286 add product type sync WIP 286 add product type sync Aug 1, 2018
@codecov-io
Copy link
Copy Markdown

codecov-io commented Aug 1, 2018

Codecov Report

Merging #296 into master will increase coverage by 0.18%.
The diff coverage is 95.62%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #296      +/-   ##
============================================
+ Coverage     96.29%   96.47%   +0.18%     
- Complexity     1066     1102      +36     
============================================
  Files           101      103       +2     
  Lines          2642     2722      +80     
  Branches        130      134       +4     
============================================
+ Hits           2544     2626      +82     
+ Misses           83       81       -2     
  Partials         15       15
Impacted Files Coverage Δ Complexity Δ
...ils/ProductTypeUpdateLocalizedEnumActionUtils.java 100% <ø> (ø) 4 <0> (ø) ⬇️
...ools/sync/producttypes/ProductTypeSyncOptions.java 100% <ø> (ø) 1 <0> (ø) ⬇️
...s/utils/ProductTypeUpdatePlainEnumActionUtils.java 100% <100%> (ø) 4 <0> (ø) ⬇️
.../sync/producttypes/utils/ProductTypeSyncUtils.java 100% <100%> (ø) 1 <1> (?)
...roducttypes/helpers/ProductTypeSyncStatistics.java 100% <100%> (ø) 2 <2> (?)
...oductTypeUpdateAttributeDefinitionActionUtils.java 100% <100%> (ø) 21 <8> (+4) ⬆️
...es/utils/AttributeDefinitionUpdateActionUtils.java 100% <100%> (ø) 17 <7> (-3) ⬇️
...roducttypes/utils/PlainEnumUpdateActionsUtils.java 100% <100%> (ø) 3 <1> (ø) ⬇️
...types/utils/ProductTypeUpdateEnumActionsUtils.java 100% <100%> (+6.25%) 18 <0> (ø) ⬇️
...ols/sync/services/impl/ProductTypeServiceImpl.java 77.77% <80.64%> (+4.8%) 16 <11> (+4) ⬆️
... and 4 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1c181f9...3b5b517. Read the comment docs.

* Add process method
* Add process batch method
* Add update existing product type method
* Add create product type method
* Update product type service
* Add integration tests
@jortizsao jortizsao force-pushed the 286-add-product-type-sync branch from a02e50a to b144368 Compare August 8, 2018 09:34
@jortizsao jortizsao changed the title WIP 286 add product type sync 286 Add product type sync Aug 8, 2018
…ew attribute

when the attributeDefinitions with the same name but of different types we shouldn't just throw an exception
but rather we should remove the old attributeDefinition and create a new one with the new type.
Copy link
Copy Markdown
Contributor

@heshamMassoud heshamMassoud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not done with the review 😉 but in general I see a lot of code not covered. Is this still coming?

Regardless, I will submit my review for now so I don't block you. Then I will submit another review.

import java.util.function.Function;

public final class ProductTypeSyncOptions extends BaseSyncOptions<ProductType, ProductTypeDraft> {
public class ProductTypeSyncOptions extends BaseSyncOptions<ProductType, ProductTypeDraft> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you remove the final?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly, I don't know... it's been a mistake

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


import static java.lang.String.format;

public class ProductTypeSyncStatistics extends BaseSyncStatistics {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no unit tests?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have private constructor for this class, since we only expect it to be instantiated through the builder. Also we should make it final. I know this is not the case for the other *Statistics classes, but maybe we should change that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have private constructor for this class, since we only expect it to be instantiated through the builder. Also we should make it final. I know this is not the case for the other *Statistics classes, but maybe we should change that.

Is there a builder for the *Statistics classes? or you mean that I have to develop one?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jortizsao

I created an integration test for that

I would say:

  1. We should cover as much of the code (as possible) with unit tests.
  2. a unit test is sufficient for the statistics since the integration tests have an overhead of the setting up/tearing down requests. So they are quite costly in the sense that they increase the time of the build significantly, etc..

see: https://martinfowler.com/bliki/TestPyramid.html

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a builder for the *Statistics classes? or you mean that I have to develop one?

Oh, my bad. I thought there is already one :( disregard the comment then. Just consider using final..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say:

We should cover as much of the code (as possible) with unit tests.
a unit test is sufficient for the statistics since the integration tests have an overhead of the setting up/tearing down requests. So they are quite costly in the sense that they increase the time of the build significantly, etc..

Yes, I'm familiar with the test pyramid and I love unit tests (I usually develop using TDD when possible) and I prefer them over integration tests.

For the ProductTypeSync class and related classes and methods (basically the ones I've added in this PR and that don't create update actions), I found complex to add unit tests to these classes due to coupling/architecture, so I decided to follow the same existing approach (cover those test cases with integration tests ).

In this case is true that is possible to add a unit test for the getReportMessage method but in order to avoid a single test class for this unit test, I thought that the integration test was enough.

Anyways, I add the unit test :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oldAttributeDefinition.getName(),
oldAttributeDefinition.getAttributeType().getClass().getName(),
newAttributeDefinitionDraft.getAttributeType().getClass().getName()));
updateActions = Stream
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about the case when the type of the attributeDefinition has changed?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I saw it down there. Please disregard this comment.

* result. If no update action is needed, for example in case where both the {@link ProductType} and the
* {@link ProductTypeDraft} have the same description, an empty {@link List} is returned.
*
* @param oldProductType the product which should be updated.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the product which should be updated. -> the {@link ProductType} which should be updated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* {@link ProductTypeDraft} have the same description, an empty {@link List} is returned.
*
* @param oldProductType the product which should be updated.
* @param newProductType the product draft where we get the new data.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the product draft where we get the new data. -> the {@link ProductTypeDraft} which should be updated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return new ArrayList<UpdateAction<ProductType>>();
}

})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general questions about this method: Why does it take already a map newAttributeDefinitionDraftsNameMap as a parameter and not a list? can't the map be already created inside of it as it's only needed by it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right! it was an old version that used a map. After a code review in the price sync we thought it was better to use a list because is less coupled and more close to the original parameters.

I change it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import io.sphere.sdk.commands.UpdateAction;
import io.sphere.sdk.products.attributes.AttributeDefinition;
import io.sphere.sdk.products.attributes.AttributeDefinitionBuilder;
import io.sphere.sdk.products.attributes.LocalizedStringAttributeType;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a type in the name of the package of this test class:
producttuypeactionutils -> producttypeactionutils ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


import javax.annotation.Nullable;

public class ProductTypeSyncStatisticsAssert extends
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great that you are creating your own statistics assertion 🎉

but maybe final 😊 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return CtpQueryUtils.queryAll(syncOptions.getCtpClient(), ProductTypeQuery.of(), productTypePageConsumer)
.thenAccept(result -> isCached = true)
.thenApply(result -> Optional.ofNullable(keyToIdCache.get(key)));
.thenAccept(result -> isCached = true)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:( indentation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.collect(
Collectors.toMap(AttributeMetaData::getName, attributeMetaData -> attributeMetaData));
.map(AttributeMetaData::of)
.collect(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:( indentation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jortizsao jortizsao force-pushed the 286-add-product-type-sync branch from 68641cc to f2e2841 Compare August 11, 2018 16:48
public class ProductTypeSyncIT {

/**
* Deletes inventories and supply channels from source and target CTP projects.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment doesn't reflect what is happening in the method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* injected {@link ProductTypeSyncOptions} instance.
*
* @param productTypeSyncOptions the container of all the options of the sync process including the CTP project
* client and/ormconfiguration and other sync-specific options.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and/or configuration

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the javadoc from the constructors and add it to the class, so this typo doesn't exist anymore.

/**
* Takes a {@link ProductTypeSyncOptions} instance to instantiate a new {@link ProductTypeSync} instance that
* could be used to sync product type drafts with the given product types in the CTP project specified in the
* injected {@link ProductTypeSyncOptions} instance.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite long sentence and not easy to read. Can you make it a bit clearer?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I would just describe what this class do instead of describing the constructors:

This class syncs product type drafts with the given product types in the CTP project.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

protected CompletionStage<ProductTypeSyncStatistics> process(
@Nonnull final List<ProductTypeDraft> productTypeDrafts) {

final List<List<ProductTypeDraft>> batches = batchElements(productTypeDrafts, syncOptions.getBatchSize());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about validate drafts here? If they're not valid, you don't have to process them further.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The invalid drafts count as a processed items in the statistics so they have to be "processed" (they are not actually processed, but the process method will consider them as a processed items)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is this:

final List<ProductTypeDraft> validProductTypeDrafts = productTypeDrafts.stream()
                                                                   .filter(this::validateDraft)
                                                                   .collect(toList());

        final List<List<ProductTypeDraft>> batches = batchElements(validProductTypeDrafts, syncOptions.getBatchSize());

and remove validateDraft part from processBatch() method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmm... but if I validate there, then the counter for "processed" items is not increased in processBatch because the invalid drafts are removed before and processBatch is responsible for increasing the counter of processed items in the statistics.

In the other synchronization of entities, the invalid drafts are considered as processed. Furthermore, in the processBatch the invalid drafts are filtered before processing, so it seems that there is no performance advantage of moving the filtering to the process.

Maybe I'm wrong, what do you think @heshamMassoud ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you are arguments are absolutely correct @jortizsao.

statistics.incrementProcessed(batch.size());
return completedFuture(statistics);
} else {
final Map<String, ProductTypeDraft> keysProductTypeDraftMap = getKeysProductTypeMap(validProductTypeDrafts);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need map? Is set of keys enough?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to reuse the existing method getKeysProductTypeMap, but I change it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.thenApply(Optional::of)
.exceptionally(exception -> {
final String errorMessage = format(CTP_PRODUCT_TYPE_FETCH_FAILED, keys);
handleError(errorMessage, exception, keys.size());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused with keys.size() - if you fail on 1 request, shouldn't you count as 1?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is when the request of a batch fails (i.e a batch of 50 product type keys), so if the request fails, it fails for the 50 product type keys, and the counter of failed items should be incremented by 50.

* {@link ProductTypeUpdateActionUtils#buildAttributesUpdateActions}) of a {@link ProductType} and a
* {@link ProductTypeDraft}. It returns a {@link List} of {@link UpdateAction}&lt;{@link ProductType}&gt; as a
* result. If no update action is needed, for example in case where both the {@link ProductType} and the
* {@link ProductTypeDraft} have the same description, an empty {@link List} is returned.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example in case where both the {@link ProductType} and the {@link ProductTypeDraft} have the same description - I thought this applies only when both product types are exactly the same?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the javadoc is confusing. It should say when all fields are the same. I change it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newAttributeDefinitionDraft.getAttributeType().getClass().getName()));
updateActions = Stream
.of(
buildChangeLabelUpdateAction(oldAttributeDefinition, newAttributeDefinitionDraft),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about changeAttributeName?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attribute name is the 'key' of the attribute (it's unique), so there can't be a changeAttributeName as update action.

A change in the attribute name will mean a deletion of the old attribute and the creation of the new attribute.

buildActions(oldAttributeDefinition, attributeDefinitionDraft)
)
.map(attributeDefinitionDraft -> {
// attribute type is required so if null we let commercetools to throw exception
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by this comment? In the line below you check for nullability anyway.

attributeDefinitionDraft.getAttributeType() != null

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment means that even knowing that the product type is invalid (because the attribute type is required for an attribute) we don't throw any exception.

We let commercetools to throw the exception. This is a decision we made because the commercetools documentation states that the attribute type is required, and we decided not throw library validations for those cases that are documented in commercetools.

In this case the validation is just for checking if there is attribute type to avoid a null pointer exception in the haveSameAttributeType.

public void getReportMessage_WithIncrementedStats_ShouldGetCorrectMessage() {
productTypeSyncStatistics.incrementCreated(1);
productTypeSyncStatistics.incrementFailed(1);
productTypeSyncStatistics.incrementUpdated(1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would give created=1, failed=2, updated=3 so you know that you didn't mix the variables.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@heshamMassoud heshamMassoud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With these comments I finalise my review on the PR. So It should be approved as soon as they are addressed ;) @jortizsao

import static com.commercetools.sync.integration.commons.utils.SphereClientUtils.CTP_SOURCE_CLIENT;
import static com.commercetools.sync.integration.commons.utils.SphereClientUtils.CTP_TARGET_CLIENT;

public class ProductTypeITUtils {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final and private empty constructor.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* injected {@link ProductTypeSyncOptions} instance.
*
* @param productTypeSyncOptions the container of all the options of the sync process including the CTP project
* client and/ormconfiguration and other sync-specific options.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and/or configuration

Copy link
Copy Markdown
Contributor Author

@jortizsao jortizsao Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment has been removed from the constructors and added it to the class as recommended by @lojzatran in his code review

* injected {@link ProductTypeSyncOptions} instance.
*
* @param productTypeSyncOptions the container of all the options of the sync process including the CTP project
* client and/ormconfiguration and other sync-specific options.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and/or configuration

Copy link
Copy Markdown
Contributor Author

@jortizsao jortizsao Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment has been removed from the constructors and added it to the class as recommended by @lojzatran in his code review


## Caveats

1. Product types are either created or updated. Currently the tool does not support product type deletion.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in your implementation of the product type sync, syncing product types with an attribute of type NestedType will not work as you will need to resolve the references on this product type. So I would add it as a Caveat that currently product type sync does not support product types with attributes of nested type yet.

Would be nice if we create an issue for it also, so we can address it in the future ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right. I add it. thanks!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread README.md
- [Categories](/docs/usage/CATEGORY_SYNC.md)
- [Products](/docs/usage/PRODUCT_SYNC.md) (_Beta_: Not recommended for production use yet.)
- [InventoryEntries](/docs/usage/INVENTORY_SYNC.md) (_Beta_: Not recommended for production use yet.)
- [ProductTypes](/docs/usage/PRODUCT_TYPE_SYNC.md) (_Beta_: Not recommended for production use yet.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason Products and InventoryEntries was marked as Beta, is because the Product Sync is still missing reference resolution of values of attributes with type referenceType and because Inventory Sync is not completely tested.

So I was wondering why the product type sync would still be marked with this note.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but now I see it makes sense because it's still missing support for NestedType attributes..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can keep it in beta or remove it (the ball is in your court xD). The Nestedtype is in Beta in commercetools, so keep the product type sync in Beta just for that reason maybe is not enough.

I put it in Beta because even after already tested it and so on... I thought it was wise to set it as Beta just for some time until we have confidence that it actually works as the customers expect.

WDYT?

Copy link
Copy Markdown
Contributor

@heshamMassoud heshamMassoud Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it in Beta because even after already tested it and so on... I thought it was wise to set it as Beta just for some time until we have confidence that it actually works as the customers expect.

I put it in Beta because even after already tested it and so on... I thought it was wise to set it as Beta just for some time until we have confidence that it actually works as the customers expect.


return fetchExistingProductTypes(keys)
.thenCompose(oldProductTypes -> syncBatch(oldProductTypes, validProductTypeDrafts))
.thenApply((ignored) -> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the parantheses around the ignored are not needed ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertThat(oldProductTypeAfter.get().getName()).isEqualTo(PRODUCT_TYPE_NAME_2);
assertThat(oldProductTypeAfter.get().getDescription()).isEqualTo(PRODUCT_TYPE_DESCRIPTION_2);
assertAttributesAreEqual(oldProductTypeAfter.get().getAttributes(),
singletonList(ATTRIBUTE_DEFINITION_DRAFT_1));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of those 4 asserts and checking that it is not empty explicitly and doing .get() after. You can do it like this:

assertThat(oldProductTypeAfter).hasValueSatisfying(productType -> {
            assertThat(productType.getName()).isEqualTo(PRODUCT_TYPE_NAME_2);
            assertThat(productType.getDescription()).isEqualTo(PRODUCT_TYPE_DESCRIPTION_2);
            assertAttributesAreEqual(productType.getAttributes(), singletonList(ATTRIBUTE_DEFINITION_DRAFT_1));
        });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use it across all asserts of this class actually ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

@Test
public void sync_beforeUpdate_ShouldCallBeforeUpdateCallback() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering why are these tests significant? Namely:

  • public void sync_beforeCreate_ShouldCallBeforeCreateCallback
  • public void sync_beforeCreate_ShouldNotCallBeforeUpdateCallback
  • public void sync_beforeUpdate_ShouldCallBeforeUpdateCallback
  • public void sync_beforeUpdate_ShouldNotCallBeforeCreateCallback

Copy link
Copy Markdown
Contributor Author

@jortizsao jortizsao Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically is to verify that the right callbacks are called in the correct actions.

i.e How would you verify that applyBeforeUpdateCallBack function is called when a product type is created?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but do you think we really need an integration test for that, isn't a unit test sufficient to test that behaviour?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jortizsao I created an issue for it #302 you can check it later. So we don't block the release ;)

"product_type_key_" + Integer.toString(i),
"product_type_name_" + Integer.toString(i),
"product_type_description_" + Integer.toString(i),
Arrays.asList(ATTRIBUTE_DEFINITION_DRAFT_1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use here instead: singletonList(ATTRIBUTE_DEFINITION_DRAFT_1)

Copy link
Copy Markdown
Contributor Author

@jortizsao jortizsao Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PRODUCT_TYPE_KEY_1,
PRODUCT_TYPE_NAME_1,
PRODUCT_TYPE_DESCRIPTION_1,
Arrays.asList(ATTRIBUTE_DEFINITION_DRAFT_1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

singletonList(ATTRIBUTE_DEFINITION_DRAFT_1)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heshamMassoud
Copy link
Copy Markdown
Contributor

heshamMassoud commented Sep 4, 2018

@jortizsao We are also missing benchmarks for the product Type Sync. I'll create it as an issue for now. #301

@heshamMassoud
Copy link
Copy Markdown
Contributor

release notes entries are also missing. I will add them.

.of(CTP_TARGET_CLIENT)
.build();

ProductTypeSyncOptions spyProductTypeSyncOptions = spy(productTypeSyncOptions);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also mentioned in the same issue: #302

@heshamMassoud heshamMassoud merged commit 4403280 into master Sep 4, 2018
@heshamMassoud heshamMassoud deleted the 286-add-product-type-sync branch September 4, 2018 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants