feat: customer group update (#1098)
This commit is contained in:
1 parent
f983cfada6
commit
d80eaa172d
8 files changed
+226
-15
No files matched your search
@@ -55,7 +55,7 @@ describe("/admin/customer-groups", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
expect(response.data.customerGroup).toEqual(
|
expect(response.data.customer_group).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
name: "test group",
|
name: "test group",
|
||||||
})
|
})
|
||||||
@@ -193,6 +193,88 @@ describe("/admin/customer-groups", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("POST /admin/customer-groups/:id", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
try {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
await customerSeeder(dbConnection)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("updates group name & metadata", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const id = "customer-group-2"
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
name: "vip-customers-v2",
|
||||||
|
metadata: {
|
||||||
|
metaKey1: `metaValue1`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api.post(`/admin/customer-groups/${id}`, body, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.customer_group).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "customer-group-2",
|
||||||
|
name: "vip-customers-v2",
|
||||||
|
metadata: {
|
||||||
|
data1: "value1",
|
||||||
|
metaKey1: `metaValue1`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
expect(response.data.customer_group).not.toHaveProperty("customers")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("deletes `metadata` nested key", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const id = "customer-group-2"
|
||||||
|
// already has some metadata initially
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
name: "vip-customers-v2",
|
||||||
|
metadata: {
|
||||||
|
data1: null, // delete
|
||||||
|
data2: "val2", // insert
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api
|
||||||
|
.post(`/admin/customer-groups/${id}?expand=customers`, body, {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer test_token",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(console.log)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.customer_group).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "customer-group-2",
|
||||||
|
name: "vip-customers-v2",
|
||||||
|
metadata: { data1: null, data2: "val2" },
|
||||||
|
customers: [],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("GET /admin/customer-groups", () => {
|
describe("GET /admin/customer-groups", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -221,13 +303,13 @@ describe("/admin/customer-groups", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
expect(response.data.customerGroup).toEqual(
|
expect(response.data.customer_group).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: "customer-group-1",
|
id: "customer-group-1",
|
||||||
name: "vip-customers",
|
name: "vip-customers",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
expect(response.data.customerGroup).not.toHaveProperty("customers")
|
expect(response.data.customer_group).not.toHaveProperty("customers")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("gets customer group with `customers` prop", async () => {
|
it("gets customer group with `customers` prop", async () => {
|
||||||
@@ -245,13 +327,13 @@ describe("/admin/customer-groups", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
expect(response.data.customerGroup).toEqual(
|
expect(response.data.customer_group).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: "customer-group-1",
|
id: "customer-group-1",
|
||||||
name: "vip-customers",
|
name: "vip-customers",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
expect(response.data.customerGroup.customers).toEqual([])
|
expect(response.data.customer_group.customers).toEqual([])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("throws error when a customer group doesn't exist", async () => {
|
it("throws error when a customer group doesn't exist", async () => {
|
||||||
|
|||||||
@@ -52,6 +52,17 @@ module.exports = async (connection, data = {}) => {
|
|||||||
name: "vip-customers",
|
name: "vip-customers",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await manager.insert(CustomerGroup, {
|
||||||
|
id: "customer-group-2",
|
||||||
|
name: "test-group-2",
|
||||||
|
metadata: { data1: "value1" },
|
||||||
|
})
|
||||||
|
|
||||||
|
await manager.insert(CustomerGroup, {
|
||||||
|
id: "customer-group-3",
|
||||||
|
name: "vest-group-3",
|
||||||
|
})
|
||||||
|
|
||||||
await manager.insert(CustomerGroup, {
|
await manager.insert(CustomerGroup, {
|
||||||
id: "test-group-4",
|
id: "test-group-4",
|
||||||
name: "test-group-4",
|
name: "test-group-4",
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import { validator } from "../../../../utils/validator"
|
|||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* properties:
|
* properties:
|
||||||
* customerGroup:
|
* customer_group:
|
||||||
* $ref: "#/components/schemas/customergroup"
|
* $ref: "#/components/schemas/customer_group"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
@@ -32,7 +32,7 @@ export default async (req, res) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const customerGroup = await customerGroupService.create(validated)
|
const customerGroup = await customerGroupService.create(validated)
|
||||||
res.status(200).json({ customerGroup })
|
res.status(200).json({ customer_group: customerGroup })
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AdminPostCustomerGroupsReq {
|
export class AdminPostCustomerGroupsReq {
|
||||||
|
|||||||
@@ -20,13 +20,16 @@ import { defaultAdminCustomerGroupsRelations } from "."
|
|||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* properties:
|
* properties:
|
||||||
* customerGroup:
|
* customer_group:
|
||||||
* $ref: "#/components/schemas/customer-group"
|
* $ref: "#/components/schemas/customer_group"
|
||||||
*/
|
*/
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
|
|
||||||
const validated = await validator(AdminGetCustomerGroupsGroupParams, req.query)
|
const validated = await validator(
|
||||||
|
AdminGetCustomerGroupsGroupParams,
|
||||||
|
req.query
|
||||||
|
)
|
||||||
|
|
||||||
const customerGroupService: CustomerGroupService = req.scope.resolve(
|
const customerGroupService: CustomerGroupService = req.scope.resolve(
|
||||||
"customerGroupService"
|
"customerGroupService"
|
||||||
@@ -45,7 +48,7 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const customerGroup = await customerGroupService.retrieve(id, findConfig)
|
const customerGroup = await customerGroupService.retrieve(id, findConfig)
|
||||||
|
|
||||||
res.json({ customerGroup })
|
res.json({ customer_group: customerGroup })
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AdminGetCustomerGroupsGroupParams extends FindParams {}
|
export class AdminGetCustomerGroupsGroupParams extends FindParams {}
|
||||||
@@ -14,6 +14,11 @@ export default (app) => {
|
|||||||
"/:id",
|
"/:id",
|
||||||
middlewares.wrap(require("./delete-customer-group").default)
|
middlewares.wrap(require("./delete-customer-group").default)
|
||||||
)
|
)
|
||||||
|
route.post(
|
||||||
|
"/:id",
|
||||||
|
middlewares.wrap(require("./update-customer-group").default)
|
||||||
|
)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import { IsObject, IsOptional, IsString } from "class-validator"
|
||||||
|
import { defaultAdminCustomerGroupsRelations } from "."
|
||||||
|
|
||||||
|
import { CustomerGroupService } from "../../../../services"
|
||||||
|
import { FindParams } from "../../../../types/common"
|
||||||
|
import { validator } from "../../../../utils/validator"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @oas [post] /customer-groups/{id}
|
||||||
|
* operationId: "PostCustomerGroupsGroup"
|
||||||
|
* summary: "Update a CustomerGroup"
|
||||||
|
* description: "Update a CustomerGroup."
|
||||||
|
* x-authenticated: true
|
||||||
|
* parameters:
|
||||||
|
* - (path) id=* {string} The id of the customer group.
|
||||||
|
* - (body) name=* {string} Name of the customer group
|
||||||
|
* - (body) metadata {object} Metadata for the customer.
|
||||||
|
* tags:
|
||||||
|
* - CustomerGroup
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: OK
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* properties:
|
||||||
|
* customer_group:
|
||||||
|
* $ref: "#/components/schemas/customer_group"
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const validatedBody = await validator(
|
||||||
|
AdminPostCustomerGroupsGroupReq,
|
||||||
|
req.body
|
||||||
|
)
|
||||||
|
const validatedQuery = await validator(FindParams, req.query)
|
||||||
|
|
||||||
|
const customerGroupService: CustomerGroupService = req.scope.resolve(
|
||||||
|
"customerGroupService"
|
||||||
|
)
|
||||||
|
|
||||||
|
await customerGroupService.update(id, validatedBody)
|
||||||
|
|
||||||
|
let expandFields: string[] = []
|
||||||
|
if (validatedQuery.expand) {
|
||||||
|
expandFields = validatedQuery.expand.split(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
const findConfig = {
|
||||||
|
relations: expandFields.length
|
||||||
|
? expandFields
|
||||||
|
: defaultAdminCustomerGroupsRelations,
|
||||||
|
}
|
||||||
|
|
||||||
|
const customerGroup = await customerGroupService.retrieve(id, findConfig)
|
||||||
|
|
||||||
|
res.json({ customer_group: customerGroup })
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminPostCustomerGroupsGroupReq {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
name?: string
|
||||||
|
|
||||||
|
@IsObject()
|
||||||
|
@IsOptional()
|
||||||
|
metadata?: object
|
||||||
|
}
|
||||||
@@ -4,7 +4,10 @@ import { DeepPartial, EntityManager } from "typeorm"
|
|||||||
import { CustomerGroup } from ".."
|
import { CustomerGroup } from ".."
|
||||||
import { CustomerGroupRepository } from "../repositories/customer-group"
|
import { CustomerGroupRepository } from "../repositories/customer-group"
|
||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
import { FilterableCustomerGroupProps } from "../types/customer-groups"
|
import {
|
||||||
|
CustomerGroupUpdate,
|
||||||
|
FilterableCustomerGroupProps,
|
||||||
|
} from "../types/customer-groups"
|
||||||
|
|
||||||
type CustomerGroupConstructorProps = {
|
type CustomerGroupConstructorProps = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
@@ -42,14 +45,14 @@ class CustomerGroupService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async retrieve(id: string, config = {}): Promise<CustomerGroup> {
|
async retrieve(id: string, config = {}): Promise<CustomerGroup> {
|
||||||
const customerRepo = this.manager_.getCustomRepository(
|
const cgRepo = this.manager_.getCustomRepository(
|
||||||
this.customerGroupRepository_
|
this.customerGroupRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
const validatedId = this.validateId_(id)
|
const validatedId = this.validateId_(id)
|
||||||
const query = this.buildQuery_({ id: validatedId }, config)
|
const query = this.buildQuery_({ id: validatedId }, config)
|
||||||
|
|
||||||
const customerGroup = await customerRepo.findOne(query)
|
const customerGroup = await cgRepo.findOne(query)
|
||||||
if (!customerGroup) {
|
if (!customerGroup) {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.NOT_FOUND,
|
MedusaError.Types.NOT_FOUND,
|
||||||
@@ -86,6 +89,38 @@ class CustomerGroupService extends BaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a customer group.
|
||||||
|
*
|
||||||
|
* @param {string} customerGroupId - id of the customer group
|
||||||
|
* @param {CustomerGroupUpdate} update - customer group partial data
|
||||||
|
*/
|
||||||
|
async update(
|
||||||
|
customerGroupId: string,
|
||||||
|
update: CustomerGroupUpdate
|
||||||
|
): Promise<CustomerGroup[]> {
|
||||||
|
return this.atomicPhase_(async (manager) => {
|
||||||
|
const { metadata, ...properties } = update
|
||||||
|
|
||||||
|
const cgRepo: CustomerGroupRepository = manager.getCustomRepository(
|
||||||
|
this.customerGroupRepository_
|
||||||
|
)
|
||||||
|
|
||||||
|
const customerGroup = await this.retrieve(customerGroupId)
|
||||||
|
|
||||||
|
for (const key in properties) {
|
||||||
|
if (typeof properties[key] !== "undefined") {
|
||||||
|
customerGroup[key] = properties[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof metadata !== "undefined") {
|
||||||
|
customerGroup.metadata = this.setMetadata_(customerGroup, metadata)
|
||||||
|
}
|
||||||
|
return await cgRepo.save(customerGroup)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove customer group
|
* Remove customer group
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -8,3 +8,8 @@ export class FilterableCustomerGroupProps {
|
|||||||
@IsType([String, [String], StringComparisonOperator])
|
@IsType([String, [String], StringComparisonOperator])
|
||||||
id?: string | string[] | StringComparisonOperator
|
id?: string | string[] | StringComparisonOperator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CustomerGroupUpdate {
|
||||||
|
name?: string
|
||||||
|
metadata?: object
|
||||||
|
}
|
||||||
Reference in new issue
Block a user