feat(fulfillment): Migration backward compatibility (#6672)

**What**
- Update migration for backward compatibility. This does not take into account data migration and table cleanup (@olivermrbl do we have a general tasks for the modules on that subject)?
- Rename fulfillment provider id to provider id
- add integration tests to ensure the migration backward compatibility
- add new module type for the options to be used in the medusa config for example

FIXES CORE-1724
This commit is contained in:
Adrien de Peretti
2024-03-12 14:53:33 +01:00
committed by GitHub
parent e82b4788ec
commit 87e63c024e
17 changed files with 897 additions and 138 deletions

View File

@@ -0,0 +1,138 @@
import {
CreateFulfillmentDTO,
CreateShippingOptionDTO,
IFulfillmentModuleService,
} from "@medusajs/types"
export function generateCreateFulfillmentData(
data: Partial<CreateFulfillmentDTO> & {
provider_id: string
shipping_option_id: string
}
) {
const randomString = Math.random().toString(36).substring(7)
return {
location_id: "test-location",
packed_at: null,
shipped_at: null,
delivered_at: null,
canceled_at: null,
data: null,
provider_id: data.provider_id,
shipping_option_id: data.shipping_option_id,
metadata: data.metadata ?? null,
delivery_address: data.delivery_address ?? {
address_1: "test-address_" + randomString,
address_2: "test-address_" + randomString,
city: "test-city_" + randomString,
postal_code: "test-postal-code_" + randomString,
country_code: "test-country-code_" + randomString,
province: "test-province_" + randomString,
phone: "test-phone_" + randomString,
full_name: "test-full-name_" + randomString,
},
items: data.items ?? [
{
title: "test-title_" + randomString,
sku: "test-sku_" + randomString,
quantity: 1,
barcode: "test-barcode_" + randomString,
},
],
labels: data.labels ?? [
{
tracking_number: "test-tracking-number_" + randomString,
tracking_url: "test-tracking-url_" + randomString,
label_url: "test-label-url_" + randomString,
},
],
order: data.order ?? {},
}
}
export function generateCreateShippingOptionsData({
name,
service_zone_id,
shipping_profile_id,
provider_id,
price_type,
rules,
type,
data,
}: Omit<CreateShippingOptionDTO, "name" | "price_type" | "type"> & {
price_type?: CreateShippingOptionDTO["price_type"]
name?: string
type?: CreateShippingOptionDTO["type"]
}): Required<CreateShippingOptionDTO> {
const randomString = Math.random().toString(36).substring(7)
return {
service_zone_id: service_zone_id,
shipping_profile_id: shipping_profile_id,
provider_id: provider_id,
type: type ?? {
code: "test-type_" + randomString,
description: "test-description_" + randomString,
label: "test-label_" + randomString,
},
data: data ?? {
amount: 1000,
},
name: name ?? Math.random().toString(36).substring(7),
price_type: price_type ?? "flat",
rules: rules ?? [
{
attribute: "weight",
operator: "eq",
value: "test",
},
],
}
}
export async function setupFullDataFulfillmentStructure(
service: IFulfillmentModuleService,
{
providerId,
}: {
providerId: string
}
) {
const randomString = Math.random().toString(36).substring(7)
const shippingProfile = await service.createShippingProfiles({
// generate random string
name: "test_" + randomString,
type: "default",
})
const fulfillmentSet = await service.create({
name: "test_" + randomString,
type: "test-type",
})
const serviceZone = await service.createServiceZones({
name: "test_" + randomString,
fulfillment_set_id: fulfillmentSet.id,
geo_zones: [
{
type: "country",
country_code: "US_" + randomString,
},
],
})
const shippingOption = await service.createShippingOptions(
generateCreateShippingOptionsData({
provider_id: providerId,
service_zone_id: serviceZone.id,
shipping_profile_id: shippingProfile.id,
})
)
await service.createFulfillment(
generateCreateFulfillmentData({
provider_id: providerId,
shipping_option_id: shippingOption.id,
})
)
}

View File

@@ -1 +1,2 @@
export * from "./tax"
export * from "./fulfillment"

View File

@@ -0,0 +1,69 @@
import { medusaIntegrationTestRunner } from "medusa-test-utils/dist"
import { setupFullDataFulfillmentStructure } from "../fixtures"
import { IFulfillmentModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
jest.setTimeout(100000)
const env = { MEDUSA_FF_MEDUSA_V2: true }
medusaIntegrationTestRunner({
env,
testSuite: ({ getContainer }) => {
let service: IFulfillmentModuleService
beforeAll(() => {
const container = getContainer()
service = container.resolve(ModuleRegistrationName.FULFILLMENT)
})
/**
* The test runner run both the medusa migrations as well as the modules
* migrations. In order to ensure the backward compatibility
* of the migration works, we will create a full data structure.
*/
describe("Fulfillment module migrations backward compatibility", () => {
it("should allow to create a full data structure after the backward compatible migration have run on top of the medusa v1 database", async () => {
await setupFullDataFulfillmentStructure(service, {
providerId: `manual_test-provider`,
})
const fulfillmentSets = await service.list(
{},
{
relations: [
"service_zones.geo_zones",
"service_zones.shipping_options.shipping_profile",
"service_zones.shipping_options.provider",
"service_zones.shipping_options.type",
"service_zones.shipping_options.rules",
"service_zones.shipping_options.fulfillments.labels",
"service_zones.shipping_options.fulfillments.items",
"service_zones.shipping_options.fulfillments.delivery_address",
],
}
)
expect(fulfillmentSets).toHaveLength(1)
let fulfillmentSet = fulfillmentSets[0]
expect(fulfillmentSet.service_zones).toHaveLength(1)
let serviceZone = fulfillmentSet.service_zones[0]
expect(serviceZone.geo_zones).toHaveLength(1)
expect(serviceZone.shipping_options).toHaveLength(1)
let geoZone = serviceZone.geo_zones[0]
let shippingOption = serviceZone.shipping_options[0]
expect(!!shippingOption.shipping_profile.deleted_at).toEqual(false)
expect(shippingOption.fulfillments).toHaveLength(1)
expect(shippingOption.rules).toHaveLength(1)
let fulfillment = shippingOption.fulfillments[0]
expect(fulfillment.labels).toHaveLength(1)
expect(fulfillment.items).toHaveLength(1)
})
})
},
})

View File

@@ -1,4 +1,5 @@
const { Modules } = require("@medusajs/modules-sdk")
const { FulfillmentModuleOptions } = require("@medusajs/fulfillment")
const DB_HOST = process.env.DB_HOST
const DB_USERNAME = process.env.DB_USERNAME
const DB_PASSWORD = process.env.DB_PASSWORD
@@ -70,5 +71,20 @@ module.exports = {
[Modules.TAX]: true,
[Modules.CURRENCY]: true,
[Modules.PAYMENT]: true,
[Modules.FULFILLMENT]: {
/** @type {import('@medusajs/fulfillment').FulfillmentModuleOptions} */
options: {
providers: [
{
resolve: "@medusajs/fulfillment-manual",
options: {
config: {
"test-provider": {},
},
},
},
],
},
},
},
}