Skip to content

[API] Integration tests — restaurant and food item modules #189

Closed

Description

@zakkiyyat

Overview

Write a comprehensive integration test suite for the restaurant and food item modules using the same Vitest + Supertest + `mongodb-memory-server` pattern established in `apps/api/src/modules/auth/tests/auth.test.ts`. Tests must run without any external services — no real MongoDB, no S3.

Dependencies: Issues #180 (Restaurant module), #181 (Food item module), and #186 (Pagination/filtering) must be merged before this issue can be completed.


Test Files

```
apps/api/src/modules/restaurants/tests/restaurant.test.ts
apps/api/src/modules/food-items/tests/food-item.test.ts
```

Both files follow the same `beforeAll` / `afterEach` / `afterAll` setup as `auth.test.ts`:

```ts
let mongoServer: MongoMemoryServer;

beforeAll(async () => {
mongoServer = await MongoMemoryServer.create();
await mongoose.connect(mongoServer.getUri());
});

afterEach(async () => {
await mongoose.connection.dropDatabase();
});

afterAll(async () => {
await mongoose.disconnect();
await mongoServer.stop();
});
```


Restaurant Test Cases (`restaurant.test.ts`)

POST /api/restaurants

  • Returns 201 and the created restaurant for an authenticated user
  • Sets `ownerId` from the JWT — ignores any `ownerId` in the request body
  • Returns 401 for unauthenticated requests
  • Returns 400 with field errors when `name` is missing
  • Returns 400 with field errors when an invalid `cuisineTag` is submitted
  • Returns 409 when the authenticated user already owns a restaurant

GET /api/restaurants

  • Returns a paginated list of active restaurants
  • Does not include soft-deleted (`isActive: false`) restaurants
  • Respects `?page` and `?limit` params and returns correct pagination metadata
  • Filters by `?cuisine=italian` returning only matching restaurants
  • Returns an empty `data` array (not 404) when no restaurants match

GET /api/restaurants/:id

  • Returns the restaurant when it exists
  • Returns 404 for a non-existent ID
  • Returns 404 for a soft-deleted restaurant

GET /api/restaurants/me

  • Returns the authenticated user's restaurant
  • Returns 404 when the user has no restaurant
  • Returns 401 when unauthenticated

PATCH /api/restaurants/:id

  • Owner can update `name` and `description`
  • Returns 403 when a different authenticated user attempts the update
  • Returns 400 for invalid field values (e.g. name too long)

DELETE /api/restaurants/:id

  • Sets `isActive: false` on the document
  • The restaurant no longer appears in the public list after deletion
  • Returns 403 when a non-owner attempts deletion

Food Item Test Cases (`food-item.test.ts`)

POST /api/restaurants/:restaurantId/food-items

  • Returns 201 and the created food item for the restaurant owner
  • Returns 403 when a different authenticated user attempts creation
  • Returns 401 for unauthenticated requests
  • Returns 400 for invalid input (missing `name`, negative `price`, unknown `dietaryTag`)
  • Returns 404 when the `restaurantId` in the path does not exist

GET /api/restaurants/:restaurantId/food-items

  • Returns only `isAvailable: true` items for public requests
  • Returns all items (including unavailable) when the owner requests with `?includeUnavailable=true`
  • Returns correct pagination metadata
  • Returns 404 when the restaurant does not exist

GET /api/restaurants/:restaurantId/food-items/:id

  • Returns the food item when it exists
  • Returns 404 for a non-existent item ID
  • Returns 404 for a soft-deleted (unavailable) item on public requests

PATCH /api/restaurants/:restaurantId/food-items/:id

  • Owner can update `name`, `price`, `isAvailable`
  • Returns 403 for non-owner
  • Returns 400 for invalid updates

DELETE /api/restaurants/:restaurantId/food-items/:id

  • Sets `isAvailable: false`
  • Item no longer appears in public list
  • Returns 403 for non-owner

Helpers

Create a `tests/helpers/` directory with shared test utilities:

```
apps/api/src/tests/helpers/
create-user.ts # Register a user and return { token, userId }
create-restaurant.ts # Create a restaurant for a user and return it
create-food-item.ts # Create a food item and return it
```

These helpers eliminate boilerplate setup in each `describe` block and make test intent clear.


Acceptance Criteria

  • `npm run test -w @discoverly/api` passes all tests with no real external dependencies
  • Each test is independent — `afterEach` drops the database, so tests do not share state
  • All 35+ test cases above are covered
  • Test file import structure matches the rest of the codebase (no relative path hacks)
  • No test takes longer than 10 seconds individually

Activity

  1. sheyman546 commented on Jun 16, 2026

    @sheyman546

    please i will love to work on this issue and i will submit within 24hr with a quality pr thank you

  2. maramina commented on Jun 16, 2026

    @maramina

    I'd love to work on this issue. It aligns well with my experience, and I can deliver a clean, well-tested PR promptly.

  3. xeeenab commented on Jun 27, 2026

    @xeeenab
    Contributor

    can i pick this up?

  4. grantfox-oss commented on Jun 27, 2026

    @grantfox-oss

    🦊 GrantFox — @xeeenab has been assigned to this issue as part of the Official Campaign campaign!

    Next steps:

    1. Open a Pull Request referencing this issue (e.g., Closes #189)
    2. Your PR will be reviewed by the MixMatch-Inc maintainers

    Good luck! Track your progress on GrantFox.

  5. grantfox-oss commented on Jun 27, 2026

    @grantfox-oss

    🎉 This issue has been marked as completed on GrantFox as part of the Official Campaign campaign!

    @xeeenab's PR #200 was approved and merged by @zakkiyyat.

    🏆 @xeeenab: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (48 total points). Track your full progress on GrantFox.

    👏 Great work, @xeeenab! Keep contributing to MixMatch-Inc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

BACKENDBACKENDGrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaignintermediate~2–3 day effortsprint-1Sprint 1: Restaurant & Menu Foundation

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions