Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('AdminNotificationBroadcastListInput', () => {
{ limit: 100, cursor: '12', type: 'MARKETING', targetKind: 'ALL_USERS' },
],
['ACCOUNT_IDS 필터', { type: 'SYSTEM', targetKind: 'ACCOUNT_IDS' }],
['null 필터(전체)', { type: null, targetKind: null }],
])('%s는 통과한다', async (_label, plain) => {
expect(await invalidProps(plain)).toEqual([]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import {
export class AdminNotificationBroadcastListInput extends CursorInput {
@IsOptional()
@IsIn(ADMIN_NOTIFICATION_TYPES)
type?: AdminNotificationTypeValue;
type?: AdminNotificationTypeValue | null;

@IsOptional()
@IsIn(ADMIN_NOTIFICATION_TARGET_KINDS)
targetKind?: AdminNotificationTargetKindValue;
targetKind?: AdminNotificationTargetKindValue | null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,13 @@ describe('AdminNotificationService (real DB)', () => {
targetAccountIds: [],
skippedAccountIds: [],
});

// GraphQL nullable 인자에 명시적 null이 오면 필터 없음과 같다
const nullFilters = await service.adminNotificationBroadcasts(actor, {
type: null,
targetKind: null,
});
expect(nullFilters.totalCount).toBe(5);
});

it.each(['abc', '-1', '1.5', '18446744073709551616'])(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ export class AdminNotificationService extends AdminBaseService {
limit: input?.limit ?? null,
cursor: input?.cursor != null ? parseIdCursor(input.cursor) : null,
});
const filter = { type: input?.type, targetKind: input?.targetKind };
const filter = {
type: input?.type ?? undefined,
targetKind: input?.targetKind ?? undefined,
};
const [rows, totalCount] = await Promise.all([
this.repo.listBroadcasts({ ...filter, ...normalized }),
this.repo.countBroadcasts(filter),
Expand Down
2 changes: 1 addition & 1 deletion src/features/product/dto/inputs/categories.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { IsIn, IsOptional } from 'class-validator';
export class CategoriesInput {
@IsOptional()
@IsIn(['EVENT', 'STYLE', 'OTHER'])
type?: 'EVENT' | 'STYLE' | 'OTHER';
type?: 'EVENT' | 'STYLE' | 'OTHER' | null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ describe('ProductCategoryService (real DB)', () => {
]);
});

it('type이 null이면 미지정과 같이 전체를 반환한다', async () => {
await createCategory(prisma, { category_type: 'EVENT', name: '생일' });
await createCategory(prisma, { category_type: 'STYLE', name: '입체' });

const result = await service.categories({ type: null });

expect(result.map((c) => c.name)).toEqual(['생일', '입체']);
});

it('type 지정 시 해당 타입만 반환한다', async () => {
await createCategory(prisma, { category_type: 'EVENT', name: '생일' });
await createCategory(prisma, { category_type: 'STYLE', name: '입체' });
Expand Down
3 changes: 2 additions & 1 deletion src/features/product/services/product-category.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export class ProductCategoryService {
constructor(private readonly repo: ProductRepository) {}

async categories(input?: CategoriesInput): Promise<CategoryItem[]> {
const rows = await this.repo.listCategories(input?.type);
// FE가 '전체'를 type: null로 보내도 Prisma where에 null이 닿지 않게
const rows = await this.repo.listCategories(input?.type ?? undefined);
return rows.map((row) => ({
id: row.id.toString(),
name: row.name,
Expand Down
Loading
Loading