From 58ffeaec60093406157f72fbd87fdde1234aad08 Mon Sep 17 00:00:00 2001 From: raj pandey Date: Tue, 7 Apr 2026 13:57:01 +0530 Subject: [PATCH] update: added skill files --- .cursor/rules/README.md | 8 +++ .gitignore | 2 + AGENTS.md | 52 ++++++++++++++ skills/README.md | 39 +++++++++++ skills/aspnetcore-integration/SKILL.md | 36 ++++++++++ skills/code-review/SKILL.md | 44 ++++++++++++ skills/code-review/references/checklist.md | 55 +++++++++++++++ .../SKILL.md | 57 ++++++++++++++++ .../references/cma-architecture.md | 45 +++++++++++++ .../references/query-and-parameters.md | 48 +++++++++++++ skills/csharp-style/SKILL.md | 51 ++++++++++++++ skills/dev-workflow/SKILL.md | 51 ++++++++++++++ skills/documentation/SKILL.md | 35 ++++++++++ skills/framework/SKILL.md | 47 +++++++++++++ skills/http-pipeline/SKILL.md | 43 ++++++++++++ .../references/retry-and-handlers.md | 41 ++++++++++++ skills/testing/SKILL.md | 55 +++++++++++++++ skills/testing/references/mstest-patterns.md | 67 +++++++++++++++++++ 18 files changed, 776 insertions(+) create mode 100644 .cursor/rules/README.md create mode 100644 AGENTS.md create mode 100644 skills/README.md create mode 100644 skills/aspnetcore-integration/SKILL.md create mode 100644 skills/code-review/SKILL.md create mode 100644 skills/code-review/references/checklist.md create mode 100644 skills/contentstack-management-dotnet-sdk/SKILL.md create mode 100644 skills/contentstack-management-dotnet-sdk/references/cma-architecture.md create mode 100644 skills/contentstack-management-dotnet-sdk/references/query-and-parameters.md create mode 100644 skills/csharp-style/SKILL.md create mode 100644 skills/dev-workflow/SKILL.md create mode 100644 skills/documentation/SKILL.md create mode 100644 skills/framework/SKILL.md create mode 100644 skills/http-pipeline/SKILL.md create mode 100644 skills/http-pipeline/references/retry-and-handlers.md create mode 100644 skills/testing/SKILL.md create mode 100644 skills/testing/references/mstest-patterns.md diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 0000000..b56b916 --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,8 @@ +# Cursor (optional) + +**Cursor** users: + +- Start at **[`AGENTS.md`](../../AGENTS.md)** — project entry point and commands. +- Skills index and `references/` layout: **[`skills/README.md`](../../skills/README.md)**. + +All conventions live in **`skills/*/SKILL.md`** and linked **`skills/*/references/*.md`**. This folder only points contributors to those paths so editor-specific config does not duplicate the canonical docs. diff --git a/.gitignore b/.gitignore index f0d5f50..8b68604 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ api_referece/* *.html *.cobertura.xml integration-test-report_*.html +*.zip +.trx \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1a8fcbe --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,52 @@ +# Contentstack Management .NET SDK – Agent guide + +**Universal entry point** for contributors and AI agents. Detailed conventions live in **`skills/*/SKILL.md`**. + +## What this repo is + +| Field | Detail | +| ----- | ------ | +| **Name:** | [contentstack/contentstack-management-dotnet](https://github.com/contentstack/contentstack-management-dotnet) | +| **Purpose:** | .NET SDK for the [Content Management API (CMA)](https://www.contentstack.com/docs/developers/apis/content-management-api/)—manage stacks, content types, entries, assets, and related resources. | +| **Out of scope (if any):** | Content **delivery** to end users should use the Content Delivery API and its SDKs, not this package. This repo does not implement the CDA. | + +## Tech stack (at a glance) + +| Area | Details | +| ---- | ------- | +| **Language** | C# 8.0, nullable reference types enabled (`LangVersion` in core project). | +| **Build** | .NET SDK; main solution [`Contentstack.Management.Core.sln`](Contentstack.Management.Core.sln). Core library targets `netstandard2.0` (and `net471` / `net472` on Windows—see [`skills/framework/SKILL.md`](skills/framework/SKILL.md)). | +| **Tests** | MSTest; test projects target `net7.0`. Unit tests: [`Contentstack.Management.Core.Unit.Tests/`](Contentstack.Management.Core.Unit.Tests/). Integration tests: [`Contentstack.Management.Core.Tests/`](Contentstack.Management.Core.Tests/) (includes `IntegrationTest/`). | +| **Lint / coverage** | No repo-wide `dotnet format` / lint script at root. Rely on **.NET SDK analyzers** and IDE analysis. Tests use **coverlet** (`XPlat code coverage`) when run as in CI. | +| **Other** | NuGet packages: `contentstack.management.csharp` (core), `contentstack.management.aspnetcore` (ASP.NET Core helpers). Assembly signing via `CSManagementSDK.snk`. | + +## Commands (quick reference) + +| Command type | Command | +| ------------ | ------- | +| **Build** | `dotnet build Contentstack.Management.Core.sln` | +| **Test (CI-parity, unit)** | `sh ./Scripts/run-unit-test-case.sh` — runs `dotnet test` on [`Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj`](Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj) with TRX logger and coverlet. | +| **Test (integration)** | `dotnet test Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj` — requires local `appsettings.json` with credentials (see [`skills/testing/SKILL.md`](skills/testing/SKILL.md)). | +| **Pack (release)** | `dotnet pack -c Release -o out` (as in [`.github/workflows/nuget-publish.yml`](.github/workflows/nuget-publish.yml)). | + +**CI:** [`.github/workflows/unit-test.yml`](.github/workflows/unit-test.yml) (unit tests on PR/push). **Branches:** PRs normally target **`development`**; **`main`** is for **hotfixes**. PRs **into `main`** must come from **`staging`** per [`.github/workflows/check-branch.yml`](.github/workflows/check-branch.yml). + +## Where the documentation lives: skills + +| Skill | Path | What it covers | +| ----- | ---- | -------------- | +| Dev workflow | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) | Branches, CI, scripts, when to run which tests. | +| SDK (CMA) | [`skills/contentstack-management-dotnet-sdk/SKILL.md`](skills/contentstack-management-dotnet-sdk/SKILL.md) | Public API, auth, package boundaries. | +| Testing | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) | MSTest layout, unit vs integration, credentials, coverage. | +| Code review | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) | PR expectations and checklist. | +| Framework / platform | [`skills/framework/SKILL.md`](skills/framework/SKILL.md) | TFMs, signing, NuGet, HTTP pipeline overview. | +| C# style | [`skills/csharp-style/SKILL.md`](skills/csharp-style/SKILL.md) | Language and layout conventions for this repo. | +| HTTP pipeline (retries) | [`skills/http-pipeline/SKILL.md`](skills/http-pipeline/SKILL.md) | Handlers, retry policy, pipeline behavior. | +| ASP.NET Core integration | [`skills/aspnetcore-integration/SKILL.md`](skills/aspnetcore-integration/SKILL.md) | `contentstack.management.aspnetcore` package and DI. | +| Documentation (DocFX) | [`skills/documentation/SKILL.md`](skills/documentation/SKILL.md) | API docs under `docfx_project/`. | + +An index with **when to use** hints is in [`skills/README.md`](skills/README.md). + +## Using Cursor (optional) + +If you use **Cursor**, [`.cursor/rules/README.md`](.cursor/rules/README.md) points to **`AGENTS.md`** and **`skills/`**—same docs as everyone else; no duplicated prose in `.cursor`. diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..e5c88ec --- /dev/null +++ b/skills/README.md @@ -0,0 +1,39 @@ +# Skills – Contentstack Management .NET SDK + +Source of truth for detailed guidance. Read [`AGENTS.md`](../AGENTS.md) first, then open the skill that matches your task. + +## Project context + +| Area | This repo (CMA SDK) | +| ---- | ------------------- | +| **API** | [Content Management API (CMA)](https://www.contentstack.com/docs/developers/apis/content-management-api/) — not the Content Delivery API (CDA). | +| **Packages** | `contentstack.management.csharp` (core), `contentstack.management.aspnetcore` (DI helpers). | +| **HTTP** | `HttpClient` through [`ContentstackClient`](../Contentstack.Management.Core/ContentstackClient.cs) → runtime pipeline (`HttpHandler`, `RetryHandler`). | +| **Language / tests** | C# 8, nullable enabled. **MSTest** on **net7.0**; unit tests use **Moq** and **AutoFixture** where existing tests do. | + +## How to use these skills + +- **In the repo:** open `skills//SKILL.md` for the topic you need. Longer templates and checklists live under `skills//references/*.md` where linked. +- **In Cursor / other AI chats:** reference a skill by path, e.g. `skills/http-pipeline/SKILL.md` or `@skills/http-pipeline` if your tooling resolves that alias to this folder. + +## Example prompts + +- “Add a new CMA endpoint wrapper following `skills/contentstack-management-dotnet-sdk/SKILL.md` and `references/cma-architecture.md`.” +- “Adjust retry behavior for 429 responses using `skills/http-pipeline/` and update unit tests under `Contentstack.Management.Core.Unit.Tests/Runtime/Pipeline/`.” +- “Write a unit test with MSTest + Moq following `skills/testing/references/mstest-patterns.md`.” + +## When to use which skill + +| Skill folder | Use when | +| ------------ | -------- | +| [`dev-workflow/`](dev-workflow/) | Git branches, CI workflows, running build/test scripts, release/NuGet flow. | +| [`contentstack-management-dotnet-sdk/`](contentstack-management-dotnet-sdk/) | `ContentstackClient`, options, authentication, public API and package boundaries. | +| [`testing/`](testing/) | Writing or running unit/integration tests, MSTest, coverlet, local credentials. | +| [`code-review/`](code-review/) | Preparing or reviewing a PR against this repository. | +| [`framework/`](framework/) | Target frameworks, signing, NuGet packaging, OS-specific builds, high-level HTTP/runtime stack. | +| [`csharp-style/`](csharp-style/) | C# language version, nullable usage, naming and folder layout consistent with the repo. | +| [`http-pipeline/`](http-pipeline/) | Changing `HttpHandler`, `RetryHandler`, retry policy, or pipeline ordering. | +| [`aspnetcore-integration/`](aspnetcore-integration/) | `Contentstack.Management.ASPNETCore` package, `IHttpClientFactory`, DI registration. | +| [`documentation/`](documentation/) | Building or updating DocFX API documentation under `docfx_project/`. | + +Each folder contains **`SKILL.md`** with YAML frontmatter (`name`, `description`). **Deep dives:** see the **Quick reference** line at the top of each `SKILL.md` for links to `references/`. diff --git a/skills/aspnetcore-integration/SKILL.md b/skills/aspnetcore-integration/SKILL.md new file mode 100644 index 0000000..be0f3de --- /dev/null +++ b/skills/aspnetcore-integration/SKILL.md @@ -0,0 +1,36 @@ +--- +name: aspnetcore-integration +description: Use for the contentstack.management.aspnetcore package, HttpClient/DI registration with ASP.NET Core. +--- + +# ASP.NET Core integration – Contentstack Management .NET SDK + +## When to use + +- Changing [`Contentstack.Management.ASPNETCore/`](../../Contentstack.Management.ASPNETCore/) or the NuGet package **`contentstack.management.aspnetcore`**. +- Registering `ContentstackClient` with `IHttpClientFactory` / `IServiceCollection`. + +## Instructions + +### Package + +- **Package ID:** `contentstack.management.aspnetcore` +- **Target:** `netstandard2.1` +- **Project:** [`contentstack.management.aspnetcore.csproj`](../../Contentstack.Management.ASPNETCore/contentstack.management.aspnetcore.csproj) + +### Registration APIs + +- [`ServiceCollectionExtensions`](../../Contentstack.Management.ASPNETCore/ServiceCollectionExtensions.cs) in namespace `Microsoft.Extensions.DependencyInjection`: + - `AddContentstackClient(IServiceCollection, ContentstackClientOptions)` / `TryAddContentstackClient` — extend here when wiring options-based registration; keep behavior aligned with DI conventions. + - `AddContentstackClient(IServiceCollection, Action)` — registers `ContentstackClient` with **`AddHttpClient`** for typed client configuration. + +When extending DI support, align with Microsoft.Extensions.DependencyInjection and `Microsoft.Extensions.Http` patterns already referenced in the project file. + +### Core dependency + +- The ASP.NET Core project references the core management package; public types come from [`Contentstack.Management.Core`](../../Contentstack.Management.Core/). + +## References + +- [`../contentstack-management-dotnet-sdk/SKILL.md`](../contentstack-management-dotnet-sdk/SKILL.md) — core client and options. +- [`../framework/SKILL.md`](../framework/SKILL.md) — NuGet and TFMs. diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 0000000..c7a725a --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,44 @@ +--- +name: code-review +description: Use when reviewing or preparing a pull request for contentstack-management-dotnet. +--- + +# Code review – Contentstack Management .NET SDK + +**Deep dive:** [`references/checklist.md`](references/checklist.md) (copy-paste PR checklist sections). + +## When to use + +- Before requesting review or merging a PR. +- When auditing changes for API safety, tests, and repo policies. + +## Instructions + +### Branch and merge expectations + +- **Typical PRs** should target **`development`**. Use **`main`** as the base branch only for **hotfixes**. +- **When the base is `main`:** only PRs from **`staging`** are allowed (enforced by [`.github/workflows/check-branch.yml`](../../.github/workflows/check-branch.yml)). Confirm head/base match team intent before approving. + +### Summary checklist + +- **Purpose:** Change matches the ticket/PR description; no unrelated refactors. +- **Tests:** Unit tests updated or added for behavior changes; run `sh ./Scripts/run-unit-test-case.sh` locally for core changes. Integration tests only when behavior depends on live API—coordinate credentials. +- **API compatibility:** Public surface (`ContentstackClient`, options, models) changes are intentional and versioned appropriately; avoid breaking changes without major bump and changelog. +- **Security:** No secrets, tokens, or keys in source or commits; `appsettings.json` with real data must not be committed. +- **Signing:** If assembly signing is affected, confirm `CSManagementSDK.snk` usage matches [`../framework/SKILL.md`](../framework/SKILL.md). +- **Style:** Follow [`../csharp-style/SKILL.md`](../csharp-style/SKILL.md); match surrounding code. +- **Documentation:** User-visible behavior changes reflected in `README.md` or package release notes when needed. + +For markdown blocks to paste into PRs, use [`references/checklist.md`](references/checklist.md). + +### Severity (optional labels) + +- **Blocker:** Build or CI broken; security issue; violates branch policy. +- **Major:** Missing tests for risky logic; breaking API without process. +- **Minor:** Naming nits, non-user-facing cleanup. + +## References + +- [`references/checklist.md`](references/checklist.md) — detailed PR checklist. +- [`../dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) — CI and branches. +- [`../contentstack-management-dotnet-sdk/SKILL.md`](../contentstack-management-dotnet-sdk/SKILL.md) — API boundaries. diff --git a/skills/code-review/references/checklist.md b/skills/code-review/references/checklist.md new file mode 100644 index 0000000..3390f7b --- /dev/null +++ b/skills/code-review/references/checklist.md @@ -0,0 +1,55 @@ +# PR review checklist (CMA Management SDK) + +Copy sections into a PR comment when useful. This checklist is for **this** repo (`HttpClient` + pipeline + MSTest), **not** the Content Delivery .NET SDK. + +## Branch policy + +```markdown +- [ ] **Default:** PR targets **`development`** unless this is a documented **hotfix** to **`main`** +- [ ] If base is **`main`**: head branch is **`staging`** (see `.github/workflows/check-branch.yml`) +``` + +## Breaking changes + +```markdown +- [ ] No public method/property removed or narrowed without deprecation / major version plan +- [ ] `JsonProperty` / JSON names for API-facing models unchanged unless intentional and documented +- [ ] New required `ContentstackClientOptions` fields have safe defaults or are optional +- [ ] Strong naming: assembly signing still consistent if keys or `csproj` changed +``` + +## HTTP and pipeline + +```markdown +- [ ] New or changed HTTP calls go through existing client/pipeline (`ContentstackClient` → `IContentstackService` → pipeline), not ad-hoc `HttpClient` usage inside services without justification +- [ ] Retry-sensitive changes reviewed alongside `RetryHandler` / `DefaultRetryPolicy` and unit tests under `Contentstack.Management.Core.Unit.Tests/Runtime/Pipeline/` +- [ ] Headers, query params, and path segments align with CMA docs; no hardcoded production URLs where options.Host should be used +``` + +## Services and query API + +```markdown +- [ ] `IContentstackService` implementations set `ResourcePath`, `HttpMethod`, `Parameters` / `QueryResources` / `PathResources` / `Content` consistently with sibling services +- [ ] New fluent `Query` methods only add to `ParameterCollection` with correct API parameter names +``` + +## Tests + +```markdown +- [ ] Unit tests use MSTest; `sh ./Scripts/run-unit-test-case.sh` passes for core changes +- [ ] Integration tests only when needed; no secrets committed (`appsettings.json` stays local) +``` + +## Security and hygiene + +```markdown +- [ ] No API keys, tokens, or passwords in source or test data checked into git +- [ ] OAuth / token handling does not log secrets +``` + +## Documentation + +```markdown +- [ ] User-visible behavior reflected in `README.md` or release notes when appropriate +- [ ] `skills/` or `references/` updated if agent/contributor workflow changed +``` diff --git a/skills/contentstack-management-dotnet-sdk/SKILL.md b/skills/contentstack-management-dotnet-sdk/SKILL.md new file mode 100644 index 0000000..e59d092 --- /dev/null +++ b/skills/contentstack-management-dotnet-sdk/SKILL.md @@ -0,0 +1,57 @@ +--- +name: contentstack-management-dotnet-sdk +description: Use when changing or using the CMA client API, authentication, or NuGet package surface for Contentstack.Management.Core. +--- + +# Contentstack Management .NET SDK (CMA) + +**Deep dive:** [`references/cma-architecture.md`](references/cma-architecture.md) (request flow, `IContentstackService`), [`references/query-and-parameters.md`](references/query-and-parameters.md) (fluent `Query`, `ParameterCollection`). + +## When to use + +- Adding or changing `ContentstackClient` behavior, options, or service entry points. +- Documenting how consumers authenticate (management token, authtoken, login). +- Reviewing breaking vs compatible changes for the NuGet package `contentstack.management.csharp`. + +## Instructions + +### Packages and entry points + +| Package ID | Project | Role | +| ---------- | ------- | ---- | +| `contentstack.management.csharp` | [`Contentstack.Management.Core/`](../../Contentstack.Management.Core/) | Main SDK; `ContentstackClient`, models, services. | +| `contentstack.management.aspnetcore` | [`Contentstack.Management.ASPNETCore/`](../../Contentstack.Management.ASPNETCore/) | ASP.NET Core registration helpers; see [`../aspnetcore-integration/SKILL.md`](../aspnetcore-integration/SKILL.md). | + +- Primary type: [`ContentstackClient`](../../Contentstack.Management.Core/ContentstackClient.cs) (`IContentstackClient`). +- Configuration: [`ContentstackClientOptions`](../../Contentstack.Management.Core/ContentstackClientOptions.cs) (and related options types). + +### Authentication (high level) + +- **Management token:** stack-scoped token; typical pattern `client.Stack(apiKey, managementToken)` per product docs. +- **Authtoken:** user/session token on the client options. +- **Login with credentials:** `ContentstackClient.Login` / `LoginAsync` with `NetworkCredential` (see root [`README.md`](../../README.md) examples). + +OAuth-related code lives under [`Services/OAuth/`](../../Contentstack.Management.Core/Services/OAuth/), [`OAuthHandler.cs`](../../Contentstack.Management.Core/OAuthHandler.cs), and [`Utils/PkceHelper.cs`](../../Contentstack.Management.Core/Utils/PkceHelper.cs). Prefer small, testable changes; preserve existing public contracts unless doing a major version bump. + +### Serialization and models + +- JSON serialization and converters are configured in `ContentstackClient` (e.g. custom `JsonConverter` types for fields and nodes). +- Domain models live under [`Models/`](../../Contentstack.Management.Core/Models/). Follow existing patterns when adding types. + +### Errors + +- Exceptions and error mapping: [`Exceptions/`](../../Contentstack.Management.Core/Exceptions/). Keep messages and HTTP status handling consistent with existing patterns. + +### Integration boundaries + +- The SDK talks to Contentstack **Management** HTTP APIs. Do not confuse with Delivery API clients. +- HTTP behavior (retries, handlers) is documented under [`../framework/SKILL.md`](../framework/SKILL.md) and [`../http-pipeline/SKILL.md`](../http-pipeline/SKILL.md). + +## References + +- [`references/cma-architecture.md`](references/cma-architecture.md) — architecture and invocation flow. +- [`references/query-and-parameters.md`](references/query-and-parameters.md) — fluent query API. +- [`../framework/SKILL.md`](../framework/SKILL.md) — TFMs, NuGet, pipeline overview. +- [`../http-pipeline/SKILL.md`](../http-pipeline/SKILL.md) — retries and handlers. +- [`../csharp-style/SKILL.md`](../csharp-style/SKILL.md) — C# conventions. +- [Content Management API](https://www.contentstack.com/docs/developers/apis/content-management-api/) (official docs). diff --git a/skills/contentstack-management-dotnet-sdk/references/cma-architecture.md b/skills/contentstack-management-dotnet-sdk/references/cma-architecture.md new file mode 100644 index 0000000..694de40 --- /dev/null +++ b/skills/contentstack-management-dotnet-sdk/references/cma-architecture.md @@ -0,0 +1,45 @@ +# CMA SDK architecture (Management .NET) + +This document describes how requests flow through **this** SDK. It is **not** the Content Delivery (CDA) client: there is no `HttpWebRequest`-only layer or delivery-token query-string-only rule set here. + +## Entry and configuration + +1. **`ContentstackClient`** ([`ContentstackClient.cs`](../../../Contentstack.Management.Core/ContentstackClient.cs)) is the public entry point. +2. **`ContentstackClientOptions`** ([`ContentstackClientOptions.cs`](../../../Contentstack.Management.Core/ContentstackClientOptions.cs)) holds `Host`, tokens, proxy, retry settings, and optional custom `RetryPolicy`. +3. The client builds a **`ContentstackRuntimePipeline`** in `BuildPipeline()` (see [`../../framework/SKILL.md`](../../framework/SKILL.md) and [`../../http-pipeline/SKILL.md`](../../http-pipeline/SKILL.md)): **`HttpHandler`** → **`RetryHandler`**. + +## Stack-scoped API + +- **`Stack`** ([`Models/Stack.cs`](../../../Contentstack.Management.Core/Models/Stack.cs)) is obtained from the client (e.g. `client.Stack(apiKey, managementToken)` or overloads). Most management operations are stack-relative. +- Domain types under **`Models/`** (entries, assets, content types, etc.) expose methods that construct or call **`IContentstackService`** implementations. + +## Service interface and invocation + +- **`IContentstackService`** ([`Services/IContentstackService.cs`](../../../Contentstack.Management.Core/Services/IContentstackService.cs)) defines one CMA operation: resource path, HTTP method, headers, query/path resources, body (`HttpContent`), and hooks to build the outbound request and handle the response. +- The client executes services via **`InvokeSync`** / **`InvokeAsync`**, which run the pipeline and return **`ContentstackResponse`**. + +Important members on `IContentstackService`: + +- **`Parameters`** — [`ParameterCollection`](../../../Contentstack.Management.Core/Queryable/ParameterCollection.cs) for typed query/body parameters (used by list/query flows). +- **`QueryResources`**, **`PathResources`**, **`AddQueryResource`**, **`AddPathResource`** — URL composition. +- **`UseQueryString`** — some operations send parameters as query string instead of body. +- **`CreateHttpRequest`** / **`OnResponse`** — integrate with [`ContentstackHttpRequest`](../../../Contentstack.Management.Core/Http/ContentstackHttpRequest.cs) and response parsing. + +Concrete services live under **`Services/`** (including nested folders by domain, e.g. stack, organization, OAuth). + +## Fluent list queries (`Queryable`) + +- **`Query`** ([`Queryable/Query.cs`](../../../Contentstack.Management.Core/Queryable/Query.cs)) provides a fluent API (`Limit`, `Skip`, `IncludeCount`, …) backed by an internal **`ParameterCollection`**. +- **`Find()`** / **`FindAsync()`** merge an optional extra `ParameterCollection`, construct **`QueryService`**, and invoke the client sync/async. See [`query-and-parameters.md`](query-and-parameters.md). + +## OAuth and auth + +- User/session auth, management tokens, and login flows are described at a high level in [`../SKILL.md`](../SKILL.md). Implementation details span **`OAuthHandler`**, **`Services/OAuth/`**, and client token dictionaries on **`ContentstackClient`**. + +## Adding a feature (checklist) + +1. Confirm the CMA contract (path, method, query vs body) from official API docs. +2. Implement or extend an **`IContentstackService`** (or reuse patterns from a sibling service in `Services/`). +3. Expose a method on the appropriate **`Stack`** / model type; keep public API consistent with existing naming. +4. Add **unit tests** (MSTest + mocks); add **integration** tests only when live API coverage is required. +5. If behavior touches HTTP retries or status codes, coordinate with [`../../http-pipeline/SKILL.md`](../../http-pipeline/SKILL.md). diff --git a/skills/contentstack-management-dotnet-sdk/references/query-and-parameters.md b/skills/contentstack-management-dotnet-sdk/references/query-and-parameters.md new file mode 100644 index 0000000..560fec2 --- /dev/null +++ b/skills/contentstack-management-dotnet-sdk/references/query-and-parameters.md @@ -0,0 +1,48 @@ +# Query and parameters (fluent list API) + +The management SDK exposes a **fluent `Query`** type for listing resources (stacks, entries, assets, roles, etc.). It is separate from the Content Delivery SDK’s query DSL. + +## Types + +| Type | Location | Role | +| ---- | -------- | ---- | +| **`Query`** | [`Queryable/Query.cs`](../../../Contentstack.Management.Core/Queryable/Query.cs) | Fluent methods add entries to an internal `ParameterCollection`, then `Find` / `FindAsync` runs `QueryService`. | +| **`ParameterCollection`** | [`Queryable/ParameterCollection.cs`](../../../Contentstack.Management.Core/Queryable/ParameterCollection.cs) | `SortedDictionary` with overloads for `string`, `double`, `bool`, `List`, etc. | + +## Typical usage pattern + +Models such as **`Entry`**, **`Asset`**, **`Role`**, **`Stack`** expose **`Query()`** returning a **`Query`** bound to that resource path. Chain parameters, then call **`Find()`** or **`FindAsync()`**: + +```csharp +// Illustrative — see XML examples on Query/Stack/Entry in the codebase. +ContentstackResponse response = client + .Stack("", "") + .ContentType("") + .Entry() + .Query() + .Limit(10) + .Skip(0) + .Find(); +``` + +Requirements enforced by **`Query`**: + +- Stack must be logged in where applicable (`ThrowIfNotLoggedIn`). +- Stack API key must be present for the call (`ThrowIfAPIKeyEmpty`). + +## Extra parameters on `Find` + +`Find(ParameterCollection collection = null)` and `FindAsync` merge an optional **`ParameterCollection`** into the query before building **`QueryService`**. Use this when ad-hoc parameters are not exposed as fluent methods. + +## Implementing new fluent methods + +1. Add a method on **`Query`** that calls `_collection.Add("api_key", value)` (or the appropriate `ParameterCollection` overload). +2. Return **`this`** for chaining. +3. Add XML documentation with a short `` consistent with existing **`Query`** members. +4. Add unit tests if serialization or parameter keys are non-trivial. + +## Relationship to `IContentstackService` + +List operations ultimately construct a **`QueryService`** that implements **`IContentstackService`** and is executed through **`ContentstackClient.InvokeSync` / `InvokeAsync`**. Path and HTTP details live on the service; the fluent API only shapes **`ParameterCollection`**. + +For full request flow, see [`cma-architecture.md`](cma-architecture.md). diff --git a/skills/csharp-style/SKILL.md b/skills/csharp-style/SKILL.md new file mode 100644 index 0000000..195066e --- /dev/null +++ b/skills/csharp-style/SKILL.md @@ -0,0 +1,51 @@ +--- +name: csharp-style +description: Use for C# language level, nullable usage, and file/folder layout consistent with Contentstack.Management.Core. +--- + +# C# style – Contentstack Management .NET SDK + +## When to use + +- Writing new C# code in `Contentstack.Management.Core` or test projects. +- Choosing names, nullability, and structure for PRs. + +## Instructions + +### Language version + +- Core library uses **C# 8.0** (`LangVersion` in [`contentstack.management.core.csproj`](../../Contentstack.Management.Core/contentstack.management.core.csproj)). +- **Nullable reference types** are enabled (`Nullable` is `enable`). Prefer explicit nullability on public APIs (`?`, `!` only when justified and consistent with existing code). + +### Project layout (core) + +Follow existing top-level folders: + +- `Services/` — API-facing service classes by domain (stack, organization, OAuth, etc.). +- `Models/` — DTOs and domain models (including `Models/Fields/`). +- `Runtime/` — pipeline, HTTP handlers, execution context. +- `Exceptions/` — SDK exception types. +- `Abstractions/`, `Queryable/`, `Utils/` — as used today. + +New features should land in the same folder that similar code uses; avoid new root folders without team agreement. + +### Naming and patterns + +- Match existing naming: PascalCase for public types and methods; private fields often camelCase with underscore prefix where already used in the file. +- Prefer `async`/`await` patterns consistent with neighboring methods when adding asynchronous APIs. +- Keep XML doc comments on public surface when the rest of the type is documented that way. + +### Tests + +- MSTest: `[TestClass]`, `[TestMethod]`, `[ClassInitialize]` where the suite requires shared setup (see integration tests). +- Use existing assertion helpers (e.g. `AssertLogger` in integration tests) where applicable. + +### What not to do + +- Do not introduce a different language version or disable nullable without an explicit team decision. +- Do not impose style rules that contradict the majority of files in the same directory. + +## References + +- [`../contentstack-management-dotnet-sdk/SKILL.md`](../contentstack-management-dotnet-sdk/SKILL.md) — API surface. +- [`../testing/SKILL.md`](../testing/SKILL.md) — test conventions. diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md new file mode 100644 index 0000000..c6f184b --- /dev/null +++ b/skills/dev-workflow/SKILL.md @@ -0,0 +1,51 @@ +--- +name: dev-workflow +description: Use for branches, CI, build/test scripts, and NuGet release flow in contentstack-management-dotnet. +--- + +# Dev workflow – Contentstack Management .NET SDK + +## When to use + +- Changing or debugging GitHub Actions workflows. +- Running the same build/test commands as CI locally. +- Preparing a release or understanding how packages are published. + +## Instructions + +### Branch policy + +- **Default workflow:** open PRs against **`development`** for regular feature and fix work. **`main`** is reserved for **hotfixes** (PRs raised directly to `main` only when patching production). +- **When the PR target is `main`:** GitHub Actions requires the head branch to be **`staging`**—other head branches are rejected by [`.github/workflows/check-branch.yml`](../../.github/workflows/check-branch.yml). Coordinate with SRE/release if a hotfix must use a different flow. +- Do not bypass enforced checks without org approval. + +### Key workflows + +| Workflow | Role | +| -------- | ---- | +| [`unit-test.yml`](../../.github/workflows/unit-test.yml) | On PR and push: runs [`Scripts/run-unit-test-case.sh`](../../Scripts/run-unit-test-case.sh) (unit tests + TRX + coverlet). | +| [`check-branch.yml`](../../.github/workflows/check-branch.yml) | For PRs **into `main`**, enforces head branch **`staging`**. | +| [`nuget-publish.yml`](../../.github/workflows/nuget-publish.yml) | On release: `dotnet pack -c Release -o out` and push to NuGet / GitHub Packages. | +| [`policy-scan.yml`](../../.github/workflows/policy-scan.yml), [`sca-scan.yml`](../../.github/workflows/sca-scan.yml) | Security / compliance scans. | + +### Local commands + +- **Build:** `dotnet build Contentstack.Management.Core.sln` +- **Unit tests (matches CI):** `sh ./Scripts/run-unit-test-case.sh` from repo root (cleans `Contentstack.Management.Core.Unit.Tests/TestResults` first). +- **Integration tests:** separate project; see [`../testing/SKILL.md`](../testing/SKILL.md). + +### Scripts + +- [`Scripts/run-unit-test-case.sh`](../../Scripts/run-unit-test-case.sh) — unit test entrypoint used in CI. +- [`Scripts/generate_integration_test_report.py`](../../Scripts/generate_integration_test_report.py) — integration test reporting helper (if used by the team). + +### Signing and secrets + +- Contributors need `CSManagementSDK.snk` for a full signed build matching the repo; see [`../framework/SKILL.md`](../framework/SKILL.md). +- NuGet push uses repository secrets (`NUGET_API_KEY`, etc.)—never commit keys. + +## References + +- [`../framework/SKILL.md`](../framework/SKILL.md) — TFMs, pack, signing. +- [`../testing/SKILL.md`](../testing/SKILL.md) — test projects and credentials. +- [`../../AGENTS.md`](../../AGENTS.md) — top-level commands table. diff --git a/skills/documentation/SKILL.md b/skills/documentation/SKILL.md new file mode 100644 index 0000000..d9c3d0d --- /dev/null +++ b/skills/documentation/SKILL.md @@ -0,0 +1,35 @@ +--- +name: documentation +description: Use when building or updating DocFX API documentation under docfx_project for this repository. +--- + +# Documentation (DocFX) – Contentstack Management .NET SDK + +## When to use + +- Regenerating or editing API reference docs. +- Updating [`docfx_project/docfx.json`](../../docfx_project/docfx.json), TOC, or filters. + +## Instructions + +### Layout + +- DocFX project root: [`docfx_project/`](../../docfx_project/) +- Key files: [`docfx.json`](../../docfx_project/docfx.json), [`toc.yml`](../../docfx_project/toc.yml), [`filterRules.yml`](../../docfx_project/filterRules.yml), [`index.md`](../../docfx_project/index.md) + +### Metadata source + +- `docfx.json` metadata section references project files under `src/**.csproj` in the DocFX config; **verify paths** match this repo’s layout (core library lives under `Contentstack.Management.Core/`, not necessarily `src/`). Update metadata `src` paths if doc generation fails after moves. + +### Build + +- Install DocFX per [official instructions](https://dotnet.github.io/docfx/), then run from `docfx_project` (typical: `docfx docfx.json` or `docfx build docfx.json`). Exact CLI may vary by DocFX version—use the version your team standardizes on. + +### Relationship to product docs + +- End-user NuGet and usage examples stay in root [`README.md`](../../README.md). DocFX is for **API reference** material. + +## References + +- [`../dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) — if docs become part of CI later. +- [DocFX](https://dotnet.github.io/docfx/) (official). diff --git a/skills/framework/SKILL.md b/skills/framework/SKILL.md new file mode 100644 index 0000000..4c71073 --- /dev/null +++ b/skills/framework/SKILL.md @@ -0,0 +1,47 @@ +--- +name: framework +description: Use for target frameworks, assembly signing, NuGet packaging, OS-specific builds, and HTTP pipeline overview in Contentstack.Management.Core. +--- + +# Framework and platform – Contentstack Management .NET SDK + +## When to use + +- Changing `TargetFrameworks`, signing, or package metadata. +- Debugging build differences between Windows and macOS/Linux. +- Understanding how `ContentstackClient` wires `HttpClient` and the runtime pipeline (before diving into retry details). + +## Instructions + +### Target frameworks + +- [`Contentstack.Management.Core/contentstack.management.core.csproj`](../../Contentstack.Management.Core/contentstack.management.core.csproj): + - **Windows:** `netstandard2.0;net471;net472` + - **Non-Windows:** `netstandard2.0` only (full framework TFMs need Windows reference assemblies). +- Test projects target **`net7.0`**. +- [`Contentstack.Management.ASPNETCore/contentstack.management.aspnetcore.csproj`](../../Contentstack.Management.ASPNETCore/contentstack.management.aspnetcore.csproj): `netstandard2.1`. + +### Assembly signing + +- Core and test projects reference **`CSManagementSDK.snk`** via `SignAssembly` / `AssemblyOriginatorKeyFile`. +- Keep strong-name policy consistent when adding new shipped assemblies. + +### NuGet + +- Core package ID: **`contentstack.management.csharp`** (see `PackageId` in core `.csproj`). +- ASP.NET Core package ID: **`contentstack.management.aspnetcore`**. +- Local pack: `dotnet pack -c Release -o out` (see [`.github/workflows/nuget-publish.yml`](../../.github/workflows/nuget-publish.yml)). + +### HTTP stack overview + +- [`ContentstackClient.BuildPipeline`](../../Contentstack.Management.Core/ContentstackClient.cs) constructs a **`ContentstackRuntimePipeline`** with: + - [`HttpHandler`](../../Contentstack.Management.Core/Runtime/Pipeline/HttpHandler/HttpHandler.cs) — sends HTTP requests. + - [`RetryHandler`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryHandler.cs) — applies retry policy (default or custom). +- Options: [`RetryConfiguration`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryConfiguration.cs) and `ContentstackClientOptions` retry-related settings. +- For deep changes to retry rules, handler ordering, or custom `RetryPolicy`, see [`../http-pipeline/SKILL.md`](../http-pipeline/SKILL.md). + +## References + +- [`../http-pipeline/SKILL.md`](../http-pipeline/SKILL.md) — pipeline and retries in detail. +- [`../dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) — CI and pack commands. +- [`../contentstack-management-dotnet-sdk/SKILL.md`](../contentstack-management-dotnet-sdk/SKILL.md) — public API. diff --git a/skills/http-pipeline/SKILL.md b/skills/http-pipeline/SKILL.md new file mode 100644 index 0000000..437ee1e --- /dev/null +++ b/skills/http-pipeline/SKILL.md @@ -0,0 +1,43 @@ +--- +name: http-pipeline +description: Use when changing HTTP handlers, retry behavior, or pipeline ordering in Contentstack.Management.Core.Runtime.Pipeline. +--- + +# HTTP pipeline and retries – Contentstack Management .NET SDK + +**Deep dive:** [`references/retry-and-handlers.md`](references/retry-and-handlers.md) (handler order, configuration, tests). + +## When to use + +- Modifying [`RetryHandler`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryHandler.cs), [`DefaultRetryPolicy`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/DefaultRetryPolicy.cs), or [`RetryConfiguration`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryConfiguration.cs). +- Adding or reordering pipeline handlers in [`ContentstackClient.BuildPipeline`](../../Contentstack.Management.Core/ContentstackClient.cs). +- Debugging retry loops, HTTP status codes treated as retryable, or network error classification. + +## Instructions + +### Pipeline construction + +- [`ContentstackClient.BuildPipeline`](../../Contentstack.Management.Core/ContentstackClient.cs) creates: + 1. [`HttpHandler`](../../Contentstack.Management.Core/Runtime/Pipeline/HttpHandler/HttpHandler.cs) — wraps the SDK `HttpClient`. + 2. [`RetryHandler`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryHandler.cs) — applies `RetryPolicy` (custom from options, or `DefaultRetryPolicy` from `RetryConfiguration.FromOptions`). + +- Custom policies: `ContentstackClientOptions.RetryPolicy` can supply a user-defined `RetryPolicy`; otherwise `DefaultRetryPolicy` + `RetryConfiguration` apply. + +### Retry configuration + +- Defaults and toggles (retry limit, delay, which error classes to retry) live in [`RetryConfiguration`](../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryConfiguration.cs). +- HTTP status codes handled by default policy include 5xx, 429, timeouts, and related cases—see `DefaultRetryPolicy` for the authoritative set. + +### Tests + +- Unit tests under [`Contentstack.Management.Core.Unit.Tests/Runtime/Pipeline/`](../../Contentstack.Management.Core.Unit.Tests/Runtime/Pipeline/) (e.g. `RetryHandler`, `RetryDelayCalculator`) should be updated when behavior changes. + +### Relationship to other docs + +- [`../framework/SKILL.md`](../framework/SKILL.md) has a short overview; this skill is the **detailed** place for pipeline edits. + +## References + +- [`references/retry-and-handlers.md`](references/retry-and-handlers.md) — retries and handlers detail. +- [`../framework/SKILL.md`](../framework/SKILL.md) — TFMs and packaging. +- [`../contentstack-management-dotnet-sdk/SKILL.md`](../contentstack-management-dotnet-sdk/SKILL.md) — client options and public API. diff --git a/skills/http-pipeline/references/retry-and-handlers.md b/skills/http-pipeline/references/retry-and-handlers.md new file mode 100644 index 0000000..c99c66f --- /dev/null +++ b/skills/http-pipeline/references/retry-and-handlers.md @@ -0,0 +1,41 @@ +# Retry handlers and pipeline (deep dive) + +## Handler order + +[`ContentstackClient.BuildPipeline`](../../../Contentstack.Management.Core/ContentstackClient.cs) registers handlers in this **outer-to-inner** order for execution: + +1. **`HttpHandler`** ([`HttpHandler.cs`](../../../Contentstack.Management.Core/Runtime/Pipeline/HttpHandler/HttpHandler.cs)) — sends the `HttpRequestMessage` via the SDK’s `HttpClient`. +2. **`RetryHandler`** ([`RetryHandler.cs`](../../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryHandler.cs)) — wraps the inner handler and applies **`RetryPolicy`**. + +Incoming calls traverse **RetryHandler** first, which delegates to **HttpHandler** for the actual HTTP call, then inspects success/failure and may retry. + +## Policy selection + +- If **`ContentstackClientOptions.RetryPolicy`** is set, that instance is used. +- Otherwise **`RetryConfiguration.FromOptions(contentstackOptions)`** builds a **`RetryConfiguration`**, then **`new DefaultRetryPolicy(retryConfiguration)`**. + +## `RetryConfiguration` (high level) + +[`RetryConfiguration.cs`](../../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/RetryConfiguration.cs) controls: + +- **`RetryOnError`**, **`RetryLimit`**, **`RetryDelay`** +- Network vs HTTP retries: **`RetryOnNetworkFailure`**, **`RetryOnDnsFailure`**, **`RetryOnSocketFailure`**, **`MaxNetworkRetries`**, **`NetworkRetryDelay`**, **`RetryOnHttpServerError`**, etc. + +Exact defaults and edge cases belong in code comments and unit tests—**do not duplicate** the full matrix here; change the source and tests together. + +## HTTP status codes (default policy) + +[`DefaultRetryPolicy`](../../../Contentstack.Management.Core/Runtime/Pipeline/RetryHandler/DefaultRetryPolicy.cs) maintains a set of status codes that may trigger HTTP retries (e.g. selected 5xx, 429, timeouts, **Unauthorized** in the default set). When adjusting this list, consider: + +- Risk of retrying non-idempotent operations. +- Interaction with auth refresh / OAuth flows on **`ContentstackClient`**. + +## Where to add tests + +- **`Contentstack.Management.Core.Unit.Tests/Runtime/Pipeline/`** — `RetryHandler`, `RetryDelayCalculator`, `DefaultRetryPolicy`, `NetworkErrorDetector`, etc. +- Keep tests deterministic (short delays, mocked inner handlers). + +## Related skills + +- [`../SKILL.md`](../SKILL.md) — summary for agents. +- [`../../framework/SKILL.md`](../../framework/SKILL.md) — TFMs and packaging. diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md new file mode 100644 index 0000000..8120e3d --- /dev/null +++ b/skills/testing/SKILL.md @@ -0,0 +1,55 @@ +--- +name: testing +description: Use for MSTest projects, unit vs integration tests, coverlet/TRX output, and local credentials in contentstack-management-dotnet. +--- + +# Testing – Contentstack Management .NET SDK + +**Deep dive:** [`references/mstest-patterns.md`](references/mstest-patterns.md) (MSTest, AutoFixture, Moq templates). + +## When to use + +- Adding or fixing unit or integration tests. +- Reproducing CI test failures (TRX, coverage). +- Setting up `appsettings.json` for integration tests. + +## Instructions + +### Projects + +| Project | Path | Purpose | +| ------- | ---- | ------- | +| Unit tests | [`Contentstack.Management.Core.Unit.Tests/`](../../Contentstack.Management.Core.Unit.Tests/) | Fast, isolated tests; **this is what CI runs** via [`Scripts/run-unit-test-case.sh`](../../Scripts/run-unit-test-case.sh). | +| Integration tests | [`Contentstack.Management.Core.Tests/`](../../Contentstack.Management.Core.Tests/) | Real API tests under `IntegrationTest/`; requires credentials. | + +- **Framework:** MSTest (`Microsoft.VisualStudio.TestTools.UnitTesting`). +- **Target framework:** `net7.0` for both test projects. +- **Coverage:** `coverlet.collector` with `--collect:"XPlat code coverage"` in the unit test script. + +### CI parity (unit) + +From repo root: + +```bash +sh ./Scripts/run-unit-test-case.sh +``` + +- TRX output: `Contentstack.Management.Core.Unit.Tests/TestResults/Report-Contentstack-DotNet-Test-Case.trx` (logger file name in script). +- The script deletes `Contentstack.Management.Core.Unit.Tests/TestResults` before running. + +### Integration tests and credentials + +- Helper: [`Contentstack.Management.Core.Tests/Contentstack.cs`](../../Contentstack.Management.Core.Tests/Contentstack.cs) loads **`appsettings.json`** via `ConfigurationBuilder` and exposes `Contentstack.CreateAuthenticatedClient()` (login using credentials from config—**never commit real secrets**). +- Add `appsettings.json` locally (it is not checked in; keep secrets out of git). Structure includes `Contentstack` section and nested `Contentstack:Credentials`, `Contentstack:Organization` as used by the tests. +- Integration tests use `[ClassInitialize]` / `[DoNotParallelize]` in many classes; follow existing patterns when adding scenarios. + +### Hygiene + +- Do not commit TRX zips, ad-hoc `TestResults` archives, or credential files. +- Prefer deterministic unit tests with mocks (see existing `Mokes/` / `Mock/` usage in unit tests). + +## References + +- [`references/mstest-patterns.md`](references/mstest-patterns.md) — unit test templates and tooling. +- [`../dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) — CI workflow that runs unit tests. +- [`../../Scripts/run-unit-test-case.sh`](../../Scripts/run-unit-test-case.sh) — exact `dotnet test` arguments. diff --git a/skills/testing/references/mstest-patterns.md b/skills/testing/references/mstest-patterns.md new file mode 100644 index 0000000..cfed865 --- /dev/null +++ b/skills/testing/references/mstest-patterns.md @@ -0,0 +1,67 @@ +# MSTest patterns (unit tests) + +This repo uses **MSTest** (`Microsoft.VisualStudio.TestTools.UnitTesting`), **not** xUnit. Many tests also use **AutoFixture**, **AutoFixture.AutoMoq**, and **Moq**. + +## Basic test class + +```csharp +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Contentstack.Management.Core.Unit.Tests.YourArea +{ + [TestClass] + public class YourFeatureTest + { + [TestInitialize] + public void Setup() + { + // Per-test setup + } + + [TestMethod] + public void YourScenario_DoesExpectedThing() + { + Assert.IsNotNull(result); + } + } +} +``` + +## AutoFixture + AutoMoq + +Common in HTTP and service tests ([`ContentstackHttpRequestTest.cs`](../../../Contentstack.Management.Core.Unit.Tests/Http/ContentstackHttpRequestTest.cs)): + +```csharp +using AutoFixture; +using AutoFixture.AutoMoq; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class YourFeatureTest +{ + private readonly IFixture _fixture = new Fixture() + .Customize(new AutoMoqCustomization()); + + [TestMethod] + public void Example() + { + var value = _fixture.Create(); + Assert.IsFalse(string.IsNullOrEmpty(value)); + } +} +``` + +## Pipeline / handler tests + +Pipeline tests often build **`ExecutionContext`**, **`RequestContext`**, **`ResponseContext`**, attach a **`RetryPolicy`**, and use test doubles from **`Mokes/`** (e.g. `MockHttpHandlerWithRetries`, `MockService`). See [`RetryHandlerTest.cs`](../../../Contentstack.Management.Core.Unit.Tests/Runtime/Pipeline/RetryHandler/RetryHandlerTest.cs). + +## Integration tests (separate project) + +Integration tests live in **`Contentstack.Management.Core.Tests`**, use **`[ClassInitialize]`**, **`[DoNotParallelize]`** in many classes, and **`Contentstack.CreateAuthenticatedClient()`** from [`Contentstack.cs`](../../../Contentstack.Management.Core.Tests/Contentstack.cs). Do **not** use this pattern in the unit test project for network I/O. + +## Commands + +- **CI parity (unit):** `sh ./Scripts/run-unit-test-case.sh` from repo root. +- **Single project:** `dotnet test Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj` + +See [`../SKILL.md`](../SKILL.md) for TRX, coverlet, and `appsettings.json` for integration runs.