Skip to content

Commit a8c24a5

Browse files
authored
Merge branch 'develop' into chore/add-many-to-many-between-product-and-option
2 parents badd8e3 + baaee11 commit a8c24a5

152 files changed

Lines changed: 7348 additions & 305 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/cyan-taxis-behave.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@medusajs/link-modules": patch
3+
"@medusajs/modules-sdk": patch
4+
---
5+
6+
feat(medusa-app): Link initialization should respect migrationOnly flag

.changeset/great-lies-decide.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"@medusajs/analytics": patch
3+
"@medusajs/auth": patch
4+
"@medusajs/cache-redis": patch
5+
"@medusajs/caching": patch
6+
"@medusajs/event-bus-redis": patch
7+
"@medusajs/file": patch
8+
"@medusajs/locking": patch
9+
"@medusajs/notification": patch
10+
"@medusajs/payment": patch
11+
"@medusajs/workflow-engine-redis": patch
12+
---
13+
14+
feat(): Add modules options autocomplete to medusa config

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ The code snippets in this section assume that your forked Medusa project and the
8383
"@medusajs/pricing": "file:../medusa/packages/modules/pricing",
8484
"@medusajs/product": "file:../medusa/packages/modules/product",
8585
"@medusajs/promotion": "file:../medusa/packages/modules/promotion",
86+
"@medusajs/rbac": "file:../medusa/packages/modules/rbac",
8687
"@medusajs/region": "file:../medusa/packages/modules/region",
8788
"@medusajs/sales-channel": "file:../medusa/packages/modules/sales-channel",
8889
"@medusajs/stock-location": "file:../medusa/packages/modules/stock-location",
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
2+
import {
3+
adminHeaders,
4+
createAdminUser,
5+
} from "../../../../helpers/create-admin-user"
6+
7+
jest.setTimeout(60000)
8+
9+
process.env.MEDUSA_FF_RBAC = "true"
10+
11+
medusaIntegrationTestRunner({
12+
testSuite: ({ dbConnection, api, getContainer }) => {
13+
let container
14+
15+
beforeEach(async () => {
16+
container = getContainer()
17+
await createAdminUser(dbConnection, adminHeaders, container)
18+
})
19+
20+
afterAll(async () => {
21+
delete process.env.MEDUSA_FF_RBAC
22+
})
23+
24+
describe("RBAC Policies - Admin API", () => {
25+
describe("POST /admin/rbac/policies", () => {
26+
it("should create a policy", async () => {
27+
const response = await api.post(
28+
"/admin/rbac/policies",
29+
{
30+
key: "read:products",
31+
resource: "product",
32+
operation: "read",
33+
name: "Read Products",
34+
description: "Permission to read products",
35+
},
36+
adminHeaders
37+
)
38+
39+
expect(response.status).toEqual(200)
40+
expect(response.data.policy).toEqual(
41+
expect.objectContaining({
42+
id: expect.any(String),
43+
key: "read:products",
44+
resource: "product",
45+
operation: "read",
46+
name: "Read Products",
47+
description: "Permission to read products",
48+
})
49+
)
50+
})
51+
52+
it("should create a policy with metadata", async () => {
53+
const response = await api.post(
54+
"/admin/rbac/policies",
55+
{
56+
key: "write:orders",
57+
resource: "order",
58+
operation: "write",
59+
name: "Write Orders",
60+
metadata: { category: "order_management" },
61+
},
62+
adminHeaders
63+
)
64+
65+
expect(response.status).toEqual(200)
66+
expect(response.data.policy).toEqual(
67+
expect.objectContaining({
68+
key: "write:orders",
69+
resource: "order",
70+
operation: "write",
71+
metadata: { category: "order_management" },
72+
})
73+
)
74+
})
75+
})
76+
77+
describe("GET /admin/rbac/policies", () => {
78+
beforeEach(async () => {
79+
await api.post(
80+
"/admin/rbac/policies",
81+
{
82+
key: "read:products",
83+
resource: "product",
84+
operation: "read",
85+
name: "Read Products",
86+
},
87+
adminHeaders
88+
)
89+
90+
await api.post(
91+
"/admin/rbac/policies",
92+
{
93+
key: "write:products",
94+
resource: "product",
95+
operation: "write",
96+
name: "Write Products",
97+
},
98+
adminHeaders
99+
)
100+
101+
await api.post(
102+
"/admin/rbac/policies",
103+
{
104+
key: "read:orders",
105+
resource: "order",
106+
operation: "read",
107+
name: "Read Orders",
108+
},
109+
adminHeaders
110+
)
111+
})
112+
113+
it("should list all policies", async () => {
114+
const response = await api.get("/admin/rbac/policies", adminHeaders)
115+
116+
expect(response.status).toEqual(200)
117+
expect(response.data.count).toEqual(3)
118+
expect(response.data.policies).toEqual(
119+
expect.arrayContaining([
120+
expect.objectContaining({
121+
key: "read:products",
122+
resource: "product",
123+
operation: "read",
124+
}),
125+
expect.objectContaining({
126+
key: "write:products",
127+
resource: "product",
128+
operation: "write",
129+
}),
130+
expect.objectContaining({
131+
key: "read:orders",
132+
resource: "order",
133+
operation: "read",
134+
}),
135+
])
136+
)
137+
})
138+
139+
it("should filter policies by resource", async () => {
140+
const response = await api.get(
141+
"/admin/rbac/policies?resource=product",
142+
adminHeaders
143+
)
144+
145+
expect(response.status).toEqual(200)
146+
expect(response.data.count).toEqual(2)
147+
expect(response.data.policies).toEqual(
148+
expect.arrayContaining([
149+
expect.objectContaining({
150+
key: "read:products",
151+
resource: "product",
152+
}),
153+
expect.objectContaining({
154+
key: "write:products",
155+
resource: "product",
156+
}),
157+
])
158+
)
159+
})
160+
161+
it("should filter policies by operation", async () => {
162+
const response = await api.get(
163+
"/admin/rbac/policies?operation=read",
164+
adminHeaders
165+
)
166+
167+
expect(response.status).toEqual(200)
168+
expect(response.data.count).toEqual(2)
169+
expect(response.data.policies).toEqual(
170+
expect.arrayContaining([
171+
expect.objectContaining({
172+
key: "read:products",
173+
operation: "read",
174+
}),
175+
expect.objectContaining({
176+
key: "read:orders",
177+
operation: "read",
178+
}),
179+
])
180+
)
181+
})
182+
})
183+
184+
describe("GET /admin/rbac/policies/:id", () => {
185+
it("should retrieve a policy by id", async () => {
186+
const createResponse = await api.post(
187+
"/admin/rbac/policies",
188+
{
189+
key: "delete:users",
190+
resource: "user",
191+
operation: "delete",
192+
name: "Delete Users",
193+
},
194+
adminHeaders
195+
)
196+
197+
const policyId = createResponse.data.policy.id
198+
199+
const response = await api.get(
200+
`/admin/rbac/policies/${policyId}`,
201+
adminHeaders
202+
)
203+
204+
expect(response.status).toEqual(200)
205+
expect(response.data.policy).toEqual(
206+
expect.objectContaining({
207+
id: policyId,
208+
key: "delete:users",
209+
resource: "user",
210+
operation: "delete",
211+
name: "Delete Users",
212+
})
213+
)
214+
})
215+
})
216+
217+
describe("POST /admin/rbac/policies/:id", () => {
218+
it("should update a policy", async () => {
219+
const createResponse = await api.post(
220+
"/admin/rbac/policies",
221+
{
222+
key: "admin:system",
223+
resource: "system",
224+
operation: "admin",
225+
name: "System Admin",
226+
},
227+
adminHeaders
228+
)
229+
230+
const policyId = createResponse.data.policy.id
231+
232+
const response = await api.post(
233+
`/admin/rbac/policies/${policyId}`,
234+
{
235+
name: "System Administrator",
236+
description: "Full system access",
237+
},
238+
adminHeaders
239+
)
240+
241+
expect(response.status).toEqual(200)
242+
expect(response.data.policy).toEqual(
243+
expect.objectContaining({
244+
id: policyId,
245+
key: "admin:system",
246+
name: "System Administrator",
247+
description: "Full system access",
248+
})
249+
)
250+
})
251+
})
252+
253+
describe("DELETE /admin/rbac/policies/:id", () => {
254+
it("should delete a policy", async () => {
255+
const createResponse = await api.post(
256+
"/admin/rbac/policies",
257+
{
258+
key: "test:delete",
259+
resource: "test",
260+
operation: "delete",
261+
name: "Test Delete",
262+
},
263+
adminHeaders
264+
)
265+
266+
const policyId = createResponse.data.policy.id
267+
268+
const deleteResponse = await api.delete(
269+
`/admin/rbac/policies/${policyId}`,
270+
adminHeaders
271+
)
272+
273+
expect(deleteResponse.status).toEqual(200)
274+
expect(deleteResponse.data).toEqual({
275+
id: policyId,
276+
object: "rbac_policy",
277+
deleted: true,
278+
})
279+
280+
const listResponse = await api.get(
281+
"/admin/rbac/policies",
282+
adminHeaders
283+
)
284+
expect(
285+
listResponse.data.policies.find((p) => p.id === policyId)
286+
).toBeUndefined()
287+
})
288+
})
289+
})
290+
},
291+
})

0 commit comments

Comments
 (0)