feat(listings): allow admin to PATCH /listings/:id (TEC-2746)
- UpdateListingCommand accepts userRole; ADMIN bypasses owner/agent check - Controller forwards user.role from JwtPayload - Adds unit test covering admin-authorized edit path Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -137,7 +137,30 @@ describe('UpdateListingHandler', () => {
|
||||
|
||||
const command = new UpdateListingCommand('listing-1', 'stranger', 'Tiêu đề mới');
|
||||
|
||||
await expect(handler.execute(command)).rejects.toThrow(/người bán|môi giới/);
|
||||
await expect(handler.execute(command)).rejects.toThrow(/người bán|môi giới|quản trị/);
|
||||
});
|
||||
|
||||
it('allows an admin to update any listing', async () => {
|
||||
const listing = createListing('listing-1', 'seller-1');
|
||||
const property = createProperty('prop-1');
|
||||
mockListingRepo.findById.mockResolvedValue(listing);
|
||||
mockPropertyRepo.findById.mockResolvedValue(property);
|
||||
|
||||
const command = new UpdateListingCommand(
|
||||
'listing-1',
|
||||
'admin-user',
|
||||
'Tiêu đề do admin sửa',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
'ADMIN',
|
||||
);
|
||||
const result = await handler.execute(command);
|
||||
|
||||
expect(result.listingId).toBe('listing-1');
|
||||
expect(result.updatedFields).toContain('title');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,5 +8,6 @@ export class UpdateListingCommand {
|
||||
public readonly rentPriceMonthly?: bigint,
|
||||
public readonly amenities?: string[],
|
||||
public readonly mediaOrder?: { mediaId: string; order: number }[],
|
||||
public readonly userRole?: string,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -38,12 +38,13 @@ export class UpdateListingHandler implements ICommandHandler<UpdateListingComman
|
||||
throw new NotFoundException('Listing', command.listingId);
|
||||
}
|
||||
|
||||
// 2. Ownership check: only the seller or assigned agent can edit
|
||||
// 2. Ownership check: only the seller, assigned agent, or admin can edit
|
||||
const isOwner = listing.sellerId === command.userId;
|
||||
const isAgent = listing.agentId !== null && listing.agentId === command.userId;
|
||||
if (!isOwner && !isAgent) {
|
||||
const isAdmin = command.userRole === 'ADMIN';
|
||||
if (!isOwner && !isAgent && !isAdmin) {
|
||||
throw new ForbiddenException(
|
||||
'Chỉ người bán hoặc môi giới được giao mới có thể chỉnh sửa tin đăng',
|
||||
'Chỉ người bán, môi giới được giao hoặc quản trị viên mới có thể chỉnh sửa tin đăng',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ export class ListingsController {
|
||||
dto.rentPriceMonthly,
|
||||
dto.amenities,
|
||||
dto.mediaOrder,
|
||||
user.role,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user