From 7296757d884b77bc72b5190b6b543070e47f376b Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Fri, 26 Jun 2026 11:22:50 +0530 Subject: [PATCH 1/2] feat: add asset scanning tests for _asset_scan_status param and api_version header --- .../Contentstack013_AssetTest.cs | 372 ++++++++++++++++++ .../Models/AssetTest.cs | 103 +++++ 2 files changed, 475 insertions(+) diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs index 2616729..5d5c329 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs @@ -26,11 +26,19 @@ public class Contentstack006_AssetTest private static List _testAssetUIDs = new List(); private static List _testFolderUIDs = new List(); private static List _testTemporaryFiles = new List(); + private static string _scanTestPublishEnvUid; + private static readonly string[] ValidScanStatuses = { "pending", "clean", "quarantined", "not_scanned" }; [ClassInitialize] public static void ClassInitialize(TestContext context) { _client = Contentstack.CreateAuthenticatedClient(); + try + { + var stack = _client.Stack(StackResponse.getStack(_client.serializer).Stack.APIKey); + EnsureScanTestPublishEnvironment(stack); + } + catch { /* non-fatal — publish scan tests will skip gracefully if env is null */ } } [ClassCleanup] @@ -38,6 +46,15 @@ public static void ClassCleanup() { CleanupTestAssets(_testAssetUIDs); CleanupTemporaryFiles(); + if (!string.IsNullOrEmpty(_scanTestPublishEnvUid)) + { + try + { + var stack = _client.Stack(StackResponse.getStack(_client.serializer).Stack.APIKey); + stack.Environment(_scanTestPublishEnvUid).Delete(); + } + catch { } + } try { _client?.Logout(); } catch { } _client = null; } @@ -301,6 +318,26 @@ private static string CreateTemporaryBinaryFile(string fileName, byte[] content) /// /// Cleans up test assets to avoid polluting the stack /// + /// + /// Creates a shared environment used by asset scan publish tests (Test109, Test110). + /// Called once from ClassInitialize; result stored in _scanTestPublishEnvUid. + /// Mirrors the EnsureBulkTestEnvironment() pattern in Contentstack015_BulkOperationTest. + /// + private static void EnsureScanTestPublishEnvironment(Stack stack) + { + var model = new EnvironmentModel + { + Name = "asset_scan_test_env", + Urls = new List + { + new LocalesUrl { Url = "https://asset-scan-test.example.com", Locale = "en-us" } + } + }; + ContentstackResponse response = stack.Environment().Create(model); + if (response.IsSuccessStatusCode) + _scanTestPublishEnvUid = response.OpenJsonObjectResponse()["environment"]?["uid"]?.ToString(); + } + private static void CleanupTestAssets(List assetUIDs) { if (_client == null) return; @@ -4433,5 +4470,340 @@ public async Task Test105_Should_Update_Uploaded_Image_Asset() #endregion + #region Asset Scanning Tests + // These tests validate the _asset_scan_status query param and api_version header. + // Assets created here are intentionally NOT added to _testAssetUIDs so they remain + // visible in the Contentstack stack UI after the test run for manual verification. + // The shared publish environment (_scanTestPublishEnvUid) is created in ClassInitialize + // and deleted in ClassCleanup. + + // ── Happy Path ───────────────────────────────────────────────────────────────── + + /// + /// Happy path: GET /v3/assets?_asset_scan_status=true + /// Verifies the SDK sends the param and the API accepts it. + /// If the response contains assets, each _asset_scan_status value must be a valid enum. + /// Example (Python equiv): asset.add_param("_asset_scan_status", True); asset.find() + /// + [TestMethod] + [DoNotParallelize] + public async Task Test106_Should_Find_Assets_With_ScanStatus_Param() + { + TestOutputLogger.LogContext("TestScenario", "FindAssetsWithScanStatusParam"); + try + { + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + ContentstackResponse response = _stack.Asset().Query().Find(collection); + + AssertLogger.IsTrue(response.IsSuccessStatusCode, "FindAssets_ScanStatus_Success", "FindAssets_ScanStatus_Success"); + Console.WriteLine($"✅ Find assets with _asset_scan_status param: HTTP {(int)response.StatusCode}"); + + var responseObject = response.OpenJsonObjectResponse(); + var assets = responseObject["assets"]; + if (assets != null) + { + foreach (var asset in assets.AsArray()) + { + var scanStatus = asset?["_asset_scan_status"]?.ToString(); + if (scanStatus != null) + { + AssertLogger.IsTrue( + Array.Exists(ValidScanStatuses, s => s == scanStatus), + $"Expected valid scan status, got: {scanStatus}", + "FindAssets_ScanStatus_ValidEnum"); + } + } + Console.WriteLine($"✅ All _asset_scan_status values are valid enums"); + } + } + catch (Exception e) + { + AssertLogger.Fail("Find assets with scan status param failed", e.Message); + } + } + + /// + /// Happy path: GET /v3/assets/{uid}?_asset_scan_status=true + /// Creates an asset, fetches it with the scan param, validates the scan status field. + /// Asset is NOT cleaned up — remains in stack UI for verification. + /// Example (Python equiv): asset.add_param("_asset_scan_status", True); asset.fetch() + /// + [TestMethod] + [DoNotParallelize] + public async Task Test107_Should_Fetch_Asset_With_ScanStatus_Param() + { + TestOutputLogger.LogContext("TestScenario", "FetchAssetWithScanStatusParam"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); + try + { + // Step 1: Create asset + var asset = new AssetModel("scanFetchTest.json", path, "application/json", + title: "Scan Fetch Test", description: "scan status fetch test", parentUID: null, tags: "scan,fetch"); + ContentstackResponse createResponse = _stack.Asset().Create(asset); + AssertLogger.IsTrue(createResponse.IsSuccessStatusCode, "FetchScan_AssetCreated", "FetchScan_AssetCreated"); + var assetUID = createResponse.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); + AssertLogger.IsNotNull(assetUID, "FetchScan_AssetUID"); + Console.WriteLine($"✅ Asset created (not in cleanup list): uid={assetUID}"); + + // Step 2: Fetch with _asset_scan_status=true + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + ContentstackResponse fetchResponse = _stack.Asset(assetUID).Fetch(collection); + + AssertLogger.IsTrue(fetchResponse.IsSuccessStatusCode, "FetchScan_Success", "FetchScan_Success"); + Console.WriteLine($"✅ Fetch with _asset_scan_status param: HTTP {(int)fetchResponse.StatusCode}"); + + var scanStatus = fetchResponse.OpenJsonObjectResponse()["asset"]?["_asset_scan_status"]?.ToString(); + if (scanStatus != null) + { + AssertLogger.IsTrue( + Array.Exists(ValidScanStatuses, s => s == scanStatus), + $"Expected valid scan status, got: {scanStatus}", + "FetchScan_ValidEnum"); + Console.WriteLine($"✅ _asset_scan_status = {scanStatus}"); + } + } + catch (Exception e) + { + AssertLogger.Fail("Fetch asset with scan status param failed", e.Message); + } + } + + /// + /// Happy path: POST /v3/assets with ParameterCollection containing _asset_scan_status. + /// SDK must accept the param without throwing. Asset is NOT cleaned up. + /// Example (Python equiv): asset.add_param("_asset_scan_status", True); asset.upload(file) + /// + [TestMethod] + [DoNotParallelize] + public async Task Test108_Should_Upload_Asset_With_ScanStatus_Param() + { + TestOutputLogger.LogContext("TestScenario", "UploadAssetWithScanStatusParam"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); + try + { + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + var asset = new AssetModel("scanUploadTest.json", path, "application/json", + title: "Scan Upload Test", description: "scan status upload test", parentUID: null, tags: "scan,upload"); + ContentstackResponse response = _stack.Asset().Create(asset, collection); + + AssertLogger.IsTrue(response.IsSuccessStatusCode, "UploadScan_Created", "UploadScan_Created"); + var assetUID = response.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); + AssertLogger.IsNotNull(assetUID, "UploadScan_AssetUID"); + Console.WriteLine($"✅ Upload with _asset_scan_status param accepted by SDK: uid={assetUID}"); + } + catch (Exception e) + { + AssertLogger.Fail("Upload asset with scan status param failed", e.Message); + } + } + + /// + /// Happy path: POST /v3/assets/{uid}/publish with api_version: 3.2 header. + /// Uses shared environment created in ClassInitialize. + /// Example (Python equiv): asset.add_header("api_version", "3.2"); asset.publish(data) + /// + [TestMethod] + [DoNotParallelize] + public async Task Test109_Should_Publish_Asset_With_ApiVersion_Header() + { + TestOutputLogger.LogContext("TestScenario", "PublishAssetWithApiVersionHeader"); + if (string.IsNullOrEmpty(_scanTestPublishEnvUid)) + { + Console.WriteLine("⚠️ Skipping Test109 — shared publish environment was not created in ClassInitialize"); + return; + } + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); + try + { + // Step 1: Create asset (not in cleanup list — stays visible in UI) + var asset = new AssetModel("scanPublishApiVersionTest.json", path, "application/json", + title: "Scan Publish ApiVersion Test", description: "api version header test", parentUID: null, tags: "scan,publish,apiversion"); + ContentstackResponse createResponse = _stack.Asset().Create(asset); + AssertLogger.IsTrue(createResponse.IsSuccessStatusCode, "PublishApiVersion_AssetCreated", "PublishApiVersion_AssetCreated"); + var assetUID = createResponse.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); + AssertLogger.IsNotNull(assetUID, "PublishApiVersion_AssetUID"); + Console.WriteLine($"✅ Asset created: uid={assetUID}"); + + // Step 2: Publish with api_version: 3.2 to the shared environment + var publishDetails = new PublishUnpublishDetails + { + Locales = new List { "en-us" }, + Environments = new List { _scanTestPublishEnvUid }, + Version = 1 + }; + ContentstackResponse publishResponse = _stack.Asset(assetUID).Publish(publishDetails, "3.2"); + + AssertLogger.IsTrue(publishResponse.IsSuccessStatusCode, "PublishApiVersion_Success", "PublishApiVersion_Success"); + Console.WriteLine($"✅ Asset published with api_version: 3.2, uid={assetUID}"); + } + catch (Exception e) + { + AssertLogger.Fail("Publish asset with api_version header failed", e.Message); + } + } + + /// + /// Happy path: POST /v3/assets/{uid}/publish WITHOUT api_version header (default SDK behavior). + /// Verifies SDK works correctly when the optional header is omitted. + /// Example (Python equiv): asset.publish(data) — no add_header call + /// + [TestMethod] + [DoNotParallelize] + public async Task Test110_Should_Publish_Asset_Without_ApiVersion_Header() + { + TestOutputLogger.LogContext("TestScenario", "PublishAssetWithoutApiVersionHeader"); + if (string.IsNullOrEmpty(_scanTestPublishEnvUid)) + { + Console.WriteLine("⚠️ Skipping Test110 — shared publish environment was not created in ClassInitialize"); + return; + } + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); + try + { + // Step 1: Create asset (not in cleanup list — stays visible in UI) + var asset = new AssetModel("scanPublishNoApiVersionTest.json", path, "application/json", + title: "Scan Publish No ApiVersion Test", description: "no api version header test", parentUID: null, tags: "scan,publish,noapiversion"); + ContentstackResponse createResponse = _stack.Asset().Create(asset); + AssertLogger.IsTrue(createResponse.IsSuccessStatusCode, "PublishNoApiVersion_AssetCreated", "PublishNoApiVersion_AssetCreated"); + var assetUID = createResponse.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); + AssertLogger.IsNotNull(assetUID, "PublishNoApiVersion_AssetUID"); + Console.WriteLine($"✅ Asset created: uid={assetUID}"); + + // Step 2: Publish WITHOUT api_version header — omitting the optional param + var publishDetails = new PublishUnpublishDetails + { + Locales = new List { "en-us" }, + Environments = new List { _scanTestPublishEnvUid }, + Version = 1 + }; + ContentstackResponse publishResponse = _stack.Asset(assetUID).Publish(publishDetails); + + AssertLogger.IsTrue(publishResponse.IsSuccessStatusCode, "PublishNoApiVersion_Success", "PublishNoApiVersion_Success"); + Console.WriteLine($"✅ Asset published without api_version header, uid={assetUID}"); + } + catch (Exception e) + { + AssertLogger.Fail("Publish asset without api_version header failed", e.Message); + } + } + + // ── Negative Path ────────────────────────────────────────────────────────────── + + /// + /// Negative path: GET /v3/assets/{uid} WITHOUT _asset_scan_status param. + /// Verifies the field is absent from the response when param is not sent. + /// Example (Python equiv): asset.fetch() — no add_param call + /// + [TestMethod] + [DoNotParallelize] + public async Task Test111_Should_Fetch_Asset_Without_ScanStatus_Param_Field_Absent() + { + TestOutputLogger.LogContext("TestScenario", "FetchAssetWithoutScanStatusParamFieldAbsent"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); + try + { + // Step 1: Create asset (not in cleanup list — stays visible in UI) + var asset = new AssetModel("scanFetchNegativeTest.json", path, "application/json", + title: "Scan Fetch Negative Test", description: "no scan param test", parentUID: null, tags: "scan,negative"); + ContentstackResponse createResponse = _stack.Asset().Create(asset); + AssertLogger.IsTrue(createResponse.IsSuccessStatusCode, "FetchNoParam_AssetCreated", "FetchNoParam_AssetCreated"); + var assetUID = createResponse.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); + AssertLogger.IsNotNull(assetUID, "FetchNoParam_AssetUID"); + + // Step 2: Fetch WITHOUT _asset_scan_status param — field must be absent + ContentstackResponse fetchResponse = _stack.Asset(assetUID).Fetch(); + + AssertLogger.IsTrue(fetchResponse.IsSuccessStatusCode, "FetchNoParam_Success", "FetchNoParam_Success"); + var assetNode = fetchResponse.OpenJsonObjectResponse()["asset"]; + AssertLogger.IsTrue( + assetNode?["_asset_scan_status"] == null, + "_asset_scan_status must be absent when param is not sent", + "FetchNoParam_FieldAbsent"); + Console.WriteLine($"✅ _asset_scan_status correctly absent when param not sent, uid={assetUID}"); + } + catch (Exception e) + { + AssertLogger.Fail("Fetch asset without scan status param (field absent) failed", e.Message); + } + } + + /// + /// Negative path: GET /v3/assets WITHOUT _asset_scan_status param. + /// Verifies the field is absent from every asset in the list response. + /// Example (Python equiv): stack.assets().find() — no add_param call + /// + [TestMethod] + [DoNotParallelize] + public async Task Test112_Should_Find_Assets_Without_ScanStatus_Param_Field_Absent() + { + TestOutputLogger.LogContext("TestScenario", "FindAssetsWithoutScanStatusParamFieldAbsent"); + try + { + // No ParameterCollection — _asset_scan_status must not appear in any asset + ContentstackResponse response = _stack.Asset().Query().Find(); + + AssertLogger.IsTrue(response.IsSuccessStatusCode, "FindNoParam_Success", "FindNoParam_Success"); + + var assets = response.OpenJsonObjectResponse()["assets"]; + if (assets != null) + { + foreach (var asset in assets.AsArray()) + { + AssertLogger.IsTrue( + asset?["_asset_scan_status"] == null, + $"_asset_scan_status must be absent when param is not sent (uid={asset?["uid"]})", + "FindNoParam_FieldAbsent"); + } + Console.WriteLine($"✅ _asset_scan_status correctly absent in all assets when param not sent"); + } + } + catch (Exception e) + { + AssertLogger.Fail("Find assets without scan status param (field absent) failed", e.Message); + } + } + + /// + /// Negative path: POST /v3/assets WITHOUT ParameterCollection. + /// Verifies _asset_scan_status is absent from the create response when param is not sent. + /// Asset is NOT cleaned up — remains in stack UI for verification. + /// Example (Python equiv): stack.assets().upload(file) — no add_param call + /// + [TestMethod] + [DoNotParallelize] + public async Task Test113_Should_Upload_Asset_Without_ScanStatus_Param_Field_Absent() + { + TestOutputLogger.LogContext("TestScenario", "UploadAssetWithoutScanStatusParamFieldAbsent"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); + try + { + // No ParameterCollection — _asset_scan_status must not appear in response + var asset = new AssetModel("scanUploadNegativeTest.json", path, "application/json", + title: "Scan Upload Negative Test", description: "no scan param upload test", parentUID: null, tags: "scan,upload,negative"); + ContentstackResponse response = _stack.Asset().Create(asset); + + AssertLogger.IsTrue(response.IsSuccessStatusCode, "UploadNoParam_Created", "UploadNoParam_Created"); + var assetNode = response.OpenJsonObjectResponse()["asset"]; + AssertLogger.IsNotNull(assetNode, "UploadNoParam_AssetNode"); + AssertLogger.IsTrue( + assetNode["_asset_scan_status"] == null, + "_asset_scan_status must be absent in create response when param is not sent", + "UploadNoParam_FieldAbsent"); + + Console.WriteLine($"✅ _asset_scan_status correctly absent in upload response, uid={assetNode["uid"]}"); + } + catch (Exception e) + { + AssertLogger.Fail("Upload asset without scan status param (field absent) failed", e.Message); + } + } + + #endregion + } } diff --git a/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs index d7918a5..bbcbf5c 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs @@ -292,5 +292,108 @@ public async System.Threading.Tasks.Task Should_Update_Image_Asset_With_JPG_Asyn Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); } + + // ── Asset Scanning Tests ────────────────────────────────────────────────────── + // These tests verify that the SDK accepts _asset_scan_status param and api_version header + // without throwing. MockHttpHandler returns a fixed response for all requests so we only + // assert that the SDK wires up the call and returns the expected response object. + + [TestMethod] + public void Should_Fetch_Asset_With_ScanStatus_Param() + { + // Example: asset.add_param("_asset_scan_status", true) → asset.fetch() + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + ContentstackResponse response = _stack.Asset(_fixture.Create()).Fetch(collection); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public async System.Threading.Tasks.Task Should_Fetch_Asset_With_ScanStatus_Param_Async() + { + // Example: asset.add_param("_asset_scan_status", true) → await asset.fetch_async() + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + ContentstackResponse response = await _stack.Asset(_fixture.Create()).FetchAsync(collection); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public void Should_Create_Asset_With_ScanStatus_Param() + { + // Example: asset.add_param("_asset_scan_status", true) → asset.upload(file) + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + ContentstackResponse response = _stack.Asset().Create(_assetModel, collection); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public async System.Threading.Tasks.Task Should_Create_Asset_With_ScanStatus_Param_Async() + { + // Example: asset.add_param("_asset_scan_status", true) → await asset.upload_async(file) + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + ContentstackResponse response = await _stack.Asset().CreateAsync(_assetModel, collection); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public void Should_Update_Asset_With_ScanStatus_Param() + { + // Example: asset.add_param("_asset_scan_status", true) → asset.update(model) + var collection = new ParameterCollection(); + collection.Add("_asset_scan_status", true); + + ContentstackResponse response = _stack.Asset(_fixture.Create()).Update(_assetModel, collection); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public void Should_Publish_Asset_With_ApiVersion_Header() + { + // Example: asset.add_header("api_version", "3.2") → asset.publish(details) + ContentstackResponse response = _stack.Asset(_fixture.Create()) + .Publish(_fixture.Create(), "3.2"); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public async System.Threading.Tasks.Task Should_Publish_Asset_With_ApiVersion_Header_Async() + { + // Example: asset.add_header("api_version", "3.2") → await asset.publish_async(details) + ContentstackResponse response = await _stack.Asset(_fixture.Create()) + .PublishAsync(_fixture.Create(), "3.2"); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } + + [TestMethod] + public void Should_Publish_Asset_Without_ApiVersion_Header() + { + // Example: asset.publish(details) — no api_version header, default SDK behavior + ContentstackResponse response = _stack.Asset(_fixture.Create()) + .Publish(_fixture.Create()); + + Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToJsonString(), response.OpenJsonObjectResponse().ToJsonString()); + } } } From 938098cf227944bf3c81b2ce5319dec33c6af593 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Sat, 27 Jun 2026 09:19:41 +0530 Subject: [PATCH 2/2] fix: params namings --- .../Contentstack013_AssetTest.cs | 42 +++++++++---------- .../Models/AssetTest.cs | 22 +++++----- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs index 5d5c329..7e25ed7 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs @@ -4471,7 +4471,7 @@ public async Task Test105_Should_Update_Uploaded_Image_Asset() #endregion #region Asset Scanning Tests - // These tests validate the _asset_scan_status query param and api_version header. + // These tests validate the include_asset_scan_status query param and api_version header. // Assets created here are intentionally NOT added to _testAssetUIDs so they remain // visible in the Contentstack stack UI after the test run for manual verification. // The shared publish environment (_scanTestPublishEnvUid) is created in ClassInitialize @@ -4480,10 +4480,10 @@ public async Task Test105_Should_Update_Uploaded_Image_Asset() // ── Happy Path ───────────────────────────────────────────────────────────────── /// - /// Happy path: GET /v3/assets?_asset_scan_status=true + /// Happy path: GET /v3/assets?include_asset_scan_status=true /// Verifies the SDK sends the param and the API accepts it. - /// If the response contains assets, each _asset_scan_status value must be a valid enum. - /// Example (Python equiv): asset.add_param("_asset_scan_status", True); asset.find() + /// If the response contains assets, each include_asset_scan_status value must be a valid enum. + /// Example (Python equiv): asset.add_param("include_asset_scan_status", True); asset.find() /// [TestMethod] [DoNotParallelize] @@ -4493,12 +4493,12 @@ public async Task Test106_Should_Find_Assets_With_ScanStatus_Param() try { var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse response = _stack.Asset().Query().Find(collection); AssertLogger.IsTrue(response.IsSuccessStatusCode, "FindAssets_ScanStatus_Success", "FindAssets_ScanStatus_Success"); - Console.WriteLine($"✅ Find assets with _asset_scan_status param: HTTP {(int)response.StatusCode}"); + Console.WriteLine($"✅ Find assets with include_asset_scan_status param: HTTP {(int)response.StatusCode}"); var responseObject = response.OpenJsonObjectResponse(); var assets = responseObject["assets"]; @@ -4525,10 +4525,10 @@ public async Task Test106_Should_Find_Assets_With_ScanStatus_Param() } /// - /// Happy path: GET /v3/assets/{uid}?_asset_scan_status=true + /// Happy path: GET /v3/assets/{uid}?include_asset_scan_status=true /// Creates an asset, fetches it with the scan param, validates the scan status field. /// Asset is NOT cleaned up — remains in stack UI for verification. - /// Example (Python equiv): asset.add_param("_asset_scan_status", True); asset.fetch() + /// Example (Python equiv): asset.add_param("include_asset_scan_status", True); asset.fetch() /// [TestMethod] [DoNotParallelize] @@ -4547,13 +4547,13 @@ public async Task Test107_Should_Fetch_Asset_With_ScanStatus_Param() AssertLogger.IsNotNull(assetUID, "FetchScan_AssetUID"); Console.WriteLine($"✅ Asset created (not in cleanup list): uid={assetUID}"); - // Step 2: Fetch with _asset_scan_status=true + // Step 2: Fetch with include_asset_scan_status=true var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse fetchResponse = _stack.Asset(assetUID).Fetch(collection); AssertLogger.IsTrue(fetchResponse.IsSuccessStatusCode, "FetchScan_Success", "FetchScan_Success"); - Console.WriteLine($"✅ Fetch with _asset_scan_status param: HTTP {(int)fetchResponse.StatusCode}"); + Console.WriteLine($"✅ Fetch with include_asset_scan_status param: HTTP {(int)fetchResponse.StatusCode}"); var scanStatus = fetchResponse.OpenJsonObjectResponse()["asset"]?["_asset_scan_status"]?.ToString(); if (scanStatus != null) @@ -4572,9 +4572,9 @@ public async Task Test107_Should_Fetch_Asset_With_ScanStatus_Param() } /// - /// Happy path: POST /v3/assets with ParameterCollection containing _asset_scan_status. + /// Happy path: POST /v3/assets with ParameterCollection containing include_asset_scan_status. /// SDK must accept the param without throwing. Asset is NOT cleaned up. - /// Example (Python equiv): asset.add_param("_asset_scan_status", True); asset.upload(file) + /// Example (Python equiv): asset.add_param("include_asset_scan_status", True); asset.upload(file) /// [TestMethod] [DoNotParallelize] @@ -4585,7 +4585,7 @@ public async Task Test108_Should_Upload_Asset_With_ScanStatus_Param() try { var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); var asset = new AssetModel("scanUploadTest.json", path, "application/json", title: "Scan Upload Test", description: "scan status upload test", parentUID: null, tags: "scan,upload"); @@ -4594,7 +4594,7 @@ public async Task Test108_Should_Upload_Asset_With_ScanStatus_Param() AssertLogger.IsTrue(response.IsSuccessStatusCode, "UploadScan_Created", "UploadScan_Created"); var assetUID = response.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); AssertLogger.IsNotNull(assetUID, "UploadScan_AssetUID"); - Console.WriteLine($"✅ Upload with _asset_scan_status param accepted by SDK: uid={assetUID}"); + Console.WriteLine($"✅ Upload with include_asset_scan_status param accepted by SDK: uid={assetUID}"); } catch (Exception e) { @@ -4695,7 +4695,7 @@ public async Task Test110_Should_Publish_Asset_Without_ApiVersion_Header() // ── Negative Path ────────────────────────────────────────────────────────────── /// - /// Negative path: GET /v3/assets/{uid} WITHOUT _asset_scan_status param. + /// Negative path: GET /v3/assets/{uid} WITHOUT include_asset_scan_status param. /// Verifies the field is absent from the response when param is not sent. /// Example (Python equiv): asset.fetch() — no add_param call /// @@ -4715,7 +4715,7 @@ public async Task Test111_Should_Fetch_Asset_Without_ScanStatus_Param_Field_Abse var assetUID = createResponse.OpenJsonObjectResponse()["asset"]?["uid"]?.ToString(); AssertLogger.IsNotNull(assetUID, "FetchNoParam_AssetUID"); - // Step 2: Fetch WITHOUT _asset_scan_status param — field must be absent + // Step 2: Fetch WITHOUT include_asset_scan_status param — field must be absent ContentstackResponse fetchResponse = _stack.Asset(assetUID).Fetch(); AssertLogger.IsTrue(fetchResponse.IsSuccessStatusCode, "FetchNoParam_Success", "FetchNoParam_Success"); @@ -4733,7 +4733,7 @@ public async Task Test111_Should_Fetch_Asset_Without_ScanStatus_Param_Field_Abse } /// - /// Negative path: GET /v3/assets WITHOUT _asset_scan_status param. + /// Negative path: GET /v3/assets WITHOUT include_asset_scan_status param. /// Verifies the field is absent from every asset in the list response. /// Example (Python equiv): stack.assets().find() — no add_param call /// @@ -4744,7 +4744,7 @@ public async Task Test112_Should_Find_Assets_Without_ScanStatus_Param_Field_Abse TestOutputLogger.LogContext("TestScenario", "FindAssetsWithoutScanStatusParamFieldAbsent"); try { - // No ParameterCollection — _asset_scan_status must not appear in any asset + // No ParameterCollection — include_asset_scan_status must not appear in any asset ContentstackResponse response = _stack.Asset().Query().Find(); AssertLogger.IsTrue(response.IsSuccessStatusCode, "FindNoParam_Success", "FindNoParam_Success"); @@ -4770,7 +4770,7 @@ public async Task Test112_Should_Find_Assets_Without_ScanStatus_Param_Field_Abse /// /// Negative path: POST /v3/assets WITHOUT ParameterCollection. - /// Verifies _asset_scan_status is absent from the create response when param is not sent. + /// Verifies include_asset_scan_status is absent from the create response when param is not sent. /// Asset is NOT cleaned up — remains in stack UI for verification. /// Example (Python equiv): stack.assets().upload(file) — no add_param call /// @@ -4782,7 +4782,7 @@ public async Task Test113_Should_Upload_Asset_Without_ScanStatus_Param_Field_Abs var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/contentTypeSchema.json"); try { - // No ParameterCollection — _asset_scan_status must not appear in response + // No ParameterCollection — include_asset_scan_status must not appear in response var asset = new AssetModel("scanUploadNegativeTest.json", path, "application/json", title: "Scan Upload Negative Test", description: "no scan param upload test", parentUID: null, tags: "scan,upload,negative"); ContentstackResponse response = _stack.Asset().Create(asset); diff --git a/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs index bbcbf5c..c18a2d5 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/AssetTest.cs @@ -294,16 +294,16 @@ public async System.Threading.Tasks.Task Should_Update_Image_Asset_With_JPG_Asyn } // ── Asset Scanning Tests ────────────────────────────────────────────────────── - // These tests verify that the SDK accepts _asset_scan_status param and api_version header + // These tests verify that the SDK accepts include_asset_scan_status param and api_version header // without throwing. MockHttpHandler returns a fixed response for all requests so we only // assert that the SDK wires up the call and returns the expected response object. [TestMethod] public void Should_Fetch_Asset_With_ScanStatus_Param() { - // Example: asset.add_param("_asset_scan_status", true) → asset.fetch() + // Example: asset.add_param("include_asset_scan_status", true) → asset.fetch() var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse response = _stack.Asset(_fixture.Create()).Fetch(collection); @@ -314,9 +314,9 @@ public void Should_Fetch_Asset_With_ScanStatus_Param() [TestMethod] public async System.Threading.Tasks.Task Should_Fetch_Asset_With_ScanStatus_Param_Async() { - // Example: asset.add_param("_asset_scan_status", true) → await asset.fetch_async() + // Example: asset.add_param("include_asset_scan_status", true) → await asset.fetch_async() var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse response = await _stack.Asset(_fixture.Create()).FetchAsync(collection); @@ -327,9 +327,9 @@ public async System.Threading.Tasks.Task Should_Fetch_Asset_With_ScanStatus_Para [TestMethod] public void Should_Create_Asset_With_ScanStatus_Param() { - // Example: asset.add_param("_asset_scan_status", true) → asset.upload(file) + // Example: asset.add_param("include_asset_scan_status", true) → asset.upload(file) var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse response = _stack.Asset().Create(_assetModel, collection); @@ -340,9 +340,9 @@ public void Should_Create_Asset_With_ScanStatus_Param() [TestMethod] public async System.Threading.Tasks.Task Should_Create_Asset_With_ScanStatus_Param_Async() { - // Example: asset.add_param("_asset_scan_status", true) → await asset.upload_async(file) + // Example: asset.add_param("include_asset_scan_status", true) → await asset.upload_async(file) var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse response = await _stack.Asset().CreateAsync(_assetModel, collection); @@ -353,9 +353,9 @@ public async System.Threading.Tasks.Task Should_Create_Asset_With_ScanStatus_Par [TestMethod] public void Should_Update_Asset_With_ScanStatus_Param() { - // Example: asset.add_param("_asset_scan_status", true) → asset.update(model) + // Example: asset.add_param("include_asset_scan_status", true) → asset.update(model) var collection = new ParameterCollection(); - collection.Add("_asset_scan_status", true); + collection.Add("include_asset_scan_status", true); ContentstackResponse response = _stack.Asset(_fixture.Create()).Update(_assetModel, collection);