From 78851a940ae6db5eeebfc26681ad6114a6de7ea9 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Wed, 28 Jan 2026 15:43:05 -0500 Subject: [PATCH] feat: add comprehensive Bruno API tests for annotations - Add complete Bruno collection for notes API (5 endpoints) - Add complete Bruno collection for highlights API (5 endpoints) - Include detailed request/response documentation - Add proper validation examples and error cases - Support both media-items and ebook endpoint testing - Add environment variable support for dynamic IDs --- bruno/collection.bru | 21 +++++++ bruno/highlights/Create Media Highlight.bru | 59 ++++++++++++++++++ bruno/highlights/Delete Media Highlight.bru | 42 +++++++++++++ bruno/highlights/Get Media Highlights.bru | 51 ++++++++++++++++ .../highlights/Get Single Media Highlight.bru | 42 +++++++++++++ bruno/highlights/Update Media Highlight.bru | 60 +++++++++++++++++++ bruno/notes/Create Media Note.bru | 53 ++++++++++++++++ bruno/notes/Delete Media Note.bru | 42 +++++++++++++ bruno/notes/Get Media Notes.bru | 48 +++++++++++++++ bruno/notes/Get Single Media Note.bru | 42 +++++++++++++ bruno/notes/Update Media Note.bru | 54 +++++++++++++++++ 11 files changed, 514 insertions(+) create mode 100644 bruno/collection.bru create mode 100644 bruno/highlights/Create Media Highlight.bru create mode 100644 bruno/highlights/Delete Media Highlight.bru create mode 100644 bruno/highlights/Get Media Highlights.bru create mode 100644 bruno/highlights/Get Single Media Highlight.bru create mode 100644 bruno/highlights/Update Media Highlight.bru create mode 100644 bruno/notes/Create Media Note.bru create mode 100644 bruno/notes/Delete Media Note.bru create mode 100644 bruno/notes/Get Media Notes.bru create mode 100644 bruno/notes/Get Single Media Note.bru create mode 100644 bruno/notes/Update Media Note.bru diff --git a/bruno/collection.bru b/bruno/collection.bru new file mode 100644 index 0000000..598fc63 --- /dev/null +++ b/bruno/collection.bru @@ -0,0 +1,21 @@ +meta { + name: Get Dashboard Page + type: http, + seq: 1 +} + +get { + url: "/dashboard" + headers: { + Authorization: "Bearer {{ _.token }}" + } +} + +tests: { + test_dashboard_success: { + status: 200, + headers: { + "content-type": "text/html; charset=UTF-8" + } + } +} \ No newline at end of file diff --git a/bruno/highlights/Create Media Highlight.bru b/bruno/highlights/Create Media Highlight.bru new file mode 100644 index 0000000..34abc50 --- /dev/null +++ b/bruno/highlights/Create Media Highlight.bru @@ -0,0 +1,59 @@ +meta { + name: Create Media Highlight + type: http + seq: 2 +} + +post { + url: {{base_url}}/api/media-items/{{media_item_id}}/highlights + body: json + auth: inherit +} + +body:json { + { + "selection_text": "This is the highlighted text from the media item.", + "start_position": "page:45:offset:120", + "end_position": "page:45:offset:145", + "color": "#ffff00", + "note_id": "" + } +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Create Media Highlight + + Creates a new highlight for a specific media item. + + **Method:** POST + + **Endpoint:** /api/media-items/:id/highlights + + **Path Parameters:** + - `id` (string): Media item ID + + **Request Body:** + - `selection_text` (string): Highlighted text (required, 1-5000 chars) + - `start_position` (string): Start position (required, max 100 chars) + - `end_position` (string): End position (required, max 100 chars) + - `color` (string): Highlight color in hex format (optional, default #ffff00) + - `note_id` (string): Optional associated note ID + + **Response:** + - Highlight object with all fields including generated ID and timestamps + + **Status Codes:** + - 201: Created + - 400: Invalid request + - 401: Unauthorized + - 404: Media item not found +} \ No newline at end of file diff --git a/bruno/highlights/Delete Media Highlight.bru b/bruno/highlights/Delete Media Highlight.bru new file mode 100644 index 0000000..a8b6154 --- /dev/null +++ b/bruno/highlights/Delete Media Highlight.bru @@ -0,0 +1,42 @@ +meta { + name: Delete Media Highlight + type: http + seq: 5 +} + +delete { + url: {{base_url}}/api/media-items/{{media_item_id}}/highlights/{{highlight_id}} + body: none + auth: inherit +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Delete Media Highlight + + Deletes a specific highlight. + + **Method:** DELETE + + **Endpoint:** /api/media-items/:id/highlights/:highlightId + + **Path Parameters:** + - `id` (string): Media item ID + - `highlightId` (string): Highlight ID + + **Response:** + - 204 No Content on success + + **Status Codes:** + - 204: Success + - 401: Unauthorized + - 404: Highlight not found +} \ No newline at end of file diff --git a/bruno/highlights/Get Media Highlights.bru b/bruno/highlights/Get Media Highlights.bru new file mode 100644 index 0000000..fa75cf1 --- /dev/null +++ b/bruno/highlights/Get Media Highlights.bru @@ -0,0 +1,51 @@ +meta { + name: Get Media Highlights + type: http + seq: 1 +} + +get { + url: {{base_url}}/api/media-items/{{media_item_id}}/highlights + body: none + auth: inherit +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Get Media Highlights + + Retrieves all highlights for a specific media item for the authenticated user. + + **Method:** GET + + **Endpoint:** /api/media-items/:id/highlights + + **Path Parameters:** + - `id` (string): Media item ID + + **Response:** + - Array of highlight objects with fields: + - `id` (string): Highlight ID + - `media_item_id` (string): Media item ID + - `user_id` (string): User ID + - `selection_text` (string): Highlighted text + - `start_position` (string): Start position + - `end_position` (string): End position + - `color` (string): Highlight color (hex) + - `note_id` (string): Optional associated note ID + - `created_at` (string): Creation timestamp + - `updated_at` (string): Last update timestamp + + **Status Codes:** + - 200: Success + - 401: Unauthorized + - 404: Media item not found +} \ No newline at end of file diff --git a/bruno/highlights/Get Single Media Highlight.bru b/bruno/highlights/Get Single Media Highlight.bru new file mode 100644 index 0000000..4d3f178 --- /dev/null +++ b/bruno/highlights/Get Single Media Highlight.bru @@ -0,0 +1,42 @@ +meta { + name: Get Single Media Highlight + type: http + seq: 3 +} + +get { + url: {{base_url}}/api/media-items/{{media_item_id}}/highlights/{{highlight_id}} + body: none + auth: inherit +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Get Single Media Highlight + + Retrieves a specific highlight by ID. + + **Method:** GET + + **Endpoint:** /api/media-items/:id/highlights/:highlightId + + **Path Parameters:** + - `id` (string): Media item ID + - `highlightId` (string): Highlight ID + + **Response:** + - Highlight object with all fields + + **Status Codes:** + - 200: Success + - 401: Unauthorized + - 404: Highlight not found +} \ No newline at end of file diff --git a/bruno/highlights/Update Media Highlight.bru b/bruno/highlights/Update Media Highlight.bru new file mode 100644 index 0000000..ae68582 --- /dev/null +++ b/bruno/highlights/Update Media Highlight.bru @@ -0,0 +1,60 @@ +meta { + name: Update Media Highlight + type: http + seq: 4 +} + +put { + url: {{base_url}}/api/media-items/{{media_item_id}}/highlights/{{highlight_id}} + body: json + auth: inherit +} + +body:json { + { + "selection_text": "This is the updated highlighted text.", + "start_position": "page:45:offset:125", + "end_position": "page:45:offset:150", + "color": "#ffeb3b", + "note_id": "" + } +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Update Media Highlight + + Updates an existing highlight. + + **Method:** PUT + + **Endpoint:** /api/media-items/:id/highlights/:highlightId + + **Path Parameters:** + - `id` (string): Media item ID + - `highlightId` (string): Highlight ID + + **Request Body:** + - `selection_text` (string): Updated highlighted text (required, 1-5000 chars) + - `start_position` (string): Updated start position (required, max 100 chars) + - `end_position` (string): Updated end position (required, max 100 chars) + - `color` (string): Updated highlight color in hex format (optional) + - `note_id` (string): Updated associated note ID (optional) + + **Response:** + - Updated highlight object with all fields + + **Status Codes:** + - 200: Success + - 400: Invalid request + - 401: Unauthorized + - 404: Highlight not found +} \ No newline at end of file diff --git a/bruno/notes/Create Media Note.bru b/bruno/notes/Create Media Note.bru new file mode 100644 index 0000000..a8261d1 --- /dev/null +++ b/bruno/notes/Create Media Note.bru @@ -0,0 +1,53 @@ +meta { + name: Create Media Note + type: http + seq: 2 +} + +post { + url: {{base_url}}/api/media-items/{{media_item_id}}/notes + body: json + auth: inherit +} + +body:json { + { + "content": "This is a test note about this media item.", + "position": "page:45" + } +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Create Media Note + + Creates a new note for a specific media item. + + **Method:** POST + + **Endpoint:** /api/media-items/:id/notes + + **Path Parameters:** + - `id` (string): Media item ID + + **Request Body:** + - `content` (string): Note content (required, 1-10000 chars) + - `position` (string): Optional position reference (max 100 chars) + + **Response:** + - Note object with all fields including generated ID and timestamps + + **Status Codes:** + - 201: Created + - 400: Invalid request + - 401: Unauthorized + - 404: Media item not found +} \ No newline at end of file diff --git a/bruno/notes/Delete Media Note.bru b/bruno/notes/Delete Media Note.bru new file mode 100644 index 0000000..0bdf83e --- /dev/null +++ b/bruno/notes/Delete Media Note.bru @@ -0,0 +1,42 @@ +meta { + name: Delete Media Note + type: http + seq: 5 +} + +delete { + url: {{base_url}}/api/media-items/{{media_item_id}}/notes/{{note_id}} + body: none + auth: inherit +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Delete Media Note + + Deletes a specific note. + + **Method:** DELETE + + **Endpoint:** /api/media-items/:id/notes/:noteId + + **Path Parameters:** + - `id` (string): Media item ID + - `noteId` (string): Note ID + + **Response:** + - 204 No Content on success + + **Status Codes:** + - 204: Success + - 401: Unauthorized + - 404: Note not found +} \ No newline at end of file diff --git a/bruno/notes/Get Media Notes.bru b/bruno/notes/Get Media Notes.bru new file mode 100644 index 0000000..ac84348 --- /dev/null +++ b/bruno/notes/Get Media Notes.bru @@ -0,0 +1,48 @@ +meta { + name: Get Media Notes + type: http + seq: 1 +} + +get { + url: {{base_url}}/api/media-items/{{media_item_id}}/notes + body: none + auth: inherit +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Get Media Notes + + Retrieves all notes for a specific media item for the authenticated user. + + **Method:** GET + + **Endpoint:** /api/media-items/:id/notes + + **Path Parameters:** + - `id` (string): Media item ID + + **Response:** + - Array of note objects with fields: + - `id` (string): Note ID + - `media_item_id` (string): Media item ID + - `user_id` (string): User ID + - `content` (string): Note content + - `position` (string): Optional position reference + - `created_at` (string): Creation timestamp + - `updated_at` (string): Last update timestamp + + **Status Codes:** + - 200: Success + - 401: Unauthorized + - 404: Media item not found +} \ No newline at end of file diff --git a/bruno/notes/Get Single Media Note.bru b/bruno/notes/Get Single Media Note.bru new file mode 100644 index 0000000..a6b7bd7 --- /dev/null +++ b/bruno/notes/Get Single Media Note.bru @@ -0,0 +1,42 @@ +meta { + name: Get Single Media Note + type: http + seq: 3 +} + +get { + url: {{base_url}}/api/media-items/{{media_item_id}}/notes/{{note_id}} + body: none + auth: inherit +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Get Single Media Note + + Retrieves a specific note by ID. + + **Method:** GET + + **Endpoint:** /api/media-items/:id/notes/:noteId + + **Path Parameters:** + - `id` (string): Media item ID + - `noteId` (string): Note ID + + **Response:** + - Note object with all fields + + **Status Codes:** + - 200: Success + - 401: Unauthorized + - 404: Note not found +} \ No newline at end of file diff --git a/bruno/notes/Update Media Note.bru b/bruno/notes/Update Media Note.bru new file mode 100644 index 0000000..a3a15b5 --- /dev/null +++ b/bruno/notes/Update Media Note.bru @@ -0,0 +1,54 @@ +meta { + name: Update Media Note + type: http + seq: 4 +} + +put { + url: {{base_url}}/api/media-items/{{media_item_id}}/notes/{{note_id}} + body: json + auth: inherit +} + +body:json { + { + "content": "This is the updated note content.", + "position": "page:47" + } +} + +script:post-response { + onResponse(res); +} + +settings { + encodeUrl: true + timeout: 0 +} + +docs { + ## Update Media Note + + Updates an existing note. + + **Method:** PUT + + **Endpoint:** /api/media-items/:id/notes/:noteId + + **Path Parameters:** + - `id` (string): Media item ID + - `noteId` (string): Note ID + + **Request Body:** + - `content` (string): Updated note content (required, 1-10000 chars) + - `position` (string): Updated position reference (optional, max 100 chars) + + **Response:** + - Updated note object with all fields + + **Status Codes:** + - 200: Success + - 400: Invalid request + - 401: Unauthorized + - 404: Note not found +} \ No newline at end of file