Files
Oxicloud/tests/api/README.md
T
2026-05-11 20:00:22 +02:00

158 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API functional tests
Tests are written using [Hurl](https://hurl.dev) — a plain-text, CLI-first HTTP testing tool.
## Prerequisites
- [Hurl](https://hurl.dev/docs/installation.html) ≥ 4.0
Install: `cargo install hurl` or via your package manager
## Configuration
Edit `test.env` to match your local instance. This file is the single source of
truth: `run.sh` sources it for shell variables and passes it to Hurl as
`--variables-file`.
```
base_url=http://localhost:8087
username=admin
email=admin@example.com
password=TestPassword1!
```
## Running the tests
```bash
# First-time setup (run once on a fresh instance)
hurl --variables-file tests/api/test.env --test tests/api/setup.hurl
# Contacts CRUD scenario
hurl --variables-file tests/api/test.env --test tests/api/contacts.hurl
# All scenarios at once
hurl --variables-file tests/api/test.env --test tests/api/setup.hurl tests/api/contacts.hurl
# With full request/response output
hurl --variables-file tests/api/test.env --test --verbose tests/api/contacts.hurl
# Generate an HTML report
hurl --variables-file tests/api/test.env --test --report-html /tmp/hurl-report tests/api/contacts.hurl
```
## Test files
| File | Description |
|---|---|
| `setup.hurl` | One-time admin account creation; also asserts the endpoint is locked afterwards |
| `files-folders.hurl` | Files & folders CRUD scenario (22 steps, see below) |
| `favorites.hurl` | Favorites add/list/remove scenario (11 steps); depends on `files-folders.hurl` state |
| `trash.hurl` | Trash move/restore/purge scenario (16 steps); depends on `files-folders.hurl` state |
| `recent.hurl` | Recent items record/list/clear scenario (6 steps); depends on `files-folders.hurl` state |
| `contacts.hurl` | Full contacts CRUD scenario (14 steps, see below) |
| `test.env` | Variables: `base_url`, `username`, `email`, `password` — used by both Hurl and `run.sh` |
## Scenario: `files-folders.hurl`
| Step | Description |
|---|---|
| 1 | Login – capture JWT token |
| 2 | List root folders – assert exactly 1 (home folder), capture `home_folder_id`, assert `parent_id` is null |
| 3 | Browse home folder sub-folders – assert empty |
| 4 | Browse home folder files – assert empty |
| 5 | Create folder named `"/"` – assert HTTP 400, `error_type == "Invalid Input"` |
| 6 | Create `test1` inside home folder – capture `test1_id`, assert `parent_id` == `home_folder_id` |
| 7 | Create `test2` inside `test1` – capture `test2_id`, assert `parent_id` == `test1_id` |
| 8 | Browse home folder – assert exactly 1 sub-folder (`test1`) |
| 9 | Browse `test1` – assert exactly 1 sub-folder (`test2`), assert `parent_id` |
| 10 | Upload `fixtures/hello.txt` into `test2` – capture `file_id`, assert name/size/mime_type/folder_id |
| 11 | List files in `test2` – assert count=1, `mime_type == text/plain`, `icon_class == fas fa-file-alt` |
| 12 | Move `test2` from `test1` into home folder – assert `parent_id` == `home_folder_id` |
| 13 | Browse `test1` – assert empty (no more children) |
| 14 | Browse home folder – assert 2 sub-folders (`test1` and `test2`) |
| 15 | Rename `test2` → `test2-renamed` – assert new name, `parent_id` unchanged |
| 16 | Rename `hello.txt` → `hello-renamed.txt` – assert new name, `folder_id` unchanged |
| 17 | Rename `hello-renamed.txt` to `"."` – assert HTTP 400, `error_type == "Invalid Input"` |
| 18 | Upload `fixtures/oxicloud-logo.jpg` into home folder – capture `logo_id`, assert `mime_type == image/jpeg` |
| 19 | List files in home folder – assert count=1, `icon_class == fas fa-file-image` |
| 20 | `GET /api/files/{logo_id}/thumbnail/icon` → HTTP 200 |
| 21 | `GET /api/files/{logo_id}/thumbnail/preview` → HTTP 200 |
| 22 | `GET /api/files/{logo_id}/thumbnail/large` → HTTP 200 |
## Scenario: `favorites.hurl`
Depends on `files-folders.hurl` having run first (test1, test2-renamed/hello-renamed.txt must exist).
| Step | Description |
|---|---|
| 1 | Login – capture JWT token |
| 2 | Assert no favorites yet |
| 3 | Discover item IDs: home folder → contents (test1=$[0], test2-renamed=$[1]) → files in test2-renamed |
| 4 | `POST /api/favorites/file/{file_id}` – add hello-renamed.txt → HTTP 201 |
| 5 | List favorites – assert count=1, item_type=file, item_name=hello-renamed.txt |
| 6 | `POST /api/favorites/folder/{test1_id}` – add test1 → HTTP 201 |
| 7 | List favorites – assert count=2, both IDs present (order-independent) |
| 8 | `DELETE /api/favorites/file/{file_id}` – remove hello-renamed.txt → HTTP 200 |
| 9 | List favorites – assert count=1, item_type=folder, item_name=test1 |
| 10 | Cleanup: `DELETE /api/favorites/folder/{test1_id}` → HTTP 200 |
| 11 | List favorites – assert count=0 |
## Scenario: `trash.hurl`
Depends on `files-folders.hurl` having run first (home folder must exist).
| Step | Description |
|---|---|
| 1 | Login – capture JWT token |
| 2 | Assert trash is empty |
| 3 | Capture home folder ID |
| 4 | Create `to-delete` folder in home folder – capture `to_delete_id` |
| 5 | Upload `hello.txt` into `to-delete` |
| 6 | `DELETE /api/folders/{to_delete_id}` – moves folder to trash → HTTP 204 |
| 7 | List trash – assert count=1, item_type=folder, name=to-delete, original_id matches; capture `trash_id` |
| 8 | List home folder contents – assert `to-delete` is not present |
| 9 | `POST /api/trash/{trash_id}/restore` → HTTP 200, `success == true` |
| 10 | List home folder contents – assert `to-delete` is present |
| 11 | List files in `to-delete` – assert count=1, name=hello.txt |
| 12 | List trash – assert empty (restore removed the entry) |
| 13 | `DELETE /api/folders/{to_delete_id}` – move restored folder to trash again → HTTP 204 |
| 14 | `DELETE /api/trash/empty` – purge trash → HTTP 200, `success == true` |
| 15 | List trash – assert empty after purge |
| 16 | List home folder contents – assert `to-delete` is not present (permanently gone) |
## Scenario: `recent.hurl`
Depends on `files-folders.hurl` having run first (test2-renamed/hello-renamed.txt must exist).
Recent items are not auto-recorded on upload — step 3 explicitly registers the access.
| Step | Description |
|---|---|
| 1 | Login – capture JWT token |
| 2 | Discover `file_id` of hello-renamed.txt via home folder → test2-renamed contents |
| 3 | `POST /api/recent/file/{file_id}` – record access → HTTP 200 |
| 4 | `GET /api/recent` – assert count=1, item_type=file, item_name=hello-renamed.txt |
| 5 | `DELETE /api/recent/clear` – clear all recent items → HTTP 200 |
| 6 | `GET /api/recent` – assert count=0 |
## Scenario: `contacts.hurl`
| Step | Description |
|---|---|
| 1 | Login – capture JWT token |
| 2 | List address books – assert system book is present and read-only |
| 3 | Create personal address book – capture `book_id` |
| 4 | List contacts in new book – assert empty |
| 5 | Create contact John Doe – capture `contact_id` |
| 6 | List contacts – assert exactly 1 result with John Doe's id |
| 7 | Get John Doe – assert all fields, capture `ETag` |
| 8 | Update John Doe (nickname, org, notes) with `If-Match` – assert new values, capture refreshed `ETag` |
| 9 | Delete John Doe with `If-Match` |
| 10 | List contacts – assert empty again |
| 11 | Delete personal address book |
| 12 | List address books – assert `book_id` no longer present |
| 13 | List system address book – assert non-empty collection of OxiCloud users |
## Legacy bash tests
`test.sh` and `common.sh` are the original curl/bash scripts kept for reference.
Run them with `bash tests/api/test.sh` from the repo root (requires `jq`).