From fddda8ea1cd75a3e7d311dbddbe53b2dc80aa11b Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Mon, 6 Apr 2026 09:49:21 +0530 Subject: [PATCH 1/3] Enh: Added cursor rules and skills --- .cursor/rules/README.md | 37 + .cursor/rules/code-review.mdc | 27 + .../rules/contentstack-management-python.mdc | 26 + .cursor/rules/dev-workflow.md | 31 + .cursor/rules/python.mdc | 30 + .cursor/rules/testing.mdc | 26 + AGENTS.md | 56 ++ skills/README.md | 10 + skills/code-review/SKILL.md | 19 + .../contentstack-management-python/SKILL.md | 29 + skills/framework/SKILL.md | 24 + skills/testing/SKILL.md | 26 + tests/report/assets/style.css | 319 ++++++++ tests/report/test-report.html | 770 ++++++++++++++++++ 14 files changed, 1430 insertions(+) create mode 100644 .cursor/rules/README.md create mode 100644 .cursor/rules/code-review.mdc create mode 100644 .cursor/rules/contentstack-management-python.mdc create mode 100644 .cursor/rules/dev-workflow.md create mode 100644 .cursor/rules/python.mdc create mode 100644 .cursor/rules/testing.mdc create mode 100644 AGENTS.md create mode 100644 skills/README.md create mode 100644 skills/code-review/SKILL.md create mode 100644 skills/contentstack-management-python/SKILL.md create mode 100644 skills/framework/SKILL.md create mode 100644 skills/testing/SKILL.md create mode 100644 tests/report/assets/style.css create mode 100644 tests/report/test-report.html diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 0000000..921b056 --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,37 @@ +# Cursor Rules — `contentstack-management` + +Rules for **contentstack-management-python**: Python **CMA** SDK (`contentstack_management`). + +## Rules overview + +| Rule | Role | +|------|------| +| [`dev-workflow.md`](dev-workflow.md) | Branch/PR, install, pytest (`unit` / `api` / `mock`), tooling | +| [`python.mdc`](python.mdc) | Python conventions, `contentstack_management/`, `setup.py` | +| [`contentstack-management-python.mdc`](contentstack-management-python.mdc) | **Client**, **Stack**, **`_APIClient`**, CMA modules | +| [`testing.mdc`](testing.mdc) | pytest suites, **`tests/cred.py`**, env | +| [`code-review.mdc`](code-review.mdc) | PR checklist (**always applied**) | + +## Rule application + +| Context | Typical rules | +|---------|----------------| +| **Every session** | `code-review.mdc` | +| **Most repo files** | `dev-workflow.md` | +| **`contentstack_management/`** | `python.mdc` + `contentstack-management-python.mdc` | +| **`tests/**`** | `testing.mdc` | +| **Packaging / CI** | `python.mdc` | + +## Quick reference + +| File | `alwaysApply` | Globs (summary) | +|------|---------------|-----------------| +| `dev-workflow.md` | no | `**/*.py`, `setup.py`, `requirements.txt`, `.github/**/*.yml` | +| `python.mdc` | no | `contentstack_management/**/*.py`, `setup.py`, `requirements.txt` | +| `contentstack-management-python.mdc` | no | `contentstack_management/**/*.py` | +| `testing.mdc` | no | `tests/**/*.py` | +| `code-review.mdc` | **yes** | — | + +## Skills + +- [`skills/README.md`](../../skills/README.md) · [`AGENTS.md`](../../AGENTS.md) diff --git a/.cursor/rules/code-review.mdc b/.cursor/rules/code-review.mdc new file mode 100644 index 0000000..33b0ff2 --- /dev/null +++ b/.cursor/rules/code-review.mdc @@ -0,0 +1,27 @@ +--- +description: "PR checklist for contentstack-management — public API, Client, HTTP layer, tests" +alwaysApply: true +--- + +# Code review — `contentstack-management` + +## Public API + +- **Exported** **`Client`**, **`Region`**, stack and resource helpers match **README** and **`contentstack_management.__all__`** / **`__init__.py`**. +- **Docstrings** on **`Client`** and changed public methods when behavior or parameters change. + +## Compatibility + +- Avoid breaking **`Client`** constructor or stack method chains without a semver strategy; document migration for breaking changes. + +## HTTP / auth + +- Changes to **`_APIClient`** or **OAuth** paths: verify retries, headers, and interceptor behavior with unit tests; no regressions for **authtoken** / **management_token** headers. + +## Tests + +- **Unit** coverage for new logic; **API** updates when live CMA request/response behavior changes; **mock** when contract-style tests are appropriate. + +## Security + +- No hardcoded tokens; no logging secrets in new code. diff --git a/.cursor/rules/contentstack-management-python.mdc b/.cursor/rules/contentstack-management-python.mdc new file mode 100644 index 0000000..cdbd8ae --- /dev/null +++ b/.cursor/rules/contentstack-management-python.mdc @@ -0,0 +1,26 @@ +--- +description: "CMA Management SDK — Client, Stack, _APIClient, resources, OAuth" +globs: + - "contentstack_management/**/*.py" +alwaysApply: false +--- + +# Contentstack Management Python SDK (`contentstack_management/`) + +## Client entry + +- **`Client`** in **`contentstack_management/contentstack.py`** builds **`endpoint`** from **host** / **region** / **scheme**, merges **headers** (**authtoken**, **management_token**, **early_access**), and constructs **`_APIClient`**. Optional **`oauth_config`** attaches **`OAuthHandler`**. + +## Features + +- **Stack** — **`contentstack_management/stack/stack.py`**: content types, entries, assets, branches, webhooks, etc. +- **Org / user** — **`organizations/`**, **`users/`**, **`user_session/`** as applicable. +- **OAuth** — **`oauth/oauth_handler.py`**, **`oauth/oauth_interceptor.py`**; keep aligned with **`_APIClient`** request path. + +## HTTP layer + +- **`_APIClient._call_request`** — central place for method, URL, JSON, files; respect **timeout** and **max_retries**. + +## Docs + +- [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) diff --git a/.cursor/rules/dev-workflow.md b/.cursor/rules/dev-workflow.md new file mode 100644 index 0000000..87b6597 --- /dev/null +++ b/.cursor/rules/dev-workflow.md @@ -0,0 +1,31 @@ +--- +description: "Branches, install, and test layout for contentstack-management-python" +globs: + - "**/*.py" + - "setup.py" + - "requirements.txt" + - ".github/**/*.yml" +alwaysApply: false +--- + +# Development workflow — `contentstack-management` + +## Before a PR + +1. **Install** — `pip install -e ".[dev]"` or install **`requirements.txt`** plus **pytest** / **pytest-cov** as needed. +2. **`pytest tests/unit/`** — required baseline (matches CI **`coverage run -m pytest tests/unit/`**). +3. **API tests** — `pytest tests/api/` when your change affects live CMA behavior; configure **`.env`** per **`tests/cred.py`**. Never commit tokens. +4. **Mock tests** — `pytest tests/mock/` when extending mocked HTTP or fixtures. + +## Packaging + +- Bump **`contentstack_management/__init__.py`** **`__version__`** and align **`setup.py`** versioning if release-facing. + +## Tooling + +- **pylint** is listed in **`requirements.txt`**; follow existing style in touched files. +- **Husky / Talisman / Snyk** — see **README.md** for local hook setup. + +## Links + +- [`AGENTS.md`](../../AGENTS.md) · [`skills/contentstack-management-python/SKILL.md`](../../skills/contentstack-management-python/SKILL.md) diff --git a/.cursor/rules/python.mdc b/.cursor/rules/python.mdc new file mode 100644 index 0000000..c36509e --- /dev/null +++ b/.cursor/rules/python.mdc @@ -0,0 +1,30 @@ +--- +description: "Python conventions for the Management SDK package and packaging files" +globs: + - "contentstack_management/**/*.py" + - "setup.py" + - "requirements.txt" +alwaysApply: false +--- + +# Python — `contentstack-management` + +## Layout + +- **`contentstack_management/contentstack.py`** — **`Client`**, **`Region`**, **`user_agents`**, OAuth wiring. +- **`contentstack_management/_api_client.py`** — **`_APIClient`** (HTTP, retries). +- **`contentstack_management/stack/`** — stack-scoped API surface. +- **Domain modules** — **`entries/`**, **`assets/`**, **`webhooks/`**, **`oauth/`**, etc. + +## Style + +- Match existing modules: naming, docstrings, and patterns already used in the same directory. +- Prefer small, focused changes; keep **`__init__.py`** exports consistent with public API intent. + +## Imports + +- Use **`requests`** (and **`requests-toolbelt`** where already used) through **`_APIClient`** patterns rather than ad-hoc clients in domain modules unless justified. + +## Security + +- Do not log **authtokens**, **management tokens**, **passwords**, or **API keys**; preserve existing header handling in **`Client`**. diff --git a/.cursor/rules/testing.mdc b/.cursor/rules/testing.mdc new file mode 100644 index 0000000..bb7cb61 --- /dev/null +++ b/.cursor/rules/testing.mdc @@ -0,0 +1,26 @@ +--- +description: "pytest unit, api, and mock tests for contentstack-management-python" +globs: + - "tests/**/*.py" +alwaysApply: false +--- + +# Testing — `contentstack-management` + +## pytest + +| Suite | Path | Notes | +|-------|------|--------| +| **Unit** | `tests/unit/**` | Fast, isolated; primary CI target (`pytest tests/unit/`) | +| **API** | `tests/api/**` | Live CMA — **`.env`** via **`tests/cred.py`** | +| **Mock** | `tests/mock/**` | Mocked HTTP / contracts | + +## Env (`tests/cred.py`) + +- **`get_credentials()`** loads **dotenv** and returns host, tokens, and resource UIDs. +- Required for real API runs typically include **`HOST`**, **`APIKEY`**, and either **`AUTHTOKEN`** or stack **`MANAGEMENT_TOKEN`** context as tests expect; see **`tests/cred.py`** and individual tests. + +## Hygiene + +- No committed secrets; use placeholders or env-only values for CI. +- Avoid leaving **`pytest.skip`** or focused-only tests enabled in paths meant for full suite runs unless intentional. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9b3ca0a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,56 @@ +# AGENTS.md — AI / automation context + +## Project + +| | | +|---|---| +| **Name** | **`contentstack-management`** (PyPI) — **Contentstack Management Python SDK** | +| **Purpose** | Python client for the **Content Management API (CMA)**: organizations, stacks, content types, entries, assets, webhooks, workflows, OAuth, and related resources. Uses **`requests`** via **`_APIClient`**. | +| **Repository** | [contentstack/contentstack-management-python](https://github.com/contentstack/contentstack-management-python.git) | + +## Tech stack + +| Area | Details | +|------|---------| +| **Language** | **Python** ≥ 3.9 (`setup.py` `python_requires`) | +| **HTTP** | **`requests`**, **`requests-toolbelt`**, **`urllib3`** | +| **Tests** | **pytest** — **`tests/unit`**, **`tests/api`**, **`tests/mock`** | +| **Lint** | **pylint** (see `requirements.txt`) | +| **Secrets / hooks** | **Talisman**, **Snyk** (see **README.md** development setup) | + +## Source layout + +| Path | Role | +|------|------| +| `contentstack_management/contentstack.py` | **`Client`**, **`Region`**, endpoint construction, **`user_agents`**, optional **OAuth** wiring | +| `contentstack_management/_api_client.py` | **`_APIClient`** — HTTP calls, retries, optional **OAuth** interceptor | +| `contentstack_management/stack/stack.py` | **Stack**-scoped CMA operations | +| `contentstack_management/*/` | Domain modules (entries, assets, webhooks, taxonomies, …) | +| `contentstack_management/__init__.py` | Public exports | +| `tests/cred.py` | **`get_credentials()`** — **dotenv** + env vars for API/mock tests | + +## Common commands + +```bash +pip install -e ".[dev]" +# or: pip install -r requirements.txt && pip install pytest pytest-cov + +pytest tests/unit/ -v +pytest tests/api/ -v # live CMA — needs .env (see tests/cred.py) +pytest tests/mock/ -v +pytest tests/ -v +coverage run -m pytest tests/unit/ +``` + +## Environment variables (API / integration tests) + +Loaded via **`tests/cred.py`** (`load_dotenv()`). Examples include **`HOST`**, **`APIKEY`**, **`AUTHTOKEN`**, **`MANAGEMENT_TOKEN`**, **`ORG_UID`**, and resource UIDs (**`CONTENT_TYPE_UID`**, **`ENTRY_UID`**, …). See that file for the full list. + +Do not commit secrets. + +## Further guidance + +- **Cursor rules:** [`.cursor/rules/README.md`](.cursor/rules/README.md) +- **Skills:** [`skills/README.md`](skills/README.md) + +Product docs: [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/). diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..2448ff9 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,10 @@ +# Project skills — `contentstack-management` + +| Skill | When to use | +|-------|-------------| +| [`code-review/`](code-review/SKILL.md) | PR review, semver, Client / HTTP changes | +| [`testing/`](testing/SKILL.md) | Unit vs API vs mock pytest | +| [`contentstack-management-python/`](contentstack-management-python/SKILL.md) | **Client**, **Stack**, **`_APIClient`**, CMA modules | +| [`framework/`](framework/SKILL.md) | **`requests`** + **`_APIClient`** + OAuth interceptor | + +**Overview:** [`AGENTS.md`](../AGENTS.md) · **Rules:** [`.cursor/rules/README.md`](../.cursor/rules/README.md) diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 0000000..87a4cec --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,19 @@ +--- +name: code-review +description: PR review for contentstack-management — public API, Client, _APIClient, OAuth, tests. +--- + +# Code review — `contentstack-management` + +## Checklist + +- [ ] **API:** New or changed **`Client`** / **Stack** / resource methods documented; **`contentstack_management/__init__.py`** exports updated if public surface changes. +- [ ] **Version:** **`__version__`** in **`contentstack_management/__init__.py`** aligned with release strategy when user-visible behavior changes. +- [ ] **HTTP:** **`_APIClient`** or OAuth changes covered by unit tests; retries and headers remain consistent. +- [ ] **Tests:** **`pytest tests/unit/`** passes; extend **`tests/api`** or **`tests/mock`** when integration or contract behavior changes. +- [ ] **Secrets:** No tokens in repo; use **`tests/cred.py`** / env for local API runs. + +## References + +- `.cursor/rules/code-review.mdc` +- `.cursor/rules/dev-workflow.md` diff --git a/skills/contentstack-management-python/SKILL.md b/skills/contentstack-management-python/SKILL.md new file mode 100644 index 0000000..f64dcce --- /dev/null +++ b/skills/contentstack-management-python/SKILL.md @@ -0,0 +1,29 @@ +--- +name: contentstack-management-python +description: contentstack-management — Python CMA client, Client, Stack, _APIClient, OAuth. +--- + +# Contentstack Management Python SDK skill + +## Entry + +- **`contentstack_management.Client`** — **`contentstack_management/contentstack.py`**: builds CMA **endpoint** from **region** / **host**, sets **headers** (**authtoken**, **management_token**), creates **`_APIClient`**, optional **OAuth**. + +## Structure + +- **`Stack`** — **`contentstack_management/stack/stack.py`**: stack-scoped resources (content types, entries, assets, …). +- **Resources** — packages under **`contentstack_management/`** (e.g. **`entries/`**, **`assets/`**, **`webhooks/`**). +- **OAuth** — **`oauth/oauth_handler.py`**, **`oauth/oauth_interceptor.py`**. + +## Extending + +- Add methods on the appropriate resource class; align path and payload shapes with **CMA** docs. +- Prefer routing HTTP through **`_APIClient`** for consistent retries and OAuth handling. + +## Docs + +- [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) + +## Rule shortcut + +- `.cursor/rules/contentstack-management-python.mdc` diff --git a/skills/framework/SKILL.md b/skills/framework/SKILL.md new file mode 100644 index 0000000..3d26ce8 --- /dev/null +++ b/skills/framework/SKILL.md @@ -0,0 +1,24 @@ +--- +name: framework +description: HTTP layer — requests-based _APIClient, retries, OAuth interceptor for the Management SDK. +--- + +# Framework skill — `requests` + `_APIClient` + +## Integration point + +- **`contentstack_management/_api_client.py`** — **`_APIClient`** uses **`requests`** in **`_call_request`**, honors **timeout** and **max_retries**, and delegates to **`oauth_interceptor`** when configured. + +## When to change + +- **Retry or transport behavior** — keep logic centralized in **`_APIClient`** unless a resource truly needs a documented exception. +- **Auth headers** — prefer extending **`Client`** / **`user_agents`** patterns rather than scattering header merges. + +## Testing + +- **Unit** — mock **`requests`** or **`_APIClient`** at the boundary used by existing tests. +- **API** — full stack via credentials from **`tests/cred.py`**. + +## Rule shortcut + +- `.cursor/rules/contentstack-management-python.mdc` diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md new file mode 100644 index 0000000..e0376a2 --- /dev/null +++ b/skills/testing/SKILL.md @@ -0,0 +1,26 @@ +--- +name: testing +description: pytest unit, api, and mock suites for contentstack-management-python. +--- + +# Testing — `contentstack-management` + +## Commands + +| Goal | Command | +|------|---------| +| Unit (CI-style) | `pytest tests/unit/ -v` or `coverage run -m pytest tests/unit/` | +| API (live CMA) | `pytest tests/api/ -v` | +| Mock | `pytest tests/mock/ -v` | +| Full tree | `pytest tests/ -v` | + +## Environment + +See **`tests/cred.py`** — **`get_credentials()`** after **`load_dotenv()`**. + +- Common vars: **`HOST`**, **`APIKEY`**, **`AUTHTOKEN`**, **`MANAGEMENT_TOKEN`**, **`ORG_UID`**, plus resource UIDs as tests require. +- Use a **`.env`** at repo root for local API runs; never commit secrets. + +## References + +- `.cursor/rules/testing.mdc` diff --git a/tests/report/assets/style.css b/tests/report/assets/style.css new file mode 100644 index 0000000..561524c --- /dev/null +++ b/tests/report/assets/style.css @@ -0,0 +1,319 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; + /* do not increase min-width as some may use split screens */ + min-width: 800px; + color: #999; +} + +h1 { + font-size: 24px; + color: black; +} + +h2 { + font-size: 16px; + color: black; +} + +p { + color: black; +} + +a { + color: #999; +} + +table { + border-collapse: collapse; +} + +/****************************** + * SUMMARY INFORMATION + ******************************/ +#environment td { + padding: 5px; + border: 1px solid #e6e6e6; + vertical-align: top; +} +#environment tr:nth-child(odd) { + background-color: #f6f6f6; +} +#environment ul { + margin: 0; + padding: 0 20px; +} + +/****************************** + * TEST RESULT COLORS + ******************************/ +span.passed, +.passed .col-result { + color: green; +} + +span.skipped, +span.xfailed, +span.rerun, +.skipped .col-result, +.xfailed .col-result, +.rerun .col-result { + color: orange; +} + +span.error, +span.failed, +span.xpassed, +.error .col-result, +.failed .col-result, +.xpassed .col-result { + color: red; +} + +.col-links__extra { + margin-right: 3px; +} + +/****************************** + * RESULTS TABLE + * + * 1. Table Layout + * 2. Extra + * 3. Sorting items + * + ******************************/ +/*------------------ + * 1. Table Layout + *------------------*/ +#results-table { + border: 1px solid #e6e6e6; + color: #999; + font-size: 12px; + width: 100%; +} +#results-table th, +#results-table td { + padding: 5px; + border: 1px solid #e6e6e6; + text-align: left; +} +#results-table th { + font-weight: bold; +} + +/*------------------ + * 2. Extra + *------------------*/ +.logwrapper { + max-height: 230px; + overflow-y: scroll; + background-color: #e6e6e6; +} +.logwrapper.expanded { + max-height: none; +} +.logwrapper.expanded .logexpander:after { + content: "collapse [-]"; +} +.logwrapper .logexpander { + z-index: 1; + position: sticky; + top: 10px; + width: max-content; + border: 1px solid; + border-radius: 3px; + padding: 5px 7px; + margin: 10px 0 10px calc(100% - 80px); + cursor: pointer; + background-color: #e6e6e6; +} +.logwrapper .logexpander:after { + content: "expand [+]"; +} +.logwrapper .logexpander:hover { + color: #000; + border-color: #000; +} +.logwrapper .log { + min-height: 40px; + position: relative; + top: -50px; + height: calc(100% + 50px); + border: 1px solid #e6e6e6; + color: black; + display: block; + font-family: "Courier New", Courier, monospace; + padding: 5px; + padding-right: 80px; + white-space: pre-wrap; +} + +div.media { + border: 1px solid #e6e6e6; + float: right; + height: 240px; + margin: 0 5px; + overflow: hidden; + width: 320px; +} + +.media-container { + display: grid; + grid-template-columns: 25px auto 25px; + align-items: center; + flex: 1 1; + overflow: hidden; + height: 200px; +} + +.media-container--fullscreen { + grid-template-columns: 0px auto 0px; +} + +.media-container__nav--right, +.media-container__nav--left { + text-align: center; + cursor: pointer; +} + +.media-container__viewport { + cursor: pointer; + text-align: center; + height: inherit; +} +.media-container__viewport img, +.media-container__viewport video { + object-fit: cover; + width: 100%; + max-height: 100%; +} + +.media__name, +.media__counter { + display: flex; + flex-direction: row; + justify-content: space-around; + flex: 0 0 25px; + align-items: center; +} + +.collapsible td:not(.col-links) { + cursor: pointer; +} +.collapsible td:not(.col-links):hover::after { + color: #bbb; + font-style: italic; + cursor: pointer; +} + +.col-result { + width: 130px; +} +.col-result:hover::after { + content: " (hide details)"; +} + +.col-result.collapsed:hover::after { + content: " (show details)"; +} + +#environment-header h2:hover::after { + content: " (hide details)"; + color: #bbb; + font-style: italic; + cursor: pointer; + font-size: 12px; +} + +#environment-header.collapsed h2:hover::after { + content: " (show details)"; + color: #bbb; + font-style: italic; + cursor: pointer; + font-size: 12px; +} + +/*------------------ + * 3. Sorting items + *------------------*/ +.sortable { + cursor: pointer; +} +.sortable.desc:after { + content: " "; + position: relative; + left: 5px; + bottom: -12.5px; + border: 10px solid #4caf50; + border-bottom: 0; + border-left-color: transparent; + border-right-color: transparent; +} +.sortable.asc:after { + content: " "; + position: relative; + left: 5px; + bottom: 12.5px; + border: 10px solid #4caf50; + border-top: 0; + border-left-color: transparent; + border-right-color: transparent; +} + +.hidden, .summary__reload__button.hidden { + display: none; +} + +.summary__data { + flex: 0 0 550px; +} +.summary__reload { + flex: 1 1; + display: flex; + justify-content: center; +} +.summary__reload__button { + flex: 0 0 300px; + display: flex; + color: white; + font-weight: bold; + background-color: #4caf50; + text-align: center; + justify-content: center; + align-items: center; + border-radius: 3px; + cursor: pointer; +} +.summary__reload__button:hover { + background-color: #46a049; +} +.summary__spacer { + flex: 0 0 550px; +} + +.controls { + display: flex; + justify-content: space-between; +} + +.filters, +.collapse { + display: flex; + align-items: center; +} +.filters button, +.collapse button { + color: #999; + border: none; + background: none; + cursor: pointer; + text-decoration: underline; +} +.filters button:hover, +.collapse button:hover { + color: #ccc; +} + +.filter__label { + margin-right: 10px; +} diff --git a/tests/report/test-report.html b/tests/report/test-report.html new file mode 100644 index 0000000..53b9c40 --- /dev/null +++ b/tests/report/test-report.html @@ -0,0 +1,770 @@ + + + + + test-report.html + + + +

test-report.html

+

Report generated on 02-Apr-2026 at 11:33:13 by pytest-html + v4.1.1

+
+

Environment

+
+
+ + + + + +
+
+

Summary

+
+
+

24 tests took 00:00:03.

+

(Un)check the boxes to filter the results.

+
+ +
+
+
+
+ + 0 Failed, + + 24 Passed, + + 0 Skipped, + + 0 Expected failures, + + 0 Unexpected passes, + + 0 Errors, + + 0 Reruns +
+
+  /  +
+
+
+
+
+
+
+
+ + + + + + + + + +
ResultTestDurationLinks
+ + + \ No newline at end of file From bacb1f09ec2aad08a764c5834d9947a7f4888b0f Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:14:04 +0530 Subject: [PATCH 2/3] Updated cursor rules as per new structure --- .cursor/rules/README.md | 38 ++------------ .cursor/rules/code-review.mdc | 27 ---------- .../rules/contentstack-management-python.mdc | 26 ---------- .cursor/rules/testing.mdc | 26 ---------- AGENTS.md | 28 +++++++--- skills/README.md | 25 ++++++--- skills/code-review/SKILL.md | 51 +++++++++++++++---- .../contentstack-management-python/SKILL.md | 29 ----------- skills/contentstack-management/SKILL.md | 43 ++++++++++++++++ .../dev-workflow/SKILL.md | 28 ++++++---- skills/framework/SKILL.md | 17 +++++-- .../python-style/SKILL.md | 23 ++++++--- skills/testing/SKILL.md | 32 +++++++++--- 13 files changed, 196 insertions(+), 197 deletions(-) delete mode 100644 .cursor/rules/code-review.mdc delete mode 100644 .cursor/rules/contentstack-management-python.mdc delete mode 100644 .cursor/rules/testing.mdc delete mode 100644 skills/contentstack-management-python/SKILL.md create mode 100644 skills/contentstack-management/SKILL.md rename .cursor/rules/dev-workflow.md => skills/dev-workflow/SKILL.md (52%) rename .cursor/rules/python.mdc => skills/python-style/SKILL.md (58%) diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md index 921b056..0c75565 100644 --- a/.cursor/rules/README.md +++ b/.cursor/rules/README.md @@ -1,37 +1,5 @@ -# Cursor Rules — `contentstack-management` +# Cursor (optional) -Rules for **contentstack-management-python**: Python **CMA** SDK (`contentstack_management`). +**Cursor** users: start at the repo root **[`AGENTS.md`](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`** (universal for any editor or tool). -## Rules overview - -| Rule | Role | -|------|------| -| [`dev-workflow.md`](dev-workflow.md) | Branch/PR, install, pytest (`unit` / `api` / `mock`), tooling | -| [`python.mdc`](python.mdc) | Python conventions, `contentstack_management/`, `setup.py` | -| [`contentstack-management-python.mdc`](contentstack-management-python.mdc) | **Client**, **Stack**, **`_APIClient`**, CMA modules | -| [`testing.mdc`](testing.mdc) | pytest suites, **`tests/cred.py`**, env | -| [`code-review.mdc`](code-review.mdc) | PR checklist (**always applied**) | - -## Rule application - -| Context | Typical rules | -|---------|----------------| -| **Every session** | `code-review.mdc` | -| **Most repo files** | `dev-workflow.md` | -| **`contentstack_management/`** | `python.mdc` + `contentstack-management-python.mdc` | -| **`tests/**`** | `testing.mdc` | -| **Packaging / CI** | `python.mdc` | - -## Quick reference - -| File | `alwaysApply` | Globs (summary) | -|------|---------------|-----------------| -| `dev-workflow.md` | no | `**/*.py`, `setup.py`, `requirements.txt`, `.github/**/*.yml` | -| `python.mdc` | no | `contentstack_management/**/*.py`, `setup.py`, `requirements.txt` | -| `contentstack-management-python.mdc` | no | `contentstack_management/**/*.py` | -| `testing.mdc` | no | `tests/**/*.py` | -| `code-review.mdc` | **yes** | — | - -## Skills - -- [`skills/README.md`](../../skills/README.md) · [`AGENTS.md`](../../AGENTS.md) +This folder only points contributors here so nothing editor-specific duplicates the canonical docs. diff --git a/.cursor/rules/code-review.mdc b/.cursor/rules/code-review.mdc deleted file mode 100644 index 33b0ff2..0000000 --- a/.cursor/rules/code-review.mdc +++ /dev/null @@ -1,27 +0,0 @@ ---- -description: "PR checklist for contentstack-management — public API, Client, HTTP layer, tests" -alwaysApply: true ---- - -# Code review — `contentstack-management` - -## Public API - -- **Exported** **`Client`**, **`Region`**, stack and resource helpers match **README** and **`contentstack_management.__all__`** / **`__init__.py`**. -- **Docstrings** on **`Client`** and changed public methods when behavior or parameters change. - -## Compatibility - -- Avoid breaking **`Client`** constructor or stack method chains without a semver strategy; document migration for breaking changes. - -## HTTP / auth - -- Changes to **`_APIClient`** or **OAuth** paths: verify retries, headers, and interceptor behavior with unit tests; no regressions for **authtoken** / **management_token** headers. - -## Tests - -- **Unit** coverage for new logic; **API** updates when live CMA request/response behavior changes; **mock** when contract-style tests are appropriate. - -## Security - -- No hardcoded tokens; no logging secrets in new code. diff --git a/.cursor/rules/contentstack-management-python.mdc b/.cursor/rules/contentstack-management-python.mdc deleted file mode 100644 index cdbd8ae..0000000 --- a/.cursor/rules/contentstack-management-python.mdc +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: "CMA Management SDK — Client, Stack, _APIClient, resources, OAuth" -globs: - - "contentstack_management/**/*.py" -alwaysApply: false ---- - -# Contentstack Management Python SDK (`contentstack_management/`) - -## Client entry - -- **`Client`** in **`contentstack_management/contentstack.py`** builds **`endpoint`** from **host** / **region** / **scheme**, merges **headers** (**authtoken**, **management_token**, **early_access**), and constructs **`_APIClient`**. Optional **`oauth_config`** attaches **`OAuthHandler`**. - -## Features - -- **Stack** — **`contentstack_management/stack/stack.py`**: content types, entries, assets, branches, webhooks, etc. -- **Org / user** — **`organizations/`**, **`users/`**, **`user_session/`** as applicable. -- **OAuth** — **`oauth/oauth_handler.py`**, **`oauth/oauth_interceptor.py`**; keep aligned with **`_APIClient`** request path. - -## HTTP layer - -- **`_APIClient._call_request`** — central place for method, URL, JSON, files; respect **timeout** and **max_retries**. - -## Docs - -- [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) diff --git a/.cursor/rules/testing.mdc b/.cursor/rules/testing.mdc deleted file mode 100644 index bb7cb61..0000000 --- a/.cursor/rules/testing.mdc +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: "pytest unit, api, and mock tests for contentstack-management-python" -globs: - - "tests/**/*.py" -alwaysApply: false ---- - -# Testing — `contentstack-management` - -## pytest - -| Suite | Path | Notes | -|-------|------|--------| -| **Unit** | `tests/unit/**` | Fast, isolated; primary CI target (`pytest tests/unit/`) | -| **API** | `tests/api/**` | Live CMA — **`.env`** via **`tests/cred.py`** | -| **Mock** | `tests/mock/**` | Mocked HTTP / contracts | - -## Env (`tests/cred.py`) - -- **`get_credentials()`** loads **dotenv** and returns host, tokens, and resource UIDs. -- Required for real API runs typically include **`HOST`**, **`APIKEY`**, and either **`AUTHTOKEN`** or stack **`MANAGEMENT_TOKEN`** context as tests expect; see **`tests/cred.py`** and individual tests. - -## Hygiene - -- No committed secrets; use placeholders or env-only values for CI. -- Avoid leaving **`pytest.skip`** or focused-only tests enabled in paths meant for full suite runs unless intentional. diff --git a/AGENTS.md b/AGENTS.md index 9b3ca0a..3ba6617 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,8 @@ -# AGENTS.md — AI / automation context +# Contentstack Management Python — Agent guide -## Project +**Universal entry point** for anyone automating or assisting work in this repo—AI agents (Cursor, Copilot, CLI tools), reviewers, and contributors. Conventions and detailed guidance live in **`skills/*/SKILL.md`**, not in editor-specific config, so the same instructions apply whether or not you use Cursor. + +## What this repo is | | | |---|---| @@ -29,7 +31,7 @@ | `contentstack_management/__init__.py` | Public exports | | `tests/cred.py` | **`get_credentials()`** — **dotenv** + env vars for API/mock tests | -## Common commands +## Commands (quick reference) ```bash pip install -e ".[dev]" @@ -48,9 +50,23 @@ Loaded via **`tests/cred.py`** (`load_dotenv()`). Examples include **`HOST`**, * Do not commit secrets. -## Further guidance +## Where the real documentation lives: skills + +Read these **`SKILL.md` files** for full conventions—**this is the source of truth** for implementation and review: + +| Skill | Path | What it covers | +|-------|------|----------------| +| **Development workflow** | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) | Install, pytest suites, packaging version, pylint, hooks, PR baseline | +| **Contentstack Management (SDK)** | [`skills/contentstack-management/SKILL.md`](skills/contentstack-management/SKILL.md) | **`Client`**, **`Stack`**, **`_APIClient`**, CMA resources, OAuth, CMA docs | +| **Python style & repo layout** | [`skills/python-style/SKILL.md`](skills/python-style/SKILL.md) | Package layout, naming, imports via **`_APIClient`**, secrets in logs | +| **Testing** | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) | pytest unit / API / mock, **`tests/cred.py`**, env hygiene | +| **Code review** | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) | PR checklist—public API, HTTP/auth, tests, security | +| **Framework / HTTP** | [`skills/framework/SKILL.md`](skills/framework/SKILL.md) | **`requests`**, retries, OAuth interceptor, where to change transport | + +An index with short “when to use” hints is in [`skills/README.md`](skills/README.md). + +## Using Cursor -- **Cursor rules:** [`.cursor/rules/README.md`](.cursor/rules/README.md) -- **Skills:** [`skills/README.md`](skills/README.md) +If you use **Cursor**, [`.cursor/rules/README.md`](.cursor/rules/README.md) only points to **`AGENTS.md`**—same source of truth as everyone else; no separate `.mdc` rule files. Product docs: [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/). diff --git a/skills/README.md b/skills/README.md index 2448ff9..2d7c58a 100644 --- a/skills/README.md +++ b/skills/README.md @@ -1,10 +1,19 @@ -# Project skills — `contentstack-management` +# Skills — Contentstack Management Python -| Skill | When to use | -|-------|-------------| -| [`code-review/`](code-review/SKILL.md) | PR review, semver, Client / HTTP changes | -| [`testing/`](testing/SKILL.md) | Unit vs API vs mock pytest | -| [`contentstack-management-python/`](contentstack-management-python/SKILL.md) | **Client**, **Stack**, **`_APIClient`**, CMA modules | -| [`framework/`](framework/SKILL.md) | **`requests`** + **`_APIClient`** + OAuth interceptor | +**This directory is the source of truth** for conventions (workflow, SDK API, style, tests, review, HTTP layer). Read **`AGENTS.md`** at the repo root for the index and quick commands; each skill is a folder with **`SKILL.md`** (YAML frontmatter: `name`, `description`). -**Overview:** [`AGENTS.md`](../AGENTS.md) · **Rules:** [`.cursor/rules/README.md`](../.cursor/rules/README.md) +## When to use which skill + +| Skill folder | Use when | +|--------------|----------| +| **dev-workflow** | Install, **`pytest`** (unit / API / mock), **`__version__`**, pylint, Talisman/Snyk, before PR | +| **contentstack-management** | **`Client`**, **`Stack`**, **`_APIClient`**, domain modules, OAuth, CMA paths and payloads | +| **python-style** | Editing **`contentstack_management/`** or **`setup.py`** / **`requirements.txt`**—layout, style, imports | +| **testing** | Adding or changing tests under **`tests/`**, **`tests/cred.py`**, env for API runs | +| **code-review** | PR checklist, API semver, HTTP regressions, secrets | +| **framework** | Changing **`_APIClient`**, retries, **`requests`** usage, OAuth interceptor wiring | + +## How to use these docs + +- **Humans / any AI tool:** Start at **`AGENTS.md`**, then open the relevant **`skills//SKILL.md`**. +- **Cursor users:** **`.cursor/rules/README.md`** only points to **`AGENTS.md`** so guidance stays universal—no duplicate `.mdc` rule sets. diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md index 87a4cec..46b7181 100644 --- a/skills/code-review/SKILL.md +++ b/skills/code-review/SKILL.md @@ -1,19 +1,50 @@ --- name: code-review -description: PR review for contentstack-management — public API, Client, _APIClient, OAuth, tests. +description: PR checklist—public API, Client/Stack, _APIClient/OAuth, tests, secrets; align with README and exports. --- -# Code review — `contentstack-management` +# Code review — Contentstack Management Python -## Checklist +## When to use -- [ ] **API:** New or changed **`Client`** / **Stack** / resource methods documented; **`contentstack_management/__init__.py`** exports updated if public surface changes. -- [ ] **Version:** **`__version__`** in **`contentstack_management/__init__.py`** aligned with release strategy when user-visible behavior changes. -- [ ] **HTTP:** **`_APIClient`** or OAuth changes covered by unit tests; retries and headers remain consistent. -- [ ] **Tests:** **`pytest tests/unit/`** passes; extend **`tests/api`** or **`tests/mock`** when integration or contract behavior changes. -- [ ] **Secrets:** No tokens in repo; use **`tests/cred.py`** / env for local API runs. +- Reviewing a PR, self-review before submit, or automated review prompts. + +## Instructions + +Work through the checklist below. Optionally tag findings: **Blocker**, **Major**, **Minor**. + +### Public API + +- [ ] **Exported** **`Client`**, **`Region`**, stack and resource helpers match **README** and **`contentstack_management.__all__`** / **`__init__.py`**. +- [ ] **Docstrings** on **`Client`** and changed public methods when behavior or parameters change. + +### Compatibility + +- [ ] Avoid breaking **`Client`** constructor or stack method chains without a semver strategy; document migration for breaking changes. + +### HTTP / auth + +- [ ] Changes to **`_APIClient`** or **OAuth** paths: verify retries, headers, and interceptor behavior with unit tests; no regressions for **authtoken** / **management_token** headers. + +### Testing + +- [ ] **Unit** coverage for new logic; **API** updates when live CMA request/response behavior changes; **mock** when contract-style tests are appropriate. +- [ ] **`pytest tests/unit/`** passes. + +### Security + +- [ ] No hardcoded tokens; no logging secrets in new code. + +### Severity (optional) + +| Level | Examples | +|-------|----------| +| **Blocker** | Breaking public API without approval; security issue; no tests for new logic where tests are practical | +| **Major** | Inconsistent HTTP/auth behavior; README examples that do not match code | +| **Minor** | Style; minor docs | ## References -- `.cursor/rules/code-review.mdc` -- `.cursor/rules/dev-workflow.md` +- **`skills/testing/SKILL.md`** +- **`skills/contentstack-management/SKILL.md`** +- **`skills/dev-workflow/SKILL.md`** diff --git a/skills/contentstack-management-python/SKILL.md b/skills/contentstack-management-python/SKILL.md deleted file mode 100644 index f64dcce..0000000 --- a/skills/contentstack-management-python/SKILL.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: contentstack-management-python -description: contentstack-management — Python CMA client, Client, Stack, _APIClient, OAuth. ---- - -# Contentstack Management Python SDK skill - -## Entry - -- **`contentstack_management.Client`** — **`contentstack_management/contentstack.py`**: builds CMA **endpoint** from **region** / **host**, sets **headers** (**authtoken**, **management_token**), creates **`_APIClient`**, optional **OAuth**. - -## Structure - -- **`Stack`** — **`contentstack_management/stack/stack.py`**: stack-scoped resources (content types, entries, assets, …). -- **Resources** — packages under **`contentstack_management/`** (e.g. **`entries/`**, **`assets/`**, **`webhooks/`**). -- **OAuth** — **`oauth/oauth_handler.py`**, **`oauth/oauth_interceptor.py`**. - -## Extending - -- Add methods on the appropriate resource class; align path and payload shapes with **CMA** docs. -- Prefer routing HTTP through **`_APIClient`** for consistent retries and OAuth handling. - -## Docs - -- [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) - -## Rule shortcut - -- `.cursor/rules/contentstack-management-python.mdc` diff --git a/skills/contentstack-management/SKILL.md b/skills/contentstack-management/SKILL.md new file mode 100644 index 0000000..e49f557 --- /dev/null +++ b/skills/contentstack-management/SKILL.md @@ -0,0 +1,43 @@ +--- +name: contentstack-management +description: Public CMA surface—Client, Stack, _APIClient, domain resources, OAuth; align with CMA docs and semver. +--- + +# Contentstack Management — SDK skill + +## When to use + +- Implementing or changing **`Client`**, **Stack**, or resource modules (entries, assets, webhooks, …). +- Updating **`README.md`** or public exports for user-visible behavior. +- Assessing semver impact of constructor, method, or export changes. + +## Main entry (consumer API) + +- **`contentstack_management.Client`** in **`contentstack.py`**: builds CMA **endpoint** from **region** / **host** / **scheme**, merges **headers** (**authtoken**, **management_token**, **early_access**), constructs **`_APIClient`**, optional **`oauth_config`** with **`OAuthHandler`**. + +## Structure + +- **`Stack`** — **`contentstack_management/stack/stack.py`**: stack-scoped resources (content types, entries, assets, branches, webhooks, …). +- **Org / user** — **`organizations/`**, **`users/`**, **`user_session/`** as applicable. +- **Resources** — packages under **`contentstack_management/`** following existing patterns. +- **OAuth** — **`oauth/oauth_handler.py`**, **`oauth/oauth_interceptor.py`**; keep aligned with **`_APIClient`** request path. + +## HTTP layer + +- **`_APIClient._call_request`** — central place for method, URL, JSON, files; respect **timeout** and **max_retries**. + +## Extending + +- Add methods on the appropriate resource class; align path and payload shapes with **CMA** docs. +- Prefer routing HTTP through **`_APIClient`** for consistent retries and OAuth handling. + +## Docs and versioning + +- Exported **`Client`**, **`Region`**, and stack helpers should match **README** and **`contentstack_management.__init__.py`**. +- Document migration for intentional breaking changes. + +## References + +- [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) +- **`skills/framework/SKILL.md`** +- **`skills/python-style/SKILL.md`** diff --git a/.cursor/rules/dev-workflow.md b/skills/dev-workflow/SKILL.md similarity index 52% rename from .cursor/rules/dev-workflow.md rename to skills/dev-workflow/SKILL.md index 87b6597..b2b9a50 100644 --- a/.cursor/rules/dev-workflow.md +++ b/skills/dev-workflow/SKILL.md @@ -1,14 +1,14 @@ --- -description: "Branches, install, and test layout for contentstack-management-python" -globs: - - "**/*.py" - - "setup.py" - - "requirements.txt" - - ".github/**/*.yml" -alwaysApply: false +name: dev-workflow +description: Install, pytest unit/API/mock, versioning, pylint, hooks—standard workflow for this SDK repo. --- -# Development workflow — `contentstack-management` +# Development workflow — Contentstack Management Python + +## When to use + +- Setting up locally, opening a PR, or matching CI expectations. +- Answering “how do we run tests?” or “what runs in CI?” ## Before a PR @@ -26,6 +26,14 @@ alwaysApply: false - **pylint** is listed in **`requirements.txt`**; follow existing style in touched files. - **Husky / Talisman / Snyk** — see **README.md** for local hook setup. -## Links +## Pull requests + +- Build passes: **`pytest tests/unit/`** at minimum; run **API** / **mock** when your change touches those layers. +- Follow **`skills/code-review/SKILL.md`** before merge. +- Prefer backward-compatible public API; call out breaking changes and semver. + +## References -- [`AGENTS.md`](../../AGENTS.md) · [`skills/contentstack-management-python/SKILL.md`](../../skills/contentstack-management-python/SKILL.md) +- **`AGENTS.md`** +- **`skills/contentstack-management/SKILL.md`** +- **`skills/testing/SKILL.md`** diff --git a/skills/framework/SKILL.md b/skills/framework/SKILL.md index 3d26ce8..6046c5b 100644 --- a/skills/framework/SKILL.md +++ b/skills/framework/SKILL.md @@ -1,13 +1,18 @@ --- name: framework -description: HTTP layer — requests-based _APIClient, retries, OAuth interceptor for the Management SDK. +description: requests-based _APIClient, retries, timeout, OAuth interceptor—central HTTP for the Management SDK. --- -# Framework skill — `requests` + `_APIClient` +# Framework / HTTP — Contentstack Management Python + +## When to use + +- Editing **`contentstack_management/_api_client.py`** or OAuth interceptor/handler wiring. +- Changing retry policy, timeouts, or how **`requests`** is invoked. ## Integration point -- **`contentstack_management/_api_client.py`** — **`_APIClient`** uses **`requests`** in **`_call_request`**, honors **timeout** and **max_retries**, and delegates to **`oauth_interceptor`** when configured. +- **`_APIClient`** uses **`requests`** in **`_call_request`**, honors **timeout** and **max_retries**, and delegates to **`oauth_interceptor`** when configured. ## When to change @@ -19,6 +24,8 @@ description: HTTP layer — requests-based _APIClient, retries, OAuth intercepto - **Unit** — mock **`requests`** or **`_APIClient`** at the boundary used by existing tests. - **API** — full stack via credentials from **`tests/cred.py`**. -## Rule shortcut +## References -- `.cursor/rules/contentstack-management-python.mdc` +- **`skills/contentstack-management/SKILL.md`** +- **`skills/dev-workflow/SKILL.md`** +- **`skills/testing/SKILL.md`** diff --git a/.cursor/rules/python.mdc b/skills/python-style/SKILL.md similarity index 58% rename from .cursor/rules/python.mdc rename to skills/python-style/SKILL.md index c36509e..d6ebb5f 100644 --- a/.cursor/rules/python.mdc +++ b/skills/python-style/SKILL.md @@ -1,13 +1,14 @@ --- -description: "Python conventions for the Management SDK package and packaging files" -globs: - - "contentstack_management/**/*.py" - - "setup.py" - - "requirements.txt" -alwaysApply: false +name: python-style +description: Package layout under contentstack_management/, setup.py, pylint-friendly style, imports, no secret logging. --- -# Python — `contentstack-management` +# Python style and repo layout — Contentstack Management Python + +## When to use + +- Editing any Python under **`contentstack_management/`**, **`setup.py`**, or **`requirements.txt`**. +- Adding modules or changing how the public package surface is exported. ## Layout @@ -19,7 +20,7 @@ alwaysApply: false ## Style - Match existing modules: naming, docstrings, and patterns already used in the same directory. -- Prefer small, focused changes; keep **`__init__.py`** exports consistent with public API intent. +- Prefer small, focused changes; keep **`__init__.py`** exports consistent with public API intent (**`README`**, **`contentstack_management.__all__`**). ## Imports @@ -28,3 +29,9 @@ alwaysApply: false ## Security - Do not log **authtokens**, **management tokens**, **passwords**, or **API keys**; preserve existing header handling in **`Client`**. + +## References + +- **`skills/framework/SKILL.md`** +- **`skills/contentstack-management/SKILL.md`** +- **`skills/testing/SKILL.md`** diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md index e0376a2..b583fa0 100644 --- a/skills/testing/SKILL.md +++ b/skills/testing/SKILL.md @@ -1,11 +1,24 @@ --- name: testing -description: pytest unit, api, and mock suites for contentstack-management-python. +description: pytest—unit, API, mock; tests/cred.py and .env; no committed secrets. --- -# Testing — `contentstack-management` +# Testing — Contentstack Management Python -## Commands +## When to use + +- Adding or changing tests under **`tests/`**. +- Debugging API vs mock failures; improving **`tests/cred.py`** usage. + +## Runner and tooling + +| Suite | Path | Notes | +|-------|------|--------| +| **Unit** | `tests/unit/**` | Fast, isolated; primary CI target | +| **API** | `tests/api/**` | Live CMA — **`.env`** via **`tests/cred.py`** | +| **Mock** | `tests/mock/**` | Mocked HTTP / contracts | + +### Commands | Goal | Command | |------|---------| @@ -14,13 +27,18 @@ description: pytest unit, api, and mock suites for contentstack-management-pytho | Mock | `pytest tests/mock/ -v` | | Full tree | `pytest tests/ -v` | -## Environment - -See **`tests/cred.py`** — **`get_credentials()`** after **`load_dotenv()`**. +## Environment (`tests/cred.py`) +- **`get_credentials()`** loads **dotenv** and returns host, tokens, and resource UIDs. - Common vars: **`HOST`**, **`APIKEY`**, **`AUTHTOKEN`**, **`MANAGEMENT_TOKEN`**, **`ORG_UID`**, plus resource UIDs as tests require. - Use a **`.env`** at repo root for local API runs; never commit secrets. +## Hygiene + +- No committed secrets; use placeholders or env-only values for CI. +- Avoid leaving **`pytest.skip`** or focused-only tests enabled in paths meant for full suite runs unless intentional. + ## References -- `.cursor/rules/testing.mdc` +- **`skills/dev-workflow/SKILL.md`** +- **`skills/code-review/SKILL.md`** From 9fa7935ed85195a6c02dc7517d3443de5a3ceb4e Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:16:21 +0530 Subject: [PATCH 3/3] Removed the reports --- tests/report/assets/style.css | 319 -------------- tests/report/test-report.html | 770 ---------------------------------- 2 files changed, 1089 deletions(-) delete mode 100644 tests/report/assets/style.css delete mode 100644 tests/report/test-report.html diff --git a/tests/report/assets/style.css b/tests/report/assets/style.css deleted file mode 100644 index 561524c..0000000 --- a/tests/report/assets/style.css +++ /dev/null @@ -1,319 +0,0 @@ -body { - font-family: Helvetica, Arial, sans-serif; - font-size: 12px; - /* do not increase min-width as some may use split screens */ - min-width: 800px; - color: #999; -} - -h1 { - font-size: 24px; - color: black; -} - -h2 { - font-size: 16px; - color: black; -} - -p { - color: black; -} - -a { - color: #999; -} - -table { - border-collapse: collapse; -} - -/****************************** - * SUMMARY INFORMATION - ******************************/ -#environment td { - padding: 5px; - border: 1px solid #e6e6e6; - vertical-align: top; -} -#environment tr:nth-child(odd) { - background-color: #f6f6f6; -} -#environment ul { - margin: 0; - padding: 0 20px; -} - -/****************************** - * TEST RESULT COLORS - ******************************/ -span.passed, -.passed .col-result { - color: green; -} - -span.skipped, -span.xfailed, -span.rerun, -.skipped .col-result, -.xfailed .col-result, -.rerun .col-result { - color: orange; -} - -span.error, -span.failed, -span.xpassed, -.error .col-result, -.failed .col-result, -.xpassed .col-result { - color: red; -} - -.col-links__extra { - margin-right: 3px; -} - -/****************************** - * RESULTS TABLE - * - * 1. Table Layout - * 2. Extra - * 3. Sorting items - * - ******************************/ -/*------------------ - * 1. Table Layout - *------------------*/ -#results-table { - border: 1px solid #e6e6e6; - color: #999; - font-size: 12px; - width: 100%; -} -#results-table th, -#results-table td { - padding: 5px; - border: 1px solid #e6e6e6; - text-align: left; -} -#results-table th { - font-weight: bold; -} - -/*------------------ - * 2. Extra - *------------------*/ -.logwrapper { - max-height: 230px; - overflow-y: scroll; - background-color: #e6e6e6; -} -.logwrapper.expanded { - max-height: none; -} -.logwrapper.expanded .logexpander:after { - content: "collapse [-]"; -} -.logwrapper .logexpander { - z-index: 1; - position: sticky; - top: 10px; - width: max-content; - border: 1px solid; - border-radius: 3px; - padding: 5px 7px; - margin: 10px 0 10px calc(100% - 80px); - cursor: pointer; - background-color: #e6e6e6; -} -.logwrapper .logexpander:after { - content: "expand [+]"; -} -.logwrapper .logexpander:hover { - color: #000; - border-color: #000; -} -.logwrapper .log { - min-height: 40px; - position: relative; - top: -50px; - height: calc(100% + 50px); - border: 1px solid #e6e6e6; - color: black; - display: block; - font-family: "Courier New", Courier, monospace; - padding: 5px; - padding-right: 80px; - white-space: pre-wrap; -} - -div.media { - border: 1px solid #e6e6e6; - float: right; - height: 240px; - margin: 0 5px; - overflow: hidden; - width: 320px; -} - -.media-container { - display: grid; - grid-template-columns: 25px auto 25px; - align-items: center; - flex: 1 1; - overflow: hidden; - height: 200px; -} - -.media-container--fullscreen { - grid-template-columns: 0px auto 0px; -} - -.media-container__nav--right, -.media-container__nav--left { - text-align: center; - cursor: pointer; -} - -.media-container__viewport { - cursor: pointer; - text-align: center; - height: inherit; -} -.media-container__viewport img, -.media-container__viewport video { - object-fit: cover; - width: 100%; - max-height: 100%; -} - -.media__name, -.media__counter { - display: flex; - flex-direction: row; - justify-content: space-around; - flex: 0 0 25px; - align-items: center; -} - -.collapsible td:not(.col-links) { - cursor: pointer; -} -.collapsible td:not(.col-links):hover::after { - color: #bbb; - font-style: italic; - cursor: pointer; -} - -.col-result { - width: 130px; -} -.col-result:hover::after { - content: " (hide details)"; -} - -.col-result.collapsed:hover::after { - content: " (show details)"; -} - -#environment-header h2:hover::after { - content: " (hide details)"; - color: #bbb; - font-style: italic; - cursor: pointer; - font-size: 12px; -} - -#environment-header.collapsed h2:hover::after { - content: " (show details)"; - color: #bbb; - font-style: italic; - cursor: pointer; - font-size: 12px; -} - -/*------------------ - * 3. Sorting items - *------------------*/ -.sortable { - cursor: pointer; -} -.sortable.desc:after { - content: " "; - position: relative; - left: 5px; - bottom: -12.5px; - border: 10px solid #4caf50; - border-bottom: 0; - border-left-color: transparent; - border-right-color: transparent; -} -.sortable.asc:after { - content: " "; - position: relative; - left: 5px; - bottom: 12.5px; - border: 10px solid #4caf50; - border-top: 0; - border-left-color: transparent; - border-right-color: transparent; -} - -.hidden, .summary__reload__button.hidden { - display: none; -} - -.summary__data { - flex: 0 0 550px; -} -.summary__reload { - flex: 1 1; - display: flex; - justify-content: center; -} -.summary__reload__button { - flex: 0 0 300px; - display: flex; - color: white; - font-weight: bold; - background-color: #4caf50; - text-align: center; - justify-content: center; - align-items: center; - border-radius: 3px; - cursor: pointer; -} -.summary__reload__button:hover { - background-color: #46a049; -} -.summary__spacer { - flex: 0 0 550px; -} - -.controls { - display: flex; - justify-content: space-between; -} - -.filters, -.collapse { - display: flex; - align-items: center; -} -.filters button, -.collapse button { - color: #999; - border: none; - background: none; - cursor: pointer; - text-decoration: underline; -} -.filters button:hover, -.collapse button:hover { - color: #ccc; -} - -.filter__label { - margin-right: 10px; -} diff --git a/tests/report/test-report.html b/tests/report/test-report.html deleted file mode 100644 index 53b9c40..0000000 --- a/tests/report/test-report.html +++ /dev/null @@ -1,770 +0,0 @@ - - - - - test-report.html - - - -

test-report.html

-

Report generated on 02-Apr-2026 at 11:33:13 by pytest-html - v4.1.1

-
-

Environment

-
-
- - - - - -
-
-

Summary

-
-
-

24 tests took 00:00:03.

-

(Un)check the boxes to filter the results.

-
- -
-
-
-
- - 0 Failed, - - 24 Passed, - - 0 Skipped, - - 0 Expected failures, - - 0 Unexpected passes, - - 0 Errors, - - 0 Reruns -
-
-  /  -
-
-
-
-
-
-
-
- - - - - - - - - -
ResultTestDurationLinks
- - - \ No newline at end of file