Skip to content

Add unit tests and fix errors for OM-268 - #88

Merged
leoAchu16 merged 9 commits into
devfrom
OM-268
Apr 8, 2026
Merged

leoAchu16 merged 9 commits into
devfrom
OM-268

Conversation

@CrisNAC

@CrisNAC CrisNAC commented Apr 8, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

Notas de Lanzamiento

  • Documentation

    • Agregada documentación OpenAPI completa para endpoints de gestión de imágenes (productos, tiendas y usuarios) y nuevo tag "Images" en Swagger UI.
  • Bug Fixes

    • Mejorado manejo de errores: operaciones de eliminación ahora retornan 404 cuando no existe imagen.
    • Ajuste en la validación de cargas para el límite de tamaño de imágenes.
  • Tests

    • Agregada suite de pruebas unitarias que cubre endpoints de imágenes, autenticación, permisos y respuestas de error.

@coderabbitai

coderabbitai Bot commented Apr 8, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@CrisNAC has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 46 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 13 minutes and 46 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ebdd1d4c-4245-44ed-949f-d2bbd22c16bf

📥 Commits

Reviewing files that changed from the base of the PR and between fae03bf and 53c6787.

📒 Files selected for processing (1)
  • src/config/swagger.config.js
📝 Walkthrough

Walkthrough

Se actualiza la invocación del límite de tamaño en el middleware de subida, se cambia la excepción lanzada por las funciones remove*Image a NotFoundError, se añaden esquemas y tags OpenAPI para imágenes, y se incorpora una suite de pruebas unitarias que cubre los endpoints de imágenes.

Changes

Cohort / File(s) Resumen
Servicios de imágenes
src/modules/images/services/product-image.service.js, src/modules/images/services/store-image.service.js, src/modules/images/services/user-image.service.js
Se reemplaza ValidationError por NotFoundError en las funciones removeProductImage, removeStoreImage y removeUserImage cuando no existe la imagen correspondiente. Revisar manejo de errores y tests que esperan códigos/formatos de error.
Middleware de subida
src/middlewares/upload.middleware.js
Se cambia IMAGE.MAX_SIZE_MB por IMAGE.MAX_SIZE_MB() al configurar limits.fileSize de multer; revisar que IMAGE.MAX_SIZE_MB sea una función accesible en runtime.
Documentación OpenAPI
src/config/swagger.config.js, src/docs/schemas/image.schema.js, src/docs/schemas/index.js
Se agregan esquemas de respuesta para imágenes, nuevo tag "Images", security cookieAuth por defecto y se exporta imageSchemas. Verificar integración con el spec y rutas documentadas.
Tests unitarios
tests/unit/images/image.test.js
Se añade una suite Vitest/Supertest extensa para endpoints de imágenes (products/stores/users), con mocks de prisma y servicios de imagen; cubre auth, permisos, validaciones y flujos CRUD de archivos. Atención a fixtures y mocks restaurados entre bloques.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • SebaKisser
  • leoAchu16
  • Andoumeda

Poem

🐰 Saltito y salto, traigo una rama de patch,
las imágenes ordenadas, con errores en su lugar,
pruebas que vigilan la senda del upload,
esquemas que brillan en el mapa OpenAPI,
¡celebro con orejas y una zanahoria en paz! 🥕✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive El título es genérico y amplio, utilizando el término vago 'fix errors' que no especifica claramente cuáles son los errores corregidos ni cuál es el cambio principal del conjunto de cambios. Considere ser más específico sobre los cambios principales, por ejemplo: 'Cambiar ValidationError por NotFoundError en servicios de imágenes' o 'Agregar tests unitarios y corregir manejo de errores en endpoints de imágenes'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch OM-268

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/docs/image.schema.js`:
- Around line 3-47: The new OpenAPI schemas defined in imageSchemas are not
being picked up because imageSchemas is not merged into the global
components.schemas and this file is not included in the Swagger `apis` glob;
update the Swagger setup to import/require imageSchemas and merge its entries
into the existing components.schemas (e.g., extend the object used to build
swaggerSpec/components.schemas) and add this file's path pattern to the Swagger
`apis` array/glob so the new components and any JSDoc comments are parsed and
published.

In `@tests/unit/images/image.test.js`:
- Around line 166-173: The test "devuelve 403 cuando no hay token" is sending a
role header via asRole and asserting 403; change it to actually omit the
authorization header by calling
request(app).put("/products/1/image").attach("image", fakeFile, "test.jpg")
directly (or modify the asRole helper to not add any headers), and update the
assertion to expect 401 instead of 403; locate the assertion
expect(res.status).toBe(403) and the request call to adjust accordingly.
- Line 67: The tests are leaking mock implementations because beforeEach
currently calls vi.clearAllMocks(), which only clears call history; replace
those calls with vi.resetAllMocks() (or add vi.resetAllMocks() alongside
clearAllMocks) to reset mock implementations like mockResolvedValue in the
beforeEach blocks (refer to the existing beforeEach(() => vi.clearAllMocks())
occurrences in this file and the other two occurrences around the same spots) so
each test starts with clean mock implementations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 04b88814-26fd-4cf3-8a62-7a658344a81a

📥 Commits

Reviewing files that changed from the base of the PR and between 01f5a03 and eb46362.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • src/docs/image.schema.js
  • src/middlewares/upload.middleware.js
  • src/modules/images/services/product-image.service.js
  • src/modules/images/services/store-image.service.js
  • src/modules/images/services/user-image.service.js
  • tests/unit/images/image.test.js

Comment thread src/docs/schemas/image.schema.js
Comment thread tests/unit/images/image.test.js Outdated
Comment thread tests/unit/images/image.test.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
tests/unit/images/image.test.js (1)

166-173: ⚠️ Potential issue | 🟠 Major

El test “sin token” está armado con autenticación y valida el status incorrecto.

En Line 166 el nombre del caso dice “no hay token”, pero en Line 167-170 se envía x-test-role: seller; eso no es anónimo. Por eso el flujo termina en otro estado (hoy 404 en pipeline), no en el esperado para falta de auth.

✅ Ajuste sugerido
-    it("devuelve 403 cuando no hay token", async () => {
-      const res = await asRole(
-        request(app).put("/products/1/image").attach("image", fakeFile, "test.jpg"),
-        "seller"
-      )
-
-      expect(res.status).toBe(403);
-    });
+    it("devuelve 401 cuando no hay token", async () => {
+      const res = await request(app)
+        .put("/products/1/image")
+        .attach("image", fakeFile, "test.jpg");
+
+      expect(res.status).toBe(401);
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/images/image.test.js` around lines 166 - 173, El test "devuelve
403 cuando no hay token" está enviando autenticación usando asRole, por eso no
simula un request anónimo; actualiza la llamada que usa
asRole(request(app).put("/products/1/image").attach("image", fakeFile,
"test.jpg"), "seller") para que sea un request sin cabeceras de auth (por
ejemplo llamar directamente request(app).put("/products/1/image").attach(...)) y
mantener expect(res.status).toBe(403); alternativamente cambia el nombre del
caso si quieres mantener el helper asRole; revisa los símbolos
request(app).put("/products/1/image"), attach("image", fakeFile, "test.jpg") y
asRole para ubicar el cambio.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/config/swagger.config.js`:
- Around line 71-79: El bloque security está mal ubicado fuera del objeto
OpenAPI y el glob de apis no incluye subdirectorios; mueve la propiedad security
dentro de la clave definition (junto a openapi/info/components/paths) para que
forme parte del documento OpenAPI y actualiza el arreglo apis para usar un
recursive glob como "./src/docs/**/*.schema.js" (o similar) para capturar
schemas en subdirectorios; busca las referencias a security y definition en
swagger-jsdoc configuration y ajusta la entrada apis para incluir patrones
recursivos.

---

Duplicate comments:
In `@tests/unit/images/image.test.js`:
- Around line 166-173: El test "devuelve 403 cuando no hay token" está enviando
autenticación usando asRole, por eso no simula un request anónimo; actualiza la
llamada que usa asRole(request(app).put("/products/1/image").attach("image",
fakeFile, "test.jpg"), "seller") para que sea un request sin cabeceras de auth
(por ejemplo llamar directamente
request(app).put("/products/1/image").attach(...)) y mantener
expect(res.status).toBe(403); alternativamente cambia el nombre del caso si
quieres mantener el helper asRole; revisa los símbolos
request(app).put("/products/1/image"), attach("image", fakeFile, "test.jpg") y
asRole para ubicar el cambio.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fcac841e-61d4-4881-b61a-f84731912860

📥 Commits

Reviewing files that changed from the base of the PR and between eb46362 and 86000cf.

📒 Files selected for processing (4)
  • src/config/swagger.config.js
  • src/docs/schemas/image.schema.js
  • src/docs/schemas/index.js
  • tests/unit/images/image.test.js
✅ Files skipped from review due to trivial changes (1)
  • src/docs/schemas/index.js

Comment thread src/config/swagger.config.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/unit/images/image.test.js (2)

208-221: Fortalecer los tests de DELETE exitoso con asserts de efectos laterales.

Hoy validan status/body, pero no que se ejecuten update, extractFilePath y deleteImage con argumentos correctos.

🔍 Propuesta (ejemplo en product delete)
   it("devuelve 200 cuando la imagen se elimina correctamente", async () => {
     prisma.products.findUnique.mockResolvedValue({ ...mockProduct, image_url: IMAGE_URL, store: { fk_user: 10 } });
     extractFilePath.mockReturnValue("1/image.jpg");
     prisma.products.update.mockResolvedValue({ ...mockProduct, image_url: null });
     deleteImage.mockResolvedValue();

     const res = await asRole(
       request(app).delete("/products/1/image"),
       "seller"
     )

     expect(res.status).toBe(200);
     expect(res.body.message).toMatch(/eliminada/i);
+    expect(extractFilePath).toHaveBeenCalledWith(IMAGE_URL, expect.any(String));
+    expect(prisma.products.update).toHaveBeenCalledWith({
+      where: { id_product: 1 },
+      data: { image_url: null },
+    });
+    expect(deleteImage).toHaveBeenCalled();
   });

Also applies to: 318-331, 442-455

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/images/image.test.js` around lines 208 - 221, El test "devuelve
200 cuando la imagen se elimina correctamente" verifica solo status/body; añade
assertions que confirmen los efectos laterales: verifica que
prisma.products.findUnique fue llamado con el id correcto (e.g. 1), que
extractFilePath se llamó con el valor IMAGE_URL, que deleteImage se llamó con la
ruta devuelta por extractFilePath ("1/image.jpg") y que prisma.products.update
fue llamado para dejar image_url en null para el mismo producto; aplica el mismo
patrón de aserciones en los otros casos referenciados (los tests en las
secciones alrededor de las líneas 318-331 y 442-455) para garantizar que las
funciones mock (prisma.products.update, extractFilePath, deleteImage) reciban
los argumentos esperados y que el orden lógico se respete.

306-332: Agregar caso 401 en DELETE /stores/:id/image para paridad de cobertura.

En este bloque faltaría el escenario “sin token”, que sí está contemplado en product/user delete.

➕ Propuesta de test
 describe("DELETE /stores/:id/image", () => {
+  it("devuelve 401 cuando no hay token", async () => {
+    const res = await request(app).delete("/stores/1/image");
+    expect(res.status).toBe(401);
+  });
+
   it("devuelve 404 cuando el comercio no tiene logo", async () => {
     prisma.stores.findUnique.mockResolvedValue({ ...mockStore, fk_user: 10 });

     const res = await asRole(
       request(app).delete("/stores/1/image"),
       "seller"
     )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/images/image.test.js` around lines 306 - 332, Add a 401 test case
for DELETE /stores/:id/image that covers the "sin token" scenario: in the same
describe("DELETE /stores/:id/image") block add an it that sends
request(app).delete("/stores/1/image") without wrapping in asRole, does not set
auth headers, and expects res.status toBe(401) (and optionally message toMatch
/token|autentic/i); also assert that downstream mocks like
prisma.stores.findUnique, prisma.stores.update, extractFilePath, and deleteImage
were not called to ensure the request was rejected early.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/unit/images/image.test.js`:
- Around line 208-221: El test "devuelve 200 cuando la imagen se elimina
correctamente" verifica solo status/body; añade assertions que confirmen los
efectos laterales: verifica que prisma.products.findUnique fue llamado con el id
correcto (e.g. 1), que extractFilePath se llamó con el valor IMAGE_URL, que
deleteImage se llamó con la ruta devuelta por extractFilePath ("1/image.jpg") y
que prisma.products.update fue llamado para dejar image_url en null para el
mismo producto; aplica el mismo patrón de aserciones en los otros casos
referenciados (los tests en las secciones alrededor de las líneas 318-331 y
442-455) para garantizar que las funciones mock (prisma.products.update,
extractFilePath, deleteImage) reciban los argumentos esperados y que el orden
lógico se respete.
- Around line 306-332: Add a 401 test case for DELETE /stores/:id/image that
covers the "sin token" scenario: in the same describe("DELETE
/stores/:id/image") block add an it that sends
request(app).delete("/stores/1/image") without wrapping in asRole, does not set
auth headers, and expects res.status toBe(401) (and optionally message toMatch
/token|autentic/i); also assert that downstream mocks like
prisma.stores.findUnique, prisma.stores.update, extractFilePath, and deleteImage
were not called to ensure the request was rejected early.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a9c1bc6b-3577-43bb-a0ff-aafdb1632397

📥 Commits

Reviewing files that changed from the base of the PR and between 86000cf and fae03bf.

📒 Files selected for processing (1)
  • tests/unit/images/image.test.js

@CrisNAC

CrisNAC commented Apr 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leoAchu16
leoAchu16 merged commit 498ff72 into dev Apr 8, 2026
2 checks passed
@Andoumeda
Andoumeda deleted the OM-268 branch April 11, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants