chore(): Module Internal Events (#13296)

* chore(): Ensure the product module emits all necessary events

* chore(): Ensure the product module emits all necessary events

* Update events tests

* more events and fixes

* more tests and category fixes

* more tests and category fixes

* Add todo

* update updateProduct_ event emitting and adjust test

* Adjust update products implementation to rely on already computed events

* rm unnecessary update variants events

* Fix formatting in changeset for product events

* refactor: Manage event emitting automatically (WIP)

* refactor: Manage event emitting automatically (WIP)

* chore(api-key): Add missing emit events and refactoring

* chore(cart): Add missing emit events and refactoring

* chore(customer): Add missing emit events and refactoring

* chore(fufillment, utils): Add missing emit events and refactoring

* chore(fufillment, utils): Add missing emit events and refactoring

* chore(inventory): Add missing emit events and refactoring

* chore(notification): Add missing emit events and refactoring

* chore(utils): Remove medusa service event handling legacy

* chore(product): Add missing emit events and refactoring

* chore(order): Add missing emit events and refactoring

* chore(payment): Add missing emit events and refactoring

* chore(pricing, util): Add missing emit events and refactoring, fix internal service upsertWithReplace event dispatching

* chore(promotions): Add missing emit events and refactoring

* chore(region): Add missing emit events and refactoring

* chore(sales-channel): Add missing emit events and refactoring

* chore(settings): Add missing emit events and refactoring

* chore(stock-location): Add missing emit events and refactoring

* chore(store): Add missing emit events and refactoring

* chore(taxes): Add missing emit events and refactoring

* chore(user): Add missing emit events and refactoring

* fix unit tests

* rm changeset for regeneration

* Create changeset for Medusa.js patch updates

Add a changeset for patch updates to multiple Medusa.js modules.

* rm unused product event builders

* address feedback

* remove old changeset

* fix event action for token generated

* fix user module events

* fix import

* fix promotion events

* add new module integration tests shard

* fix medusa service

* revert shard

* fix event action

* fix pipeline

* fix pipeline

---------

Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2025-09-10 14:37:38 +02:00
committed by GitHub
parent afe21741c4
commit e8822f3e69
55 changed files with 3614 additions and 2353 deletions

View File

@@ -219,7 +219,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "fulfillment_set",
data: {
id: expect.arrayContaining([fulfillmentSets[i].id]),
id: fulfillmentSets[i].id,
},
}),
]),
@@ -338,7 +338,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "fulfillment_set",
data: {
id: expect.arrayContaining([fulfillmentSets[i].id]),
id: fulfillmentSets[i].id,
},
}),
buildExpectedEventMessageShape({
@@ -346,9 +346,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "service_zone",
data: {
id: expect.arrayContaining([
fulfillmentSets[i].service_zones[0].id,
]),
id: fulfillmentSets[i].service_zones[0].id,
},
}),
]),
@@ -514,7 +512,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "fulfillment_set",
data: {
id: expect.arrayContaining([fulfillmentSets[i].id]),
id: fulfillmentSets[i].id,
},
}),
buildExpectedEventMessageShape({
@@ -522,9 +520,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "service_zone",
data: {
id: expect.arrayContaining([
fulfillmentSets[i].service_zones[0].id,
]),
id: fulfillmentSets[i].service_zones[0].id,
},
}),
buildExpectedEventMessageShape({
@@ -532,9 +528,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "geo_zone",
data: {
id: expect.arrayContaining([
fulfillmentSets[i].service_zones[0].geo_zones[0].id,
]),
id: fulfillmentSets[i].service_zones[0].geo_zones[0].id,
},
}),
]),
@@ -724,7 +718,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
})
expect(updatedFulfillmentSets).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[1][0]).toHaveLength(1)
expect(eventBusEmitSpy.mock.calls[1][0]).toHaveLength(2)
for (const data_ of updateData) {
const currentFullfillmentSet = fullfillmentSets.find(
@@ -746,7 +740,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "updated",
object: "fulfillment_set",
data: {
id: expect.arrayContaining([currentFullfillmentSet.id]),
id: currentFullfillmentSet.id,
},
}),
]),
@@ -1075,7 +1069,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
)
expect(updatedFulfillmentSets).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[1][0]).toHaveLength(5)
expect(eventBusEmitSpy.mock.calls[1][0]).toHaveLength(10)
for (const data_ of updateData) {
const expectedFulfillmentSet = updatedFulfillmentSets.find(
@@ -1116,7 +1110,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "updated",
object: "fulfillment_set",
data: {
id: expect.arrayContaining([expectedFulfillmentSet.id]),
id: expectedFulfillmentSet.id,
},
}),
buildExpectedEventMessageShape({
@@ -1124,9 +1118,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "service_zone",
data: {
id: expect.arrayContaining([
expectedFulfillmentSet.service_zones[0].id,
]),
id: expectedFulfillmentSet.service_zones[0].id,
},
}),
buildExpectedEventMessageShape({
@@ -1134,9 +1126,8 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "geo_zone",
data: {
id: expect.arrayContaining([
expectedFulfillmentSet.service_zones[0].geo_zones[0].id,
]),
id: expectedFulfillmentSet.service_zones[0].geo_zones[0]
.id,
},
}),
buildExpectedEventMessageShape({
@@ -1144,9 +1135,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "deleted",
object: "service_zone",
data: {
id: expect.arrayContaining([
originalFulfillmentSet.service_zones[0].id,
]),
id: originalFulfillmentSet.service_zones[0].id,
},
}),
buildExpectedEventMessageShape({
@@ -1154,9 +1143,8 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "deleted",
object: "geo_zone",
data: {
id: expect.arrayContaining([
originalFulfillmentSet.service_zones[0].geo_zones[0].id,
]),
id: originalFulfillmentSet.service_zones[0].geo_zones[0]
.id,
},
}),
]),
@@ -1245,7 +1233,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
)
expect(updatedFulfillmentSets).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[1][0]).toHaveLength(3)
expect(eventBusEmitSpy.mock.calls[1][0]).toHaveLength(6)
for (const data_ of updateData) {
const expectedFulfillmentSet = updatedFulfillmentSets.find(
@@ -1290,7 +1278,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "updated",
object: "fulfillment_set",
data: {
id: expect.arrayContaining([expectedFulfillmentSet.id]),
id: expectedFulfillmentSet.id,
},
}),
buildExpectedEventMessageShape({
@@ -1298,7 +1286,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "service_zone",
data: {
id: expect.arrayContaining([createdServiceZone.id]),
id: createdServiceZone.id,
},
}),
buildExpectedEventMessageShape({
@@ -1306,9 +1294,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "geo_zone",
data: {
id: expect.arrayContaining([
createdServiceZone.geo_zones[0].id,
]),
id: createdServiceZone.geo_zones[0].id,
},
}),
]),

View File

@@ -152,15 +152,21 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
})
)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(4)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(5)
expect(eventBusEmitSpy).toHaveBeenCalledWith(
[
expect.arrayContaining([
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_CREATED,
action: "created",
object: "fulfillment",
data: { id: fulfillment.id },
}),
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_UPDATED,
action: "updated",
object: "fulfillment",
data: { id: fulfillment.id },
}),
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_ADDRESS_CREATED,
action: "created",
@@ -179,7 +185,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
object: "fulfillment_label",
data: { id: fulfillment.labels[0].id },
}),
],
]),
{
internal: true,
}
@@ -244,15 +250,21 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
})
)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(4)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(5)
expect(eventBusEmitSpy).toHaveBeenCalledWith(
[
expect.arrayContaining([
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_CREATED,
action: "created",
object: "fulfillment",
data: { id: fulfillment.id },
}),
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_UPDATED,
action: "updated",
object: "fulfillment",
data: { id: fulfillment.id },
}),
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_ADDRESS_CREATED,
action: "created",
@@ -271,7 +283,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
object: "fulfillment_label",
data: { id: fulfillment.labels[0].id },
}),
],
]),
{
internal: true,
}
@@ -383,15 +395,9 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
})
)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(4)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(3)
expect(eventBusEmitSpy).toHaveBeenCalledWith(
[
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_UPDATED,
action: "updated",
object: "fulfillment",
data: { id: updatedFulfillment.id },
}),
expect.arrayContaining([
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.FULFILLMENT_LABEL_DELETED,
action: "deleted",
@@ -410,7 +416,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
object: "fulfillment_label",
data: { id: label4.id },
}),
],
]),
{
internal: true,
}

View File

@@ -154,7 +154,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
const geoZones = await service.createGeoZones(data)
expect(geoZones).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(1)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(2)
let i = 0
for (const data_ of data) {
@@ -172,7 +172,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
eventName: FulfillmentEvents.GEO_ZONE_CREATED,
action: "created",
object: "geo_zone",
data: { id: expect.arrayContaining([geoZones[i].id]) },
data: { id: geoZones[i].id },
}),
]),
{
@@ -331,7 +331,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
const updatedGeoZones = await service.updateGeoZones(updateData)
expect(updatedGeoZones).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(1)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(2)
for (const data_ of updateData) {
const expectedGeoZone = updatedGeoZones.find(
@@ -352,7 +352,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
eventName: FulfillmentEvents.GEO_ZONE_UPDATED,
action: "updated",
object: "geo_zone",
data: { id: expect.arrayContaining([expectedGeoZone.id]) },
data: { id: expectedGeoZone.id },
}),
]),
{

View File

@@ -371,7 +371,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(4)
expect(eventBusEmitSpy).toHaveBeenCalledWith(
[
expect.arrayContaining([
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.GEO_ZONE_DELETED,
action: "deleted",
@@ -396,7 +396,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
object: "geo_zone",
data: { id: usGeoZone.id },
}),
],
]),
{
internal: true,
}
@@ -510,7 +510,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
expect(updatedServiceZones).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(3) // Since the update only calls create and update which are already tested, only check the length
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(6) // Since the update only calls create and update which are already tested, only check the length
for (const data_ of updateData) {
const expectedServiceZone = updatedServiceZones.find(

View File

@@ -522,7 +522,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(3)
expect(eventBusEmitSpy).toHaveBeenCalledWith(
[
expect.arrayContaining([
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.SHIPPING_OPTION_CREATED,
action: "created",
@@ -541,7 +541,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
object: "shipping_option_rule",
data: { id: createdShippingOption.rules[0].id },
}),
],
]),
{
internal: true,
}
@@ -582,7 +582,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
)
expect(createdShippingOptions).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(3)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(6)
let i = 0
for (const data_ of createData) {
@@ -620,9 +620,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "shipping_option",
data: {
id: expect.arrayContaining([
createdShippingOptions[i].id,
]),
id: createdShippingOptions[i].id,
},
}),
buildExpectedEventMessageShape({
@@ -630,9 +628,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "shipping_option_type",
data: {
id: expect.arrayContaining([
createdShippingOptions[i].type.id,
]),
id: createdShippingOptions[i].type.id,
},
}),
buildExpectedEventMessageShape({
@@ -640,9 +636,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "shipping_option_rule",
data: {
id: expect.arrayContaining([
createdShippingOptions[i].rules[0].id,
]),
id: createdShippingOptions[i].rules[0].id,
},
}),
]),
@@ -823,7 +817,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
])
)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(5)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(4)
expect(eventBusEmitSpy).toHaveBeenCalledWith(
expect.arrayContaining([
buildExpectedEventMessageShape({
@@ -832,12 +826,6 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
object: "shipping_option",
data: { id: updatedShippingOption.id },
}),
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.SHIPPING_OPTION_TYPE_DELETED,
action: "deleted",
object: "shipping_option_type",
data: { id: shippingOption.type.id },
}),
buildExpectedEventMessageShape({
eventName: FulfillmentEvents.SHIPPING_OPTION_TYPE_CREATED,
action: "created",
@@ -1374,14 +1362,16 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
])
// Test with full address including postal expression
const shippingOptions = await service.listShippingOptionsForContext({
address: {
country_code: "US",
province_code: "CA",
city: "Los Angeles",
postal_expression: "90210",
},
})
const shippingOptions = await service.listShippingOptionsForContext(
{
address: {
country_code: "US",
province_code: "CA",
city: "Los Angeles",
postal_expression: "90210",
},
}
)
expect(shippingOptions).toHaveLength(1)
})
@@ -1419,13 +1409,15 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
])
// Test with city but no postal expression
const shippingOptions = await service.listShippingOptionsForContext({
address: {
country_code: "US",
province_code: "CA",
city: "San Francisco",
},
})
const shippingOptions = await service.listShippingOptionsForContext(
{
address: {
country_code: "US",
province_code: "CA",
city: "San Francisco",
},
}
)
expect(shippingOptions).toHaveLength(1)
})
@@ -1462,12 +1454,14 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
])
// Test with province but no city
const shippingOptions = await service.listShippingOptionsForContext({
address: {
country_code: "US",
province_code: "NY",
},
})
const shippingOptions = await service.listShippingOptionsForContext(
{
address: {
country_code: "US",
province_code: "NY",
},
}
)
expect(shippingOptions).toHaveLength(1)
})
@@ -1503,11 +1497,13 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
])
// Test with only country
const shippingOptions = await service.listShippingOptionsForContext({
address: {
country_code: "CA",
},
})
const shippingOptions = await service.listShippingOptionsForContext(
{
address: {
country_code: "CA",
},
}
)
expect(shippingOptions).toHaveLength(1)
})
@@ -1758,14 +1754,16 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
])
// Address with undefined fields should still match if country matches
const shippingOptions = await service.listShippingOptionsForContext({
address: {
country_code: "US",
province_code: undefined,
city: undefined,
postal_expression: undefined,
},
})
const shippingOptions = await service.listShippingOptionsForContext(
{
address: {
country_code: "US",
province_code: undefined,
city: undefined,
postal_expression: undefined,
},
}
)
expect(shippingOptions).toHaveLength(1)
})
@@ -1831,26 +1829,27 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
})
// Create shipping options for each zone
const [usOption, europeOption, canadaOption] = await service.createShippingOptions([
generateCreateShippingOptionsData({
name: "US Shipping",
service_zone_id: fulfillmentSet.service_zones[0].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "Europe Shipping",
service_zone_id: fulfillmentSet.service_zones[1].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "Canada Shipping",
service_zone_id: fulfillmentSet.service_zones[2].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
])
const [usOption, europeOption, canadaOption] =
await service.createShippingOptions([
generateCreateShippingOptionsData({
name: "US Shipping",
service_zone_id: fulfillmentSet.service_zones[0].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "Europe Shipping",
service_zone_id: fulfillmentSet.service_zones[1].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "Canada Shipping",
service_zone_id: fulfillmentSet.service_zones[2].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
])
// Test US ZIP code - should only match US zone
let shippingOptions = await service.listShippingOptionsForContext({
@@ -1970,26 +1969,27 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
})
// Create shipping options with different prices for each zone
const [broadOption, californiaOption, laOption] = await service.createShippingOptions([
generateCreateShippingOptionsData({
name: "Standard US Shipping",
service_zone_id: fulfillmentSet.service_zones[0].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "California Express",
service_zone_id: fulfillmentSet.service_zones[1].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "LA Premium",
service_zone_id: fulfillmentSet.service_zones[2].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
])
const [broadOption, californiaOption, laOption] =
await service.createShippingOptions([
generateCreateShippingOptionsData({
name: "Standard US Shipping",
service_zone_id: fulfillmentSet.service_zones[0].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "California Express",
service_zone_id: fulfillmentSet.service_zones[1].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
generateCreateShippingOptionsData({
name: "LA Premium",
service_zone_id: fulfillmentSet.service_zones[2].id,
shipping_profile_id: shippingProfile.id,
provider_id: providerId,
}),
])
// Test LA ZIP code - should match all three zones
let shippingOptions = await service.listShippingOptionsForContext({
@@ -2001,7 +2001,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
},
})
expect(shippingOptions).toHaveLength(3)
const laIds = shippingOptions.map(opt => opt.id)
const laIds = shippingOptions.map((opt) => opt.id)
expect(laIds).toContain(broadOption.id)
expect(laIds).toContain(californiaOption.id)
expect(laIds).toContain(laOption.id)
@@ -2015,7 +2015,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
},
})
expect(shippingOptions).toHaveLength(2)
const caIds = shippingOptions.map(opt => opt.id)
const caIds = shippingOptions.map((opt) => opt.id)
expect(caIds).toContain(broadOption.id)
expect(caIds).toContain(californiaOption.id)
expect(caIds).not.toContain(laOption.id)

View File

@@ -100,7 +100,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
await service.createShippingProfiles(createData)
expect(createdShippingProfiles).toHaveLength(2)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(1)
expect(eventBusEmitSpy.mock.calls[0][0]).toHaveLength(2)
let i = 0
for (const data_ of createData) {
@@ -118,9 +118,7 @@ moduleIntegrationTestRunner<IFulfillmentModuleService>({
action: "created",
object: "shipping_profile",
data: {
id: expect.arrayContaining([
createdShippingProfiles[i].id,
]),
id: createdShippingProfiles[i].id,
},
}),
]),