{"id":31644430,"url":"https://github.com/yoavmosco/gorest-users-tests","last_synced_at":"2025-10-07T04:52:43.559Z","repository":{"id":314623717,"uuid":"1056173322","full_name":"yoavmosco/gorest-users-tests","owner":"yoavmosco","description":"Postman tests for GoRest Users API (QA portfolio)","archived":false,"fork":false,"pushed_at":"2025-09-29T13:54:45.000Z","size":156,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-29T15:30:00.157Z","etag":null,"topics":["api-testing","portfolio","postman","qa"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yoavmosco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-13T14:42:37.000Z","updated_at":"2025-09-29T13:54:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"acdf0935-e52f-4832-8296-907a2a1f8378","html_url":"https://github.com/yoavmosco/gorest-users-tests","commit_stats":null,"previous_names":["yoavmosco/gorest-users-tests"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yoavmosco/gorest-users-tests","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavmosco%2Fgorest-users-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavmosco%2Fgorest-users-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavmosco%2Fgorest-users-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavmosco%2Fgorest-users-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yoavmosco","download_url":"https://codeload.github.com/yoavmosco/gorest-users-tests/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yoavmosco%2Fgorest-users-tests/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278722768,"owners_count":26034461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-testing","portfolio","postman","qa"],"created_at":"2025-10-07T04:52:41.114Z","updated_at":"2025-10-07T04:52:43.552Z","avatar_url":"https://github.com/yoavmosco.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# API Testing \u0026 Automation Project (GoREST public API)\n\n[![Newman API tests](https://github.com/yoavmosco/gorest-users-tests/actions/workflows/newman.yml/badge.svg)](https://github.com/yoavmosco/gorest-users-tests/actions/workflows/newman.yml)\n\nTests for GoREST **Users** API focusing on happy-path, negative, pagination (strict), boundary, and error-message quality.\n\n## What’s covered\n- Folder-level checks (status / array / light schema).\n- Request-level assertions for each scenario under `/users`.\n- **Pagination (strict)**:\n  - Page 2 has **no overlap** with Page 1 (0 shared IDs).\n  - Invalid `page` (e.g. `-1`) returns the **same item set** as Page 1 (order-agnostic).\n- **Error quality audits**: verify clarity for 4xx (duplicate email, invalid enums).\n\n## How to run (Postman UI)\n1. Import collection: `postman/GoREST Users Tests.postman_collection.json`\n2. Import environment: `postman/env/GoREST Local.postman_environment.json`\n3. **Set environment variables:**\n   - `token` → insert your personal GoREST API token (never commit it to Git).\n   - `mockBaseUrl` → insert your own Postman Mock Server URL (see [Mock-based TDD](#mock-based-tdd-postman-mock-server)).\n   - `baseUrl` is already preconfigured in the environment file.\n4. Run folders:\n   - Pagination: run page=1 → page=2 → invalid.\n   - Negative / Email: **Seed (201)** → **Duplicate (422)** → **Cleanup (204)**.\n   - Other 422 tests (missing/invalid format) are independent.\n\n## How to run (Newman CLI)\nThis project also includes a ready-to-run Newman setup.\n\n### Prerequisites\n- [Node.js](https://nodejs.org/) (v16+)\n- Run `npm install` in the project root to install `newman` and `newman-reporter-htmlextra`.\n\n### Run Locally\nRuns the collection with your local **secret** environment and generates an HTML report:\n\n```bash\nnpm run test:api\n```\n\u003e Note: make sure to provide your own valid values in the environment file (`postman/env/GoREST Local.postman_environment.json`) before running:\n\u003e - `token` → your personal GoREST API token\n\u003e - `mockBaseUrl` → your Postman Mock Server URL\n\n### Running specific folders\nUseful when you want to run only a subset (e.g., skip mocks):\n```bash\nnpx newman run \"postman/collection/GoREST Users Tests.postman_collection.json\" \\\n  -e \"postman/env/GoREST Local.postman_environment.json\" \\\n  --folder \"Pagination\" \\\n  --folder \"Negative\"\n```\n\n### Fail-fast (bail)  \nStop early when failures occur:\n\n```bash\n# Stop on the first failing request/test\nnpx newman run \"postman/collection/GoREST Users Tests.postman_collection.json\" \\\n  -e \"postman/env/GoREST Local.postman_environment.json\" \\\n  --bail\n```\n\n```bash\n# Stop when the first folder fails (continue within a folder, but stop when a folder overall fails)\nnpx newman run \"postman/collection/GoREST Users Tests.postman_collection.json\" \\\n  -e \"postman/env/GoREST Local.postman_environment.json\" \\\n  --bail folder\n```\n\n### npm scripts\nFor convenience, the project defines two ready-to-run npm scripts:\n\n- `npm run test:api` → full run with HTML report (htmlextra).\n- `npm run test:smoke` → quick “smoke run” of core folders (Happy Path, Negative, Boundary, Pagination), skipping mocks, with `--bail`.\n\n\u003e These are defined in `package.json` under `\"scripts\"`, so anyone can run them without remembering long Newman commands.\n\n## Run with Docker (no local Node required)\n\nBuild the image once:\n\n```bash\ndocker build -t gorest-tests .\n```\n\nRun (PowerShell on Windows):\n\n```powershell\ndocker run --rm `\n  -e TOKEN=\"YOUR_GOREST_TOKEN\" `\n  -e MOCK_BASE_URL=\"https://\u003cyour-mock-id\u003e.mock.pstmn.io\" `\n  -v \"${PWD}\\reports:/app/reports\" `\n  gorest-tests\n```\n\nRun (macOS/Linux/Git Bash):\n\n```bash\ndocker run --rm   -e TOKEN=\"YOUR_GOREST_TOKEN\"   -e MOCK_BASE_URL=\"https://\u003cyour-mock-id\u003e.mock.pstmn.io\"   -v \"$PWD/reports:/app/reports\"   gorest-tests\n```\n\n## CI – GitHub Actions (Newman)\nStatus: ![Newman API tests](https://github.com/yoavmosco/gorest-users-tests/actions/workflows/newman.yml/badge.svg)\n\nOn every push/PR to `main`, the workflow runs `newman` with HTML and JUnit reports:\n- Secrets used: `GOREST_TOKEN` (GoREST API token), `MOCK_BASE_URL` (Postman Mock URL).\n- Artifacts: `newman-reports` → contains `reports/newman.html` and `reports/junit.xml`.\n\n**How to download reports:**  \nGo to **Actions → Newman API tests → latest run → Artifacts → newman-reports** and download the ZIP.\n\n### Report preview\n![Newman HTML Report](docs/newman-report.png)\n\n## Challenges \u0026 solutions\n- **Schema failed on 404**  \n  *Fix:* schema guard — run only on **2xx JSON**. For the delete-verify step, assert **404 + message** without schema.\n- **Duplicate email stability**  \n  *Problem:* pre-request seeding was async → sometimes got `201` instead of `422`.  \n  *Fix:* deterministic flow **Seed → Duplicate (422) → Cleanup (204)**.\n\n### Error quality as TDD\nAssertions for **clear error messages** and correct **4xx codes** are written first and then used as **TDD** until the behavior matches.  \nExample focus: duplicate email (422), invalid enums, missing required fields.\n\n## Mock-based TDD (Postman Mock Server)\nFollowing the section above, this mock server was created to demonstrate the TDD approach for invalid error messages, specifically showing the desired fix for invalid `status` messages.\n\n**Folder:** `Users / Error Quality – Mock Server (TDD)`  \n**How it works:**\n- `DEF: POST /users — invalid status (422 example only)` holds a 422 Example used by the mock (do **not** run it).  \n- Runnable requests:  \n  - `MOCK: invalid status (string)`  \n  - `MOCK: invalid status (number)`  \n  These call `{{mockBaseUrl}}/users` with invalid values and always assert the **STRICT** message:  \n  ```json\n  [\n    {\n      \"field\": \"status\",\n      \"message\": \"status is invalid; must be one of: active, inactive\"\n    }\n  ]\n\n**Environment:** add `mockBaseUrl = https://\u003cyour-mock-id\u003e.mock.pstmn.io` (No Auth required for the mock).\n\n## Repo structure\n```\npostman/\n├─ GoREST Users Tests.postman_collection.json\n└─ env/\n   └─ GoREST Local.postman_environment.json\ntest-plan/\n└─ TEST_PLAN.md\ntest-cases/\n└─ TEST_CASES.md\nfindings/\n└─ KNOWN_ISSUES.md\n```\n\n## Known issues / Findings\n| ID  | Title                                | Type            | Repro (high level)                 | Expected               | Actual                 | Status/Notes                        |\n|-----|--------------------------------------|-----------------|-----------------------------------|------------------------|------------------------|------------------------------------- |\n| K1  | Invalid `page` falls back to Page 1  | Finding         | GET `/users?page=-1` after Page 1 | Error or explicit empty | Same item set as Page 1 | Covered by strict compare test      |\n| K2  | Error messages for invalid enums can be vague | Potential issue | POST `/users` with `status=123` | “must be one of …”     | “can’t be blank”       | Using error-quality tests as TDD    |\n\n## Documentation\n- [Summary](SUMMARY.md)\n- [Test Plan](test-plan/TEST_PLAN.md)\n- [Test Cases](test-cases/TEST_CASES.md)\n- [Known Issues](findings/KNOWN_ISSUES.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoavmosco%2Fgorest-users-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyoavmosco%2Fgorest-users-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoavmosco%2Fgorest-users-tests/lists"}