@hed-hog/tag 0.0.366 → 0.0.370

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -558,6 +558,7 @@ export default function TagPage() {
558
558
  statusContent={draftStatusContent}
559
559
  cancelLabel={t('cancel')}
560
560
  onCancel={() => {
561
+ clearDraft();
561
562
  setIsSheetOpen(false);
562
563
  setEditingTagId(null);
563
564
  }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hed-hog/tag",
3
- "version": "0.0.366",
3
+ "version": "0.0.370",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "dependencies": {
@@ -10,9 +10,9 @@
10
10
  "@nestjs/jwt": "^11",
11
11
  "@nestjs/mapped-types": "*",
12
12
  "@hed-hog/api-prisma": "0.0.6",
13
- "@hed-hog/core": "0.0.366",
14
- "@hed-hog/api-pagination": "0.0.7",
15
13
  "@hed-hog/api": "0.0.8",
14
+ "@hed-hog/api-pagination": "0.0.7",
15
+ "@hed-hog/core": "0.0.370",
16
16
  "@hed-hog/api-locale": "0.0.14"
17
17
  },
18
18
  "exports": {
@@ -29,6 +29,7 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
32
+ "test": "jest --config jest.config.ts --runInBand",
32
33
  "prebuild": "pnpm --dir ../.. exec ts-node ./scripts/build-dependencies.ts libraries/tag",
33
34
  "build": "tsc --project tsconfig.production.json",
34
35
  "patch": "npx ts-node ../../scripts/patch.ts libraries/tag",
@@ -0,0 +1,187 @@
1
+ jest.mock('@hed-hog/api-locale', () => ({
2
+ getLocaleText: jest.fn((_key: string, _locale: string, fallback: string) => fallback ?? 'Error'),
3
+ }));
4
+
5
+ import { BadRequestException } from '@nestjs/common';
6
+ import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
7
+ import { TagService } from './tag.service';
8
+
9
+ describe('TagService', () => {
10
+ let prisma: any;
11
+ let service: TagService;
12
+
13
+ beforeEach(() => {
14
+ prisma = {
15
+ tag: {
16
+ findMany: jest.fn().mockResolvedValue([]),
17
+ findUnique: jest.fn(),
18
+ count: jest.fn().mockResolvedValue(0),
19
+ create: jest.fn(),
20
+ update: jest.fn(),
21
+ delete: jest.fn(),
22
+ },
23
+ };
24
+ service = new TagService(prisma as any);
25
+ });
26
+
27
+ afterEach(() => {
28
+ jest.clearAllMocks();
29
+ });
30
+
31
+ describe('list', () => {
32
+ it('retorna dados paginados', async () => {
33
+ prisma.tag.findMany.mockResolvedValue([{ id: 1, slug: 'promo', color: '#ff0000', status: 'active' }]);
34
+ prisma.tag.count.mockResolvedValue(1);
35
+
36
+ const result = await service.list({ skip: 0, take: 10, search: '' });
37
+
38
+ expect(result.total).toBe(1);
39
+ expect(result.data).toHaveLength(1);
40
+ expect(result.page).toBe(1);
41
+ expect(result.lastPage).toBe(1);
42
+ });
43
+
44
+ it('calcula página e lastPage corretamente', async () => {
45
+ prisma.tag.findMany.mockResolvedValue([]);
46
+ prisma.tag.count.mockResolvedValue(25);
47
+
48
+ const result = await service.list({ skip: 10, take: 10, search: '' });
49
+
50
+ expect(result.page).toBe(2);
51
+ expect(result.lastPage).toBe(3);
52
+ expect(result.prev).toBe(1);
53
+ expect(result.next).toBe(3);
54
+ });
55
+
56
+ it('aplica filtro de busca no where quando search fornecido', async () => {
57
+ prisma.tag.findMany.mockResolvedValue([]);
58
+ prisma.tag.count.mockResolvedValue(0);
59
+
60
+ await service.list({ skip: 0, take: 10, search: 'sale' });
61
+
62
+ const [call] = prisma.tag.findMany.mock.calls;
63
+ expect(call[0].where).toMatchObject({ OR: expect.any(Array) });
64
+ });
65
+
66
+ it('não aplica filtro quando search vazio', async () => {
67
+ prisma.tag.findMany.mockResolvedValue([]);
68
+ prisma.tag.count.mockResolvedValue(0);
69
+
70
+ await service.list({ skip: 0, take: 10, search: '' });
71
+
72
+ const [call] = prisma.tag.findMany.mock.calls;
73
+ expect(call[0].where).toEqual({});
74
+ });
75
+ });
76
+
77
+ describe('getStats', () => {
78
+ it('retorna contagens por status', async () => {
79
+ prisma.tag.count
80
+ .mockResolvedValueOnce(10)
81
+ .mockResolvedValueOnce(7)
82
+ .mockResolvedValueOnce(3);
83
+
84
+ const result = await service.getStats();
85
+
86
+ expect(result).toEqual({ total: 10, active: 7, inactive: 3 });
87
+ });
88
+ });
89
+
90
+ describe('create', () => {
91
+ it('lança BadRequestException para cor inválida', async () => {
92
+ await expect(
93
+ service.create('en', { slug: 'test', color: 'red', status: 'active' } as any),
94
+ ).rejects.toThrow(BadRequestException);
95
+ });
96
+
97
+ it('lança BadRequestException para cor sem #', async () => {
98
+ await expect(
99
+ service.create('en', { slug: 'test', color: 'ff0000' } as any),
100
+ ).rejects.toThrow(BadRequestException);
101
+ });
102
+
103
+ it('cria tag com cor hexadecimal válida de 6 dígitos', async () => {
104
+ const created = { id: 1, slug: 'promo', color: '#ff0000', status: 'active' };
105
+ prisma.tag.create.mockResolvedValue(created);
106
+
107
+ const result = await service.create('en', { slug: 'promo', color: '#ff0000' } as any);
108
+
109
+ expect(prisma.tag.create).toHaveBeenCalledWith(
110
+ expect.objectContaining({ data: expect.objectContaining({ slug: 'promo', color: '#ff0000' }) }),
111
+ );
112
+ expect(result).toMatchObject({ id: 1 });
113
+ });
114
+
115
+ it('cria tag com cor hexadecimal válida de 3 dígitos', async () => {
116
+ prisma.tag.create.mockResolvedValue({ id: 2, slug: 'sale', color: '#f00', status: 'active' });
117
+
118
+ const result = await service.create('en', { slug: 'sale', color: '#f00' } as any);
119
+
120
+ expect(result).toMatchObject({ id: 2 });
121
+ });
122
+
123
+ it('usa status active como padrão', async () => {
124
+ prisma.tag.create.mockResolvedValue({ id: 1, slug: 'x', color: '#aabbcc', status: 'active' });
125
+
126
+ await service.create('en', { slug: 'x', color: '#aabbcc' } as any);
127
+
128
+ expect(prisma.tag.create).toHaveBeenCalledWith(
129
+ expect.objectContaining({ data: expect.objectContaining({ status: 'active' }) }),
130
+ );
131
+ });
132
+ });
133
+
134
+ describe('getById', () => {
135
+ it('retorna tag quando encontrada', async () => {
136
+ prisma.tag.findUnique.mockResolvedValue({ id: 1, slug: 'promo', color: '#ff0000' });
137
+
138
+ const result = await service.getById(1, 'en');
139
+
140
+ expect(result).toMatchObject({ id: 1 });
141
+ });
142
+
143
+ it('lança BadRequestException quando tag não existe', async () => {
144
+ prisma.tag.findUnique.mockResolvedValue(null);
145
+
146
+ await expect(service.getById(999, 'en')).rejects.toThrow(BadRequestException);
147
+ });
148
+ });
149
+
150
+ describe('update', () => {
151
+ it('lança BadRequestException quando tag não existe', async () => {
152
+ prisma.tag.findUnique.mockResolvedValue(null);
153
+
154
+ await expect(service.update(999, { slug: 'x' }, 'en')).rejects.toThrow(BadRequestException);
155
+ });
156
+
157
+ it('atualiza campos fornecidos', async () => {
158
+ prisma.tag.findUnique.mockResolvedValue({ id: 1, slug: 'old', color: '#ff0000' });
159
+ prisma.tag.update.mockResolvedValue({ id: 1, slug: 'new', color: '#ff0000' });
160
+
161
+ const result = await service.update(1, { slug: 'new' }, 'en');
162
+
163
+ expect(prisma.tag.update).toHaveBeenCalledWith(
164
+ expect.objectContaining({ where: { id: 1 } }),
165
+ );
166
+ expect(result).toMatchObject({ id: 1, slug: 'new' });
167
+ });
168
+ });
169
+
170
+ describe('delete', () => {
171
+ it('lança BadRequestException quando tag não existe', async () => {
172
+ prisma.tag.findUnique.mockResolvedValue(null);
173
+
174
+ await expect(service.delete(999, 'en')).rejects.toThrow(BadRequestException);
175
+ });
176
+
177
+ it('deleta tag quando encontrada', async () => {
178
+ prisma.tag.findUnique.mockResolvedValue({ id: 1, slug: 'promo' });
179
+ prisma.tag.delete.mockResolvedValue({ id: 1 });
180
+
181
+ const result = await service.delete(1, 'en');
182
+
183
+ expect(prisma.tag.delete).toHaveBeenCalledWith({ where: { id: 1 } });
184
+ expect(result).toMatchObject({ id: 1 });
185
+ });
186
+ });
187
+ });