fix(medusa): Allow deleting metadata fields (#3055)

This commit is contained in:
Kasper Fabricius Kristensen authored and GitHub committed 2023-01-19 11:34:13 +01:00
1 parent 6481b0c357
commit fcba705701
4 files changed
+57 -3

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
fix(medusa): Allow users to unset metadata fields in updates.
@@ -1334,6 +1334,37 @@ describe("/admin/products", () => {
expect(response.data.product.images.length).toEqual(0) expect(response.data.product.images.length).toEqual(0)
}) })
it("updates a product by deleting a field from metadata", async () => {
const api = useApi()
const product = await simpleProductFactory(dbConnection, {
metadata: {
"test-key": "test-value",
"test-key-2": "test-value-2",
"test-key-3": "test-value-3",
},
})
const payload = {
metadata: {
"test-key": "",
"test-key-2": null,
},
}
const response = await api.post(
"/admin/products/" + product.id,
payload,
adminHeaders
)
expect(response.status).toEqual(200)
expect(response.data.product.metadata).toEqual({
"test-key-2": null,
"test-key-3": "test-value-3",
})
})
it("fails to update product with invalid status", async () => { it("fails to update product with invalid status", async () => {
const api = useApi() const api = useApi()
@@ -5,17 +5,17 @@ import {
ProductType, ProductType,
ShippingProfile, ShippingProfile,
ShippingProfileType, ShippingProfileType,
Store Store,
} from "@medusajs/medusa" } from "@medusajs/medusa"
import faker from "faker" import faker from "faker"
import { Connection } from "typeorm" import { Connection } from "typeorm"
import { import {
ProductVariantFactoryData, ProductVariantFactoryData,
simpleProductVariantFactory simpleProductVariantFactory,
} from "./simple-product-variant-factory" } from "./simple-product-variant-factory"
import { import {
SalesChannelFactoryData, SalesChannelFactoryData,
simpleSalesChannelFactory simpleSalesChannelFactory,
} from "./simple-sales-channel-factory" } from "./simple-sales-channel-factory"
export type ProductFactoryData = { export type ProductFactoryData = {
@@ -28,6 +28,7 @@ export type ProductFactoryData = {
options?: { id: string; title: string }[] options?: { id: string; title: string }[]
variants?: ProductVariantFactoryData[] variants?: ProductVariantFactoryData[]
sales_channels?: SalesChannelFactoryData[] sales_channels?: SalesChannelFactoryData[]
metadata?: Record<string, unknown>
} }
export const simpleProductFactory = async ( export const simpleProductFactory = async (
@@ -83,6 +84,7 @@ export const simpleProductFactory = async (
discountable: !data.is_giftcard, discountable: !data.is_giftcard,
tags: [] as ProductTag[], tags: [] as ProductTag[],
profile_id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id, profile_id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id,
metadata: data.metadata || null,
} as Product } as Product
if (typeof data.tags !== "undefined") { if (typeof data.tags !== "undefined") {
+16
View File
@@ -12,6 +12,7 @@ export function setMetadata(
): Record<string, unknown> { ): Record<string, unknown> {
const existing = obj.metadata || {} const existing = obj.metadata || {}
const newData = {} const newData = {}
for (const [key, value] of Object.entries(metadata)) { for (const [key, value] of Object.entries(metadata)) {
if (typeof key !== "string") { if (typeof key !== "string") {
throw new MedusaError( throw new MedusaError(
@@ -19,6 +20,21 @@ export function setMetadata(
"Key type is invalid. Metadata keys must be strings" "Key type is invalid. Metadata keys must be strings"
) )
} }
/**
* We reserve the empty string as a way to delete a key.
* If the value is an empty string, we don't
* set it, and if it exists in the existing metadata, we
* unset the field.
*/
if (value === "") {
if (key in existing) {
delete existing[key]
}
continue
}
newData[key] = value newData[key] = value
} }