Merge pull request #7348 from medusajs/fix/2152

Fix issue related to removing last product from the collection
This commit is contained in:
Harminder Virk
2024-05-17 15:47:37 +05:30
committed by GitHub
4 changed files with 110 additions and 22 deletions
@@ -248,7 +248,9 @@ export function internalModuleServiceFactory<
if (input_.selector) { if (input_.selector) {
const entitiesToUpdate = await this.list( const entitiesToUpdate = await this.list(
input_.selector, input_.selector,
{}, {
take: null,
},
sharedContext sharedContext
) )
// Create a pair of entity and data to update // Create a pair of entity and data to update
@@ -25,6 +25,8 @@ let moduleOptions = {
], ],
} }
jest.setTimeout(30000)
moduleIntegrationTestRunner({ moduleIntegrationTestRunner({
moduleName: Modules.NOTIFICATION, moduleName: Modules.NOTIFICATION,
moduleOptions, moduleOptions,
@@ -365,6 +365,73 @@ moduleIntegrationTestRunner({
"ProductCollection with id: does-not-exist was not found" "ProductCollection with id: does-not-exist was not found"
) )
}) })
it("should dissociate existing products when new products are synced", async () => {
await service.upsertCollections([
{
id: collectionId,
product_ids: [productOne.id, productTwo.id],
},
])
/**
* Another upsert should remove the first productOne
*/
await service.upsertCollections([
{
id: collectionId,
product_ids: [productTwo.id],
},
])
const productCollection = await service.retrieveCollection(
collectionId,
{
select: ["products.id"],
relations: ["products"],
}
)
expect(productCollection.products).toHaveLength(1)
expect(productCollection).toEqual(
expect.objectContaining({
products: expect.arrayContaining([
expect.objectContaining({
id: productTwo.id,
}),
]),
})
)
})
it("should dissociate all existing products", async () => {
await service.upsertCollections([
{
id: collectionId,
product_ids: [productOne.id, productTwo.id],
},
])
/**
* Another upsert should remove the first productOne
*/
await service.upsertCollections([
{
id: collectionId,
product_ids: [],
},
])
const productCollection = await service.retrieveCollection(
collectionId,
{
select: ["products.id"],
relations: ["products"],
}
)
expect(productCollection.products).toHaveLength(0)
})
}) })
describe("createCollections", () => { describe("createCollections", () => {
@@ -34,6 +34,7 @@ import {
removeUndefined, removeUndefined,
isValidHandle, isValidHandle,
toHandle, toHandle,
isPresent,
} from "@medusajs/utils" } from "@medusajs/utils"
import { import {
ProductCategoryEventData, ProductCategoryEventData,
@@ -925,37 +926,53 @@ export default class ProductModuleService<
sharedContext sharedContext
) )
const collectionWithProducts = await promiseAll( const collections: TProductCollection[] = []
updatedCollections.map(async (collection, i) => {
const input = normalizedInput.find((c) => c.id === collection.id) const updateSelectorAndData = updatedCollections.flatMap(
(collectionData) => {
const input = normalizedInput.find((c) => c.id === collectionData.id)
const productsToUpdate = (input as any)?.products const productsToUpdate = (input as any)?.products
if (!productsToUpdate) {
return { ...collection, products: [] } const dissociateSelector = {
collection_id: collectionData.id,
}
const associateSelector = {}
if (!!productsToUpdate?.length) {
const productIds = productsToUpdate.map((p) => p.id)
dissociateSelector["id"] = { $nin: productIds }
associateSelector["id"] = { $in: productIds }
} }
await this.productService_.update( const result: Record<string, any>[] = [
{ {
selector: { collection_id: collection.id }, selector: dissociateSelector,
data: { collection_id: null }, data: {
collection_id: null,
},
}, },
sharedContext ]
)
if (productsToUpdate.length > 0) { if (isPresent(associateSelector)) {
await this.productService_.update( result.push({
productsToUpdate.map((p) => ({ selector: associateSelector,
id: p.id, data: {
collection_id: collection.id, collection_id: collectionData.id,
})), },
sharedContext })
)
} }
return { ...collection, products: productsToUpdate } collections.push({
}) ...collectionData,
products: productsToUpdate ?? [],
})
return result
}
) )
return collectionWithProducts await this.productService_.update(updateSelectorAndData, sharedContext)
return collections
} }
@InjectManager("baseRepository_") @InjectManager("baseRepository_")