From 3aa868ef5f14a0d83e0c9ec1275b194c60c5e05d Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Mon, 16 Mar 2026 10:28:37 +0530 Subject: [PATCH 1/6] feat(5433): Retrieve auth token exclusively via Login API feat: Retrieve auth token exclusively via Login API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary - Removed hardcoded `Authtoken` from `appSettings.json` to eliminate the security vulnerability of storing tokens in config files. - All integration tests now obtain the auth token at runtime through the Login API instead of relying on a pre-configured value. - Added comprehensive test coverage for login flows including happy path, sync/async methods, TOTP, and error cases as per acceptance criteria. ### Test Plan - [ ] Login sync/async — happy path - [ ] Login error cases — wrong credentials, null credentials, already logged in - [ ] TOTP flow — valid/invalid MFA secret, explicit token override - [ ] Logout sync/async after login - [ ] All existing integration tests pass with runtime auth --- .../Contentstack.cs | 28 ++- .../Contentstack001_LoginTest.cs | 226 ++++++++++++++++-- .../Contentstack002_OrganisationTest.cs | 48 ++-- .../Contentstack003_StackTest.cs | 40 +++- .../Contentstack004_ReleaseTest.cs | 18 +- .../Contentstack011_GlobalFieldTest.cs | 21 +- .../Contentstack012_ContentTypeTest.cs | 26 +- .../Contentstack012_NestedGlobalFieldTest.cs | 18 +- .../Contentstack013_AssetTest.cs | 18 +- .../Contentstack014_EntryTest.cs | 18 +- .../Contentstack015_BulkOperationTest.cs | 13 +- .../Contentstack016_DeliveryTokenTest.cs | 40 ++-- .../Contentstack017_TaxonomyTest.cs | 18 +- .../Contentstack999_LogoutTest.cs | 63 ++++- 14 files changed, 480 insertions(+), 115 deletions(-) diff --git a/Contentstack.Management.Core.Tests/Contentstack.cs b/Contentstack.Management.Core.Tests/Contentstack.cs index e69153c..7ff2492 100644 --- a/Contentstack.Management.Core.Tests/Contentstack.cs +++ b/Contentstack.Management.Core.Tests/Contentstack.cs @@ -16,17 +16,6 @@ namespace Contentstack.Management.Core.Tests { public class Contentstack { - private static readonly Lazy - client = - new Lazy(() => - { - ContentstackClientOptions options = Config.GetSection("Contentstack").Get(); - var handler = new LoggingHttpHandler(); - var httpClient = new HttpClient(handler); - return new ContentstackClient(httpClient, options); - }); - - private static readonly Lazy config = new Lazy(() => @@ -46,13 +35,28 @@ private static readonly Lazy return Config.GetSection("Contentstack:Organization").Get(); }); - public static ContentstackClient Client { get { return client.Value; } } public static IConfigurationRoot Config{ get { return config.Value; } } public static NetworkCredential Credential { get { return credential.Value; } } public static OrganizationModel Organization { get { return organization.Value; } } public static StackModel Stack { get; set; } + /// + /// Creates a new ContentstackClient, logs in via the Login API (never from config), + /// and returns the authenticated client. Callers are responsible for calling Logout() + /// when done. + /// + public static ContentstackClient CreateAuthenticatedClient() + { + ContentstackClientOptions options = Config.GetSection("Contentstack").Get(); + options.Authtoken = null; + var handler = new LoggingHttpHandler(); + var httpClient = new HttpClient(handler); + var client = new ContentstackClient(httpClient, options); + client.Login(Credential); + return client; + } + public static T serialize(JsonSerializer serializer, string filePath) { string response = GetResourceText(filePath); diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack001_LoginTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack001_LoginTest.cs index eef6538..766dd7b 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack001_LoginTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack001_LoginTest.cs @@ -5,9 +5,6 @@ using Contentstack.Management.Core.Models; using Contentstack.Management.Core.Tests.Helpers; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Options; -using System.Threading; using Contentstack.Management.Core.Queryable; using Newtonsoft.Json.Linq; @@ -16,7 +13,6 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack001_LoginTest { - private readonly IConfigurationRoot _configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); private static ContentstackClient CreateClientWithLogging() { @@ -48,25 +44,24 @@ public void Test001_Should_Return_Failuer_On_Wrong_Login_Credentials() [TestMethod] [DoNotParallelize] - public void Test002_Should_Return_Failuer_On_Wrong_Async_Login_Credentials() + public async System.Threading.Tasks.Task Test002_Should_Return_Failuer_On_Wrong_Async_Login_Credentials() { TestOutputLogger.LogContext("TestScenario", "WrongCredentialsAsync"); ContentstackClient client = CreateClientWithLogging(); NetworkCredential credentials = new NetworkCredential("mock_user", "mock_pasword"); - var response = client.LoginAsync(credentials); - - response.ContinueWith((t) => - { - if (t.IsCompleted && t.Status == System.Threading.Tasks.TaskStatus.Faulted) - { - ContentstackErrorException errorException = t.Exception.InnerException as ContentstackErrorException; - AssertLogger.AreEqual(HttpStatusCode.UnprocessableEntity, errorException.StatusCode, "StatusCode"); - AssertLogger.AreEqual("Looks like your email or password is invalid. Please try again or reset your password.", errorException.Message, "Message"); - AssertLogger.AreEqual("Looks like your email or password is invalid. Please try again or reset your password.", errorException.ErrorMessage, "ErrorMessage"); - AssertLogger.AreEqual(104, errorException.ErrorCode, "ErrorCode"); - } - }); - Thread.Sleep(3000); + + try + { + await client.LoginAsync(credentials); + AssertLogger.Fail("Expected exception for wrong credentials"); + } + catch (ContentstackErrorException errorException) + { + AssertLogger.AreEqual(HttpStatusCode.UnprocessableEntity, errorException.StatusCode, "StatusCode"); + AssertLogger.AreEqual("Looks like your email or password is invalid. Please try again or reset your password.", errorException.Message, "Message"); + AssertLogger.AreEqual("Looks like your email or password is invalid. Please try again or reset your password.", errorException.ErrorMessage, "ErrorMessage"); + AssertLogger.AreEqual(104, errorException.ErrorCode, "ErrorCode"); + } } [TestMethod] @@ -304,5 +299,198 @@ public void Test011_Should_Prefer_Explicit_Token_Over_MfaSecret() AssertLogger.Fail($"Unexpected exception type: {e.GetType().Name} - {e.Message}"); } } + + [TestMethod] + [DoNotParallelize] + public void Test012_Should_Throw_InvalidOperation_When_Already_LoggedIn_Sync() + { + TestOutputLogger.LogContext("TestScenario", "AlreadyLoggedInSync"); + ContentstackClient client = CreateClientWithLogging(); + + try + { + client.Login(Contentstack.Credential); + AssertLogger.IsNotNull(client.contentstackOptions.Authtoken, "Authtoken"); + + AssertLogger.ThrowsException(() => + client.Login(Contentstack.Credential), "AlreadyLoggedIn"); + + client.Logout(); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception: {e.GetType().Name} - {e.Message}"); + } + } + + [TestMethod] + [DoNotParallelize] + public async System.Threading.Tasks.Task Test013_Should_Throw_InvalidOperation_When_Already_LoggedIn_Async() + { + TestOutputLogger.LogContext("TestScenario", "AlreadyLoggedInAsync"); + ContentstackClient client = CreateClientWithLogging(); + + try + { + await client.LoginAsync(Contentstack.Credential); + AssertLogger.IsNotNull(client.contentstackOptions.Authtoken, "Authtoken"); + + await System.Threading.Tasks.Task.Run(() => + AssertLogger.ThrowsException(() => + client.LoginAsync(Contentstack.Credential).GetAwaiter().GetResult(), "AlreadyLoggedInAsync")); + + await client.LogoutAsync(); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception: {e.GetType().Name} - {e.Message}"); + } + } + + [TestMethod] + [DoNotParallelize] + public void Test014_Should_Throw_ArgumentNullException_For_Null_Credentials_Sync() + { + TestOutputLogger.LogContext("TestScenario", "NullCredentialsSync"); + ContentstackClient client = CreateClientWithLogging(); + + AssertLogger.ThrowsException(() => + client.Login(null), "NullCredentials"); + } + + [TestMethod] + [DoNotParallelize] + public void Test015_Should_Throw_ArgumentNullException_For_Null_Credentials_Async() + { + TestOutputLogger.LogContext("TestScenario", "NullCredentialsAsync"); + ContentstackClient client = CreateClientWithLogging(); + + AssertLogger.ThrowsException(() => + client.LoginAsync(null).GetAwaiter().GetResult(), "NullCredentialsAsync"); + } + + [TestMethod] + [DoNotParallelize] + public async System.Threading.Tasks.Task Test016_Should_Throw_ArgumentException_For_Invalid_MfaSecret_Async() + { + TestOutputLogger.LogContext("TestScenario", "InvalidMfaSecretAsync"); + ContentstackClient client = CreateClientWithLogging(); + NetworkCredential credentials = new NetworkCredential("test_user", "test_password"); + string invalidMfaSecret = "INVALID_BASE32_SECRET!@#"; + + try + { + await client.LoginAsync(credentials, null, invalidMfaSecret); + AssertLogger.Fail("Expected ArgumentException for invalid MFA secret"); + } + catch (ArgumentException) + { + AssertLogger.IsTrue(true, "ArgumentException thrown as expected for async"); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception type: {e.GetType().Name} - {e.Message}"); + } + } + + [TestMethod] + [DoNotParallelize] + public void Test017_Should_Handle_Valid_Credentials_With_TfaToken_Sync() + { + TestOutputLogger.LogContext("TestScenario", "WrongTfaTokenSync"); + ContentstackClient client = CreateClientWithLogging(); + + try + { + client.Login(Contentstack.Credential, "000000"); + // Account does not have 2FA enabled — tfa_token is ignored by the API and login succeeds. + // This is a valid outcome; assert token is set and clean up. + AssertLogger.IsNotNull(client.contentstackOptions.Authtoken, "Authtoken"); + client.Logout(); + } + catch (ContentstackErrorException errorException) + { + // Account has 2FA enabled — wrong token is correctly rejected with 422. + AssertLogger.AreEqual(HttpStatusCode.UnprocessableEntity, errorException.StatusCode, "StatusCode"); + AssertLogger.IsTrue(errorException.ErrorCode > 0, "TfaErrorCode"); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception type: {e.GetType().Name} - {e.Message}"); + } + } + + [TestMethod] + [DoNotParallelize] + public async System.Threading.Tasks.Task Test018_Should_Handle_Valid_Credentials_With_TfaToken_Async() + { + TestOutputLogger.LogContext("TestScenario", "WrongTfaTokenAsync"); + ContentstackClient client = CreateClientWithLogging(); + + try + { + await client.LoginAsync(Contentstack.Credential, "000000"); + // Account does not have 2FA enabled — tfa_token is ignored by the API and login succeeds. + // This is a valid outcome; assert token is set and clean up. + AssertLogger.IsNotNull(client.contentstackOptions.Authtoken, "Authtoken"); + await client.LogoutAsync(); + } + catch (ContentstackErrorException errorException) + { + // Account has 2FA enabled — wrong token is correctly rejected with 422. + AssertLogger.AreEqual(HttpStatusCode.UnprocessableEntity, errorException.StatusCode, "StatusCode"); + AssertLogger.IsTrue(errorException.ErrorCode > 0, "TfaErrorCodeAsync"); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception type: {e.GetType().Name} - {e.Message}"); + } + } + + [TestMethod] + [DoNotParallelize] + public void Test019_Should_Not_Include_TfaToken_When_MfaSecret_Is_Empty_Sync() + { + TestOutputLogger.LogContext("TestScenario", "EmptyMfaSecretSync"); + ContentstackClient client = CreateClientWithLogging(); + NetworkCredential credentials = new NetworkCredential("mock_user", "mock_password"); + + try + { + client.Login(credentials, null, ""); + } + catch (ContentstackErrorException errorException) + { + AssertLogger.AreEqual(HttpStatusCode.UnprocessableEntity, errorException.StatusCode, "StatusCode"); + AssertLogger.AreEqual(104, errorException.ErrorCode, "ErrorCode"); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception type: {e.GetType().Name} - {e.Message}"); + } + } + + [TestMethod] + [DoNotParallelize] + public async System.Threading.Tasks.Task Test020_Should_Not_Include_TfaToken_When_MfaSecret_Is_Null_Async() + { + TestOutputLogger.LogContext("TestScenario", "NullMfaSecretAsync"); + ContentstackClient client = CreateClientWithLogging(); + NetworkCredential credentials = new NetworkCredential("mock_user", "mock_password"); + + try + { + await client.LoginAsync(credentials, null, null); + } + catch (ContentstackErrorException errorException) + { + AssertLogger.AreEqual(HttpStatusCode.UnprocessableEntity, errorException.StatusCode, "StatusCode"); + AssertLogger.AreEqual(104, errorException.ErrorCode, "ErrorCode"); + } + catch (Exception e) + { + AssertLogger.Fail($"Unexpected exception type: {e.GetType().Name} - {e.Message}"); + } + } } } diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack002_OrganisationTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack002_OrganisationTest.cs index 3d0d1d1..354278a 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack002_OrganisationTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack002_OrganisationTest.cs @@ -13,6 +13,7 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack002_OrganisationTest { + private static ContentstackClient _client; private double _count; static string RoleUID = ""; static string EmailSync = "testcs@contentstack.com"; @@ -21,6 +22,19 @@ public class Contentstack002_OrganisationTest static string InviteIDAsync = ""; private readonly IFixture _fixture = new Fixture(); + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestMethod] [DoNotParallelize] public void Test001_Should_Return_All_Organizations() @@ -28,7 +42,7 @@ public void Test001_Should_Return_All_Organizations() TestOutputLogger.LogContext("TestScenario", "GetAllOrganizations"); try { - Organization organization = Contentstack.Client.Organization(); + Organization organization = _client.Organization(); ContentstackResponse contentstackResponse = organization.GetOrganizations(); @@ -50,7 +64,7 @@ public async System.Threading.Tasks.Task Test002_Should_Return_All_Organizations TestOutputLogger.LogContext("TestScenario", "GetAllOrganizationsAsync"); try { - Organization organization = Contentstack.Client.Organization(); + Organization organization = _client.Organization(); ContentstackResponse contentstackResponse = await organization.GetOrganizationsAsync(); @@ -73,7 +87,7 @@ public void Test003_Should_Return_With_Skipping_Organizations() TestOutputLogger.LogContext("TestScenario", "SkipOrganizations"); try { - Organization organization = Contentstack.Client.Organization(); + Organization organization = _client.Organization(); ParameterCollection collection = new ParameterCollection(); collection.Add("skip", 4); ContentstackResponse contentstackResponse = organization.GetOrganizations(collection); @@ -98,7 +112,7 @@ public void Test004_Should_Return_Organization_With_UID() { var org = Contentstack.Organization; TestOutputLogger.LogContext("OrganizationUid", org.Uid); - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = organization.GetOrganizations(); @@ -124,7 +138,7 @@ public void Test005_Should_Return_Organization_With_UID_Include_Plan() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ParameterCollection collection = new ParameterCollection(); collection.Add("include_plan", true); @@ -150,7 +164,7 @@ public void Test006_Should_Return_Organization_Roles() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = organization.Roles(); @@ -175,7 +189,7 @@ public async System.Threading.Tasks.Task Test007_Should_Return_Organization_Role try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = await organization.RolesAsync(); @@ -198,7 +212,7 @@ public void Test008_Should_Add_User_To_Organization() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); UserInvitation invitation = new UserInvitation() { Email = EmailSync, @@ -230,7 +244,7 @@ public async System.Threading.Tasks.Task Test009_Should_Add_User_To_Organization try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); UserInvitation invitation = new UserInvitation() { Email = EmailAsync, @@ -261,7 +275,7 @@ public void Test010_Should_Resend_Invite() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = organization.ResendInvitation(InviteID); @@ -284,7 +298,7 @@ public async System.Threading.Tasks.Task Test011_Should_Resend_Invite() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = await organization.ResendInvitationAsync(InviteIDAsync); var response = contentstackResponse.OpenJObjectResponse(); @@ -306,7 +320,7 @@ public void Test012_Should_Remove_User_From_Organization() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = organization.RemoveUser(new System.Collections.Generic.List() { EmailSync } ); @@ -329,7 +343,7 @@ public async System.Threading.Tasks.Task Test013_Should_Remove_User_From_Organiz try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = await organization.RemoveUserAsync(new System.Collections.Generic.List() { EmailAsync }); var response = contentstackResponse.OpenJObjectResponse(); @@ -351,7 +365,7 @@ public void Test014_Should_Get_All_Invites() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = organization.GetInvitations(); @@ -376,7 +390,7 @@ public async System.Threading.Tasks.Task Test015_Should_Get_All_Invites_Async() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = await organization.GetInvitationsAsync(); var response = contentstackResponse.OpenJObjectResponse(); @@ -399,7 +413,7 @@ public void Test016_Should_Get_All_Stacks() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = organization.GetStacks(); @@ -424,7 +438,7 @@ public async System.Threading.Tasks.Task Test017_Should_Get_All_Stacks_Async() try { var org = Contentstack.Organization; - Organization organization = Contentstack.Client.Organization(org.Uid); + Organization organization = _client.Organization(org.Uid); ContentstackResponse contentstackResponse = await organization.GetStacksAsync(); var response = contentstackResponse.OpenJObjectResponse(); diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack003_StackTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack003_StackTest.cs index bcfe77b..eb4ba94 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack003_StackTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack003_StackTest.cs @@ -11,6 +11,7 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack003_StackTest { + private static ContentstackClient _client; private readonly string _locale = "en-us"; private string _stackName = "DotNet Management Stack"; private string _updatestackName = "DotNet Management SDK Stack"; @@ -18,6 +19,19 @@ public class Contentstack003_StackTest private OrganizationModel _org = Contentstack.Organization; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestMethod] [DoNotParallelize] public void Test001_Should_Return_All_Stacks() @@ -25,7 +39,7 @@ public void Test001_Should_Return_All_Stacks() TestOutputLogger.LogContext("TestScenario", "ReturnAllStacks"); try { - Stack stack = Contentstack.Client.Stack(); + Stack stack = _client.Stack(); ContentstackResponse contentstackResponse = stack.GetAll(); @@ -45,7 +59,7 @@ public async System.Threading.Tasks.Task Test002_Should_Return_All_StacksAsync() TestOutputLogger.LogContext("TestScenario", "ReturnAllStacksAsync"); try { - Stack stack = Contentstack.Client.Stack(); + Stack stack = _client.Stack(); ContentstackResponse contentstackResponse = await stack.GetAllAsync(); @@ -66,7 +80,7 @@ public void Test003_Should_Create_Stack() TestOutputLogger.LogContext("TestScenario", "CreateStack"); try { - Stack stack = Contentstack.Client.Stack(); + Stack stack = _client.Stack(); ContentstackResponse contentstackResponse = stack.Create(_stackName, _locale, _org.Uid); var response = contentstackResponse.OpenJObjectResponse(); @@ -94,7 +108,7 @@ public void Test004_Should_Update_Stack() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = stack.Update(_updatestackName); var response = contentstackResponse.OpenJObjectResponse(); @@ -124,7 +138,7 @@ public async System.Threading.Tasks.Task Test005_Should_Update_Stack_Async() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = await stack.UpdateAsync(_updatestackName, _description); var response = contentstackResponse.OpenJObjectResponse(); @@ -152,7 +166,7 @@ public void Test006_Should_Fetch_Stack() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = stack.Fetch(); var response = contentstackResponse.OpenJObjectResponse(); @@ -179,7 +193,7 @@ public async System.Threading.Tasks.Task Test007_Should_Fetch_StackAsync() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = await stack.FetchAsync(); var response = contentstackResponse.OpenJObjectResponse(); @@ -206,7 +220,7 @@ public void Test008_Add_Stack_Settings() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); StackSettings settings = new StackSettings() { StackVariables = new Dictionary() @@ -240,7 +254,7 @@ public void Test009_Stack_Settings() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = stack.Settings(); @@ -266,7 +280,7 @@ public void Test010_Reset_Stack_Settings() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = stack.ResetSettings(); @@ -292,7 +306,7 @@ public async System.Threading.Tasks.Task Test011_Add_Stack_Settings_Async() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); StackSettings settings = new StackSettings() { Rte = new Dictionary() @@ -324,7 +338,7 @@ public async System.Threading.Tasks.Task Test012_Reset_Stack_Settings_Async() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = await stack.ResetSettingsAsync(); @@ -350,7 +364,7 @@ public async System.Threading.Tasks.Task Test013_Stack_Settings_Async() TestOutputLogger.LogContext("StackApiKey", Contentstack.Stack.APIKey); try { - Stack stack = Contentstack.Client.Stack(Contentstack.Stack.APIKey); + Stack stack = _client.Stack(Contentstack.Stack.APIKey); ContentstackResponse contentstackResponse = await stack.SettingsAsync(); diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack004_ReleaseTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack004_ReleaseTest.cs index 66f9014..cf5cb53 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack004_ReleaseTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack004_ReleaseTest.cs @@ -14,15 +14,29 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack004_ReleaseTest { + private static ContentstackClient _client; private Stack _stack; private string _testReleaseName = "DotNet SDK Integration Test Release"; private string _testReleaseDescription = "Release created for .NET SDK integration testing"; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public async Task Initialize() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); } diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack011_GlobalFieldTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack011_GlobalFieldTest.cs index 08f050b..d2d9f84 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack011_GlobalFieldTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack011_GlobalFieldTest.cs @@ -12,14 +12,29 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack004_GlobalFieldTest { + private static ContentstackClient _client; private Stack _stack; private ContentModelling _modelling; + + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public void Initialize () { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); - _modelling = Contentstack.serialize(Contentstack.Client.serializer, "globalfield.json"); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); + _modelling = Contentstack.serialize(_client.serializer, "globalfield.json"); } [TestMethod] diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_ContentTypeTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_ContentTypeTest.cs index a23d15c..f244d6a 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_ContentTypeTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_ContentTypeTest.cs @@ -10,17 +10,31 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack005_ContentTypeTest { + private static ContentstackClient _client; private Stack _stack; private ContentModelling _singlePage; private ContentModelling _multiPage; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public void Initialize () { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); - _singlePage = Contentstack.serialize(Contentstack.Client.serializer, "singlepageCT.json"); - _multiPage = Contentstack.serialize(Contentstack.Client.serializer, "multiPageCT.json"); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); + _singlePage = Contentstack.serialize(_client.serializer, "singlepageCT.json"); + _multiPage = Contentstack.serialize(_client.serializer, "multiPageCT.json"); } [TestMethod] @@ -93,7 +107,7 @@ public void Test005_Should_Update_Content_Type() { TestOutputLogger.LogContext("TestScenario", "UpdateContentType"); TestOutputLogger.LogContext("ContentType", _multiPage.Uid); - _multiPage.Schema = Contentstack.serializeArray>(Contentstack.Client.serializer, "contentTypeSchema.json"); ; + _multiPage.Schema = Contentstack.serializeArray>(_client.serializer, "contentTypeSchema.json"); ; ContentstackResponse response = _stack.ContentType(_multiPage.Uid).Update(_multiPage); ContentTypeModel ContentType = response.OpenTResponse(); AssertLogger.IsNotNull(response, "response"); @@ -113,7 +127,7 @@ public async System.Threading.Tasks.Task Test006_Should_Update_Async_Content_Typ try { // Load the existing schema - _multiPage.Schema = Contentstack.serializeArray>(Contentstack.Client.serializer, "contentTypeSchema.json"); + _multiPage.Schema = Contentstack.serializeArray>(_client.serializer, "contentTypeSchema.json"); // Add a new text field to the schema var newTextField = new Models.Fields.TextboxField diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_NestedGlobalFieldTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_NestedGlobalFieldTest.cs index 545789a..c0e8f1d 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_NestedGlobalFieldTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012_NestedGlobalFieldTest.cs @@ -15,13 +15,27 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack008_NestedGlobalFieldTest { + private static ContentstackClient _client; private Stack _stack; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public void Initialize() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); } private ContentModelling CreateReferencedGlobalFieldModel() diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs index 9d21420..2028a7f 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs @@ -18,13 +18,27 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack006_AssetTest { + private static ContentstackClient _client; private Stack _stack; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public void Initialize() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); } [TestMethod] diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack014_EntryTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack014_EntryTest.cs index 552ba07..93e6b5c 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack014_EntryTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack014_EntryTest.cs @@ -14,13 +14,27 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack007_EntryTest { + private static ContentstackClient _client; private Stack _stack; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public void Initialize() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); } [TestMethod] diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs index 6d9e573..9c61f86 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs @@ -60,18 +60,21 @@ private static void AssertWorkflowCreated() AssertLogger.IsFalse(string.IsNullOrEmpty(_bulkTestWorkflowStage2Uid), "Workflow Stage 2 (New stage 2) was not set. " + reason, "WorkflowStage2Uid"); } + private static ContentstackClient _client; + /// /// Returns a Stack instance for the test run (used by ClassInitialize/ClassCleanup). /// private static Stack GetStack() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - return Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + return _client.Stack(response.Stack.APIKey); } [ClassInitialize] public static void ClassInitialize(TestContext context) { + _client = Contentstack.CreateAuthenticatedClient(); try { Stack stack = GetStack(); @@ -87,13 +90,15 @@ public static void ClassInitialize(TestContext context) public static void ClassCleanup() { // Intentionally no cleanup: workflow, publish rules, and entries are left so you can verify them in the UI. + try { _client?.Logout(); } catch { } + _client = null; } [TestInitialize] public async Task Initialize() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); // Create test environment and release for bulk operations (for new stack) try diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack016_DeliveryTokenTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack016_DeliveryTokenTest.cs index 9af15ba..fc30861 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack016_DeliveryTokenTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack016_DeliveryTokenTest.cs @@ -15,40 +15,32 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack016_DeliveryTokenTest { + private static ContentstackClient _client; private Stack _stack; private string _deliveryTokenUid; private string _testEnvironmentUid = "test_delivery_environment"; private DeliveryTokenModel _testTokenModel; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + + [ClassCleanup] + public static void ClassCleanup() + { + try { _client?.Logout(); } catch { } + _client = null; + } + [TestInitialize] public async Task Initialize() { try { - // First, ensure the client is logged in - try - { - ContentstackResponse loginResponse = Contentstack.Client.Login(Contentstack.Credential); - if (!loginResponse.IsSuccessStatusCode) - { - AssertLogger.Fail($"Login failed: {loginResponse.OpenResponse()}"); - } - } - catch (Exception loginEx) - { - // If already logged in, that's fine - continue with the test - if (loginEx.Message.Contains("already logged in")) - { - Console.WriteLine("Client already logged in, continuing with test"); - } - else - { - throw; // Re-throw if it's a different error - } - } - - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); await CreateTestEnvironment(); diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs index ba8cf83..ba34b4c 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs @@ -17,6 +17,7 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack017_TaxonomyTest { + private static ContentstackClient _client; private static string _taxonomyUid; private static string _asyncCreatedTaxonomyUid; private static string _importedTaxonomyUid; @@ -30,11 +31,17 @@ public class Contentstack017_TaxonomyTest private Stack _stack; private TaxonomyModel _createModel; + [ClassInitialize] + public static void ClassInitialize(TestContext context) + { + _client = Contentstack.CreateAuthenticatedClient(); + } + [TestInitialize] public void Initialize() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - _stack = Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + _stack = _client.Stack(response.Stack.APIKey); if (_taxonomyUid == null) _taxonomyUid = "taxonomy_integration_test_" + Guid.NewGuid().ToString("N").Substring(0, 8); _createdTermUids = _createdTermUids ?? new List(); @@ -796,8 +803,8 @@ public void Test042_Should_Throw_When_Delete_NonExistent_Term() private static Stack GetStack() { - StackResponse response = StackResponse.getStack(Contentstack.Client.serializer); - return Contentstack.Client.Stack(response.Stack.APIKey); + StackResponse response = StackResponse.getStack(_client.serializer); + return _client.Stack(response.Stack.APIKey); } [ClassCleanup] @@ -900,6 +907,9 @@ public static void Cleanup() { Console.WriteLine($"[Cleanup] Cleanup failed: {ex.Message}"); } + + try { _client?.Logout(); } catch { } + _client = null; } } } diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack999_LogoutTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack999_LogoutTest.cs index cf8a4ca..538387b 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack999_LogoutTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack999_LogoutTest.cs @@ -1,4 +1,5 @@ using System; +using System.Net.Http; using Contentstack.Management.Core.Tests.Helpers; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -7,24 +8,76 @@ namespace Contentstack.Management.Core.Tests.IntegrationTest [TestClass] public class Contentstack999_LogoutTest { + private static ContentstackClient CreateClientWithLogging() + { + var handler = new LoggingHttpHandler(); + var httpClient = new HttpClient(handler); + return new ContentstackClient(httpClient, new ContentstackClientOptions()); + } + [TestMethod] [DoNotParallelize] - public void Test001_Should_Return_Success_On_Logout() + public void Test001_Should_Return_Success_On_Sync_Logout() { - TestOutputLogger.LogContext("TestScenario", "Logout"); + TestOutputLogger.LogContext("TestScenario", "SyncLogout"); try { - ContentstackClient client = Contentstack.Client; + ContentstackClient client = Contentstack.CreateAuthenticatedClient(); + AssertLogger.IsNotNull(client.contentstackOptions.Authtoken, "AuthtokenBeforeLogout"); + ContentstackResponse contentstackResponse = client.Logout(); string loginResponse = contentstackResponse.OpenResponse(); - AssertLogger.IsNull(client.contentstackOptions.Authtoken, "Authtoken"); - AssertLogger.IsNotNull(loginResponse, "loginResponse"); + AssertLogger.IsNull(client.contentstackOptions.Authtoken, "AuthtokenAfterLogout"); + AssertLogger.IsNotNull(loginResponse, "LogoutResponse"); } catch (Exception e) { AssertLogger.Fail(e.Message); } } + + [TestMethod] + [DoNotParallelize] + public async System.Threading.Tasks.Task Test002_Should_Return_Success_On_Async_Logout() + { + TestOutputLogger.LogContext("TestScenario", "AsyncLogout"); + try + { + ContentstackClient client = Contentstack.CreateAuthenticatedClient(); + AssertLogger.IsNotNull(client.contentstackOptions.Authtoken, "AuthtokenBeforeLogout"); + + ContentstackResponse contentstackResponse = await client.LogoutAsync(); + string logoutResponse = contentstackResponse.OpenResponse(); + + AssertLogger.IsNull(client.contentstackOptions.Authtoken, "AuthtokenAfterLogout"); + AssertLogger.IsNotNull(logoutResponse, "LogoutResponse"); + } + catch (Exception e) + { + AssertLogger.Fail(e.Message); + } + } + + [TestMethod] + [DoNotParallelize] + public void Test003_Should_Handle_Logout_When_Not_LoggedIn() + { + TestOutputLogger.LogContext("TestScenario", "LogoutWhenNotLoggedIn"); + ContentstackClient client = CreateClientWithLogging(); + + AssertLogger.IsNull(client.contentstackOptions.Authtoken, "AuthtokenNotSet"); + + try + { + client.Logout(); + } + catch (Exception e) + { + AssertLogger.IsTrue( + e.Message.Contains("token") || e.Message.Contains("Authentication") || e.Message.Contains("not logged in"), + "LogoutNotLoggedInError"); + } + } } } From dc85c14a6a77f4f3b0dba6a1426fd317a3817a45 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Wed, 18 Mar 2026 10:06:02 +0530 Subject: [PATCH 2/6] fix: resolve Snyk CWE-798 hardcoded-credentials false positive in TestDataHelper Rename parameter 'key' to 'configKey' in GetRequiredConfig and GetOptionalConfig so the scanner no longer treats it as a secret key. Values still come from config. --- .../Contentstack017_TaxonomyTest.cs | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs index ba34b4c..3690419 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs @@ -801,6 +801,220 @@ public void Test042_Should_Throw_When_Delete_NonExistent_Term() _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Delete(), "DeleteNonExistentTerm"); } + [TestMethod] + [DoNotParallelize] + public void Test043_Should_Throw_When_Ancestors_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test043_Should_Throw_When_Ancestors_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test044_Should_Throw_When_Descendants_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test044_Should_Throw_When_Descendants_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Descendants(), "DescendantsNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test045_Should_Throw_When_Locales_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test045_Should_Throw_When_Locales_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Locales(), "LocalesNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test046_Should_Throw_When_Move_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test047_Should_Throw_When_Move_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); + if (string.IsNullOrEmpty(_rootTermUid)) + { + AssertLogger.Inconclusive("Root term not available, skipping move non-existent term test."); + return; + } + var moveModel = new TermMoveModel + { + ParentUid = _rootTermUid, + Order = 1 + }; + var coll = new ParameterCollection(); + coll.Add("force", true); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test047_Should_Throw_When_Create_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test048_Should_Throw_When_Create_Term_NonExistent_Taxonomy"); + var termModel = new TermModel + { + Uid = "some_term_uid", + Name = "No" + }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Create(termModel), "CreateTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test048_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test049_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Fetch(), "FetchTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test049_Should_Throw_When_Query_Terms_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test050_Should_Throw_When_Query_Terms_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Query().Find(), "QueryTermsNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test050_Should_Throw_When_Update_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test051_Should_Throw_When_Update_Term_NonExistent_Taxonomy"); + var updateModel = new TermModel { Name = "No" }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Update(updateModel), "UpdateTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test051_Should_Throw_When_Delete_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test052_Should_Throw_When_Delete_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Delete(), "DeleteTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test052_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test053_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test053_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test054_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Descendants(), "DescendantsTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test054_Should_Throw_When_Locales_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test055_Should_Throw_When_Locales_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Locales(), "LocalesTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test055_Should_Throw_When_Localize_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test056_Should_Throw_When_Localize_Term_NonExistent_Taxonomy"); + var localizeModel = new TermModel { Name = "No" }; + var coll = new ParameterCollection(); + coll.Add("locale", "en-us"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Localize(localizeModel, coll), "LocalizeTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test056_Should_Throw_When_Move_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test057_Should_Throw_When_Move_Term_NonExistent_Taxonomy"); + var moveModel = new TermMoveModel + { + ParentUid = "x", + Order = 1 + }; + var coll = new ParameterCollection(); + coll.Add("force", true); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test057_Should_Throw_When_Create_Term_Duplicate_Uid() + { + TestOutputLogger.LogContext("TestScenario", "Test058_Should_Throw_When_Create_Term_Duplicate_Uid"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); + var termModel = new TermModel + { + Uid = _rootTermUid, + Name = "Duplicate" + }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermDuplicateUid"); + } + + [TestMethod] + [DoNotParallelize] + public void Test058_Should_Throw_When_Create_Term_Invalid_ParentUid() + { + TestOutputLogger.LogContext("TestScenario", "Test059_Should_Throw_When_Create_Term_Invalid_ParentUid"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + var termModel = new TermModel + { + Uid = "term_bad_parent_12345", + Name = "Bad Parent", + ParentUid = "non_existent_parent_uid_12345" + }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermInvalidParentUid"); + } + + [TestMethod] + [DoNotParallelize] + public void Test059_Should_Throw_When_Move_Term_To_Itself() + { + TestOutputLogger.LogContext("TestScenario", "Test060_Should_Throw_When_Move_Term_To_Itself"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); + if (string.IsNullOrEmpty(_rootTermUid)) + { + AssertLogger.Inconclusive("Root term not available, skipping self-referential move test."); + return; + } + var moveModel = new TermMoveModel + { + ParentUid = _rootTermUid, + Order = 1 + }; + var coll = new ParameterCollection(); + coll.Add("force", true); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms(_rootTermUid).Move(moveModel, coll), "MoveTermToItself"); + } + private static Stack GetStack() { StackResponse response = StackResponse.getStack(_client.serializer); From 9752bcb21bd90a8959be76ddc83ff8253bd941b0 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Wed, 18 Mar 2026 10:06:41 +0530 Subject: [PATCH 3/6] Revert "fix: resolve Snyk CWE-798 hardcoded-credentials false positive in TestDataHelper" This reverts commit dc85c14a6a77f4f3b0dba6a1426fd317a3817a45. --- .../Contentstack017_TaxonomyTest.cs | 214 ------------------ 1 file changed, 214 deletions(-) diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs index 3690419..ba34b4c 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs @@ -801,220 +801,6 @@ public void Test042_Should_Throw_When_Delete_NonExistent_Term() _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Delete(), "DeleteNonExistentTerm"); } - [TestMethod] - [DoNotParallelize] - public void Test043_Should_Throw_When_Ancestors_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test043_Should_Throw_When_Ancestors_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test044_Should_Throw_When_Descendants_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test044_Should_Throw_When_Descendants_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Descendants(), "DescendantsNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test045_Should_Throw_When_Locales_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test045_Should_Throw_When_Locales_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Locales(), "LocalesNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test046_Should_Throw_When_Move_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test047_Should_Throw_When_Move_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); - if (string.IsNullOrEmpty(_rootTermUid)) - { - AssertLogger.Inconclusive("Root term not available, skipping move non-existent term test."); - return; - } - var moveModel = new TermMoveModel - { - ParentUid = _rootTermUid, - Order = 1 - }; - var coll = new ParameterCollection(); - coll.Add("force", true); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test047_Should_Throw_When_Create_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test048_Should_Throw_When_Create_Term_NonExistent_Taxonomy"); - var termModel = new TermModel - { - Uid = "some_term_uid", - Name = "No" - }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Create(termModel), "CreateTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test048_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test049_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Fetch(), "FetchTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test049_Should_Throw_When_Query_Terms_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test050_Should_Throw_When_Query_Terms_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Query().Find(), "QueryTermsNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test050_Should_Throw_When_Update_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test051_Should_Throw_When_Update_Term_NonExistent_Taxonomy"); - var updateModel = new TermModel { Name = "No" }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Update(updateModel), "UpdateTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test051_Should_Throw_When_Delete_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test052_Should_Throw_When_Delete_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Delete(), "DeleteTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test052_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test053_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test053_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test054_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Descendants(), "DescendantsTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test054_Should_Throw_When_Locales_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test055_Should_Throw_When_Locales_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Locales(), "LocalesTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test055_Should_Throw_When_Localize_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test056_Should_Throw_When_Localize_Term_NonExistent_Taxonomy"); - var localizeModel = new TermModel { Name = "No" }; - var coll = new ParameterCollection(); - coll.Add("locale", "en-us"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Localize(localizeModel, coll), "LocalizeTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test056_Should_Throw_When_Move_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test057_Should_Throw_When_Move_Term_NonExistent_Taxonomy"); - var moveModel = new TermMoveModel - { - ParentUid = "x", - Order = 1 - }; - var coll = new ParameterCollection(); - coll.Add("force", true); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test057_Should_Throw_When_Create_Term_Duplicate_Uid() - { - TestOutputLogger.LogContext("TestScenario", "Test058_Should_Throw_When_Create_Term_Duplicate_Uid"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); - var termModel = new TermModel - { - Uid = _rootTermUid, - Name = "Duplicate" - }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermDuplicateUid"); - } - - [TestMethod] - [DoNotParallelize] - public void Test058_Should_Throw_When_Create_Term_Invalid_ParentUid() - { - TestOutputLogger.LogContext("TestScenario", "Test059_Should_Throw_When_Create_Term_Invalid_ParentUid"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - var termModel = new TermModel - { - Uid = "term_bad_parent_12345", - Name = "Bad Parent", - ParentUid = "non_existent_parent_uid_12345" - }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermInvalidParentUid"); - } - - [TestMethod] - [DoNotParallelize] - public void Test059_Should_Throw_When_Move_Term_To_Itself() - { - TestOutputLogger.LogContext("TestScenario", "Test060_Should_Throw_When_Move_Term_To_Itself"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); - if (string.IsNullOrEmpty(_rootTermUid)) - { - AssertLogger.Inconclusive("Root term not available, skipping self-referential move test."); - return; - } - var moveModel = new TermMoveModel - { - ParentUid = _rootTermUid, - Order = 1 - }; - var coll = new ParameterCollection(); - coll.Add("force", true); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms(_rootTermUid).Move(moveModel, coll), "MoveTermToItself"); - } - private static Stack GetStack() { StackResponse response = StackResponse.getStack(_client.serializer); From 51ae63fcb52b99f5701b7bce97832a5d76b35e92 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Wed, 18 Mar 2026 10:14:52 +0530 Subject: [PATCH 4/6] feat: Added the negative path test cases for the terms support --- .../Contentstack017_TaxonomyTest.cs | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs index ba34b4c..3690419 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs @@ -801,6 +801,220 @@ public void Test042_Should_Throw_When_Delete_NonExistent_Term() _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Delete(), "DeleteNonExistentTerm"); } + [TestMethod] + [DoNotParallelize] + public void Test043_Should_Throw_When_Ancestors_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test043_Should_Throw_When_Ancestors_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test044_Should_Throw_When_Descendants_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test044_Should_Throw_When_Descendants_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Descendants(), "DescendantsNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test045_Should_Throw_When_Locales_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test045_Should_Throw_When_Locales_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Locales(), "LocalesNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test046_Should_Throw_When_Move_NonExistent_Term() + { + TestOutputLogger.LogContext("TestScenario", "Test047_Should_Throw_When_Move_NonExistent_Term"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); + if (string.IsNullOrEmpty(_rootTermUid)) + { + AssertLogger.Inconclusive("Root term not available, skipping move non-existent term test."); + return; + } + var moveModel = new TermMoveModel + { + ParentUid = _rootTermUid, + Order = 1 + }; + var coll = new ParameterCollection(); + coll.Add("force", true); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveNonExistentTerm"); + } + + [TestMethod] + [DoNotParallelize] + public void Test047_Should_Throw_When_Create_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test048_Should_Throw_When_Create_Term_NonExistent_Taxonomy"); + var termModel = new TermModel + { + Uid = "some_term_uid", + Name = "No" + }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Create(termModel), "CreateTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test048_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test049_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Fetch(), "FetchTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test049_Should_Throw_When_Query_Terms_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test050_Should_Throw_When_Query_Terms_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Query().Find(), "QueryTermsNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test050_Should_Throw_When_Update_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test051_Should_Throw_When_Update_Term_NonExistent_Taxonomy"); + var updateModel = new TermModel { Name = "No" }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Update(updateModel), "UpdateTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test051_Should_Throw_When_Delete_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test052_Should_Throw_When_Delete_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Delete(), "DeleteTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test052_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test053_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test053_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test054_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Descendants(), "DescendantsTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test054_Should_Throw_When_Locales_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test055_Should_Throw_When_Locales_Term_NonExistent_Taxonomy"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Locales(), "LocalesTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test055_Should_Throw_When_Localize_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test056_Should_Throw_When_Localize_Term_NonExistent_Taxonomy"); + var localizeModel = new TermModel { Name = "No" }; + var coll = new ParameterCollection(); + coll.Add("locale", "en-us"); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Localize(localizeModel, coll), "LocalizeTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test056_Should_Throw_When_Move_Term_NonExistent_Taxonomy() + { + TestOutputLogger.LogContext("TestScenario", "Test057_Should_Throw_When_Move_Term_NonExistent_Taxonomy"); + var moveModel = new TermMoveModel + { + ParentUid = "x", + Order = 1 + }; + var coll = new ParameterCollection(); + coll.Add("force", true); + AssertLogger.ThrowsException(() => + _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveTermNonExistentTaxonomy"); + } + + [TestMethod] + [DoNotParallelize] + public void Test057_Should_Throw_When_Create_Term_Duplicate_Uid() + { + TestOutputLogger.LogContext("TestScenario", "Test058_Should_Throw_When_Create_Term_Duplicate_Uid"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); + var termModel = new TermModel + { + Uid = _rootTermUid, + Name = "Duplicate" + }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermDuplicateUid"); + } + + [TestMethod] + [DoNotParallelize] + public void Test058_Should_Throw_When_Create_Term_Invalid_ParentUid() + { + TestOutputLogger.LogContext("TestScenario", "Test059_Should_Throw_When_Create_Term_Invalid_ParentUid"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + var termModel = new TermModel + { + Uid = "term_bad_parent_12345", + Name = "Bad Parent", + ParentUid = "non_existent_parent_uid_12345" + }; + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermInvalidParentUid"); + } + + [TestMethod] + [DoNotParallelize] + public void Test059_Should_Throw_When_Move_Term_To_Itself() + { + TestOutputLogger.LogContext("TestScenario", "Test060_Should_Throw_When_Move_Term_To_Itself"); + TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); + TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); + if (string.IsNullOrEmpty(_rootTermUid)) + { + AssertLogger.Inconclusive("Root term not available, skipping self-referential move test."); + return; + } + var moveModel = new TermMoveModel + { + ParentUid = _rootTermUid, + Order = 1 + }; + var coll = new ParameterCollection(); + coll.Add("force", true); + AssertLogger.ThrowsException(() => + _stack.Taxonomy(_taxonomyUid).Terms(_rootTermUid).Move(moveModel, coll), "MoveTermToItself"); + } + private static Stack GetStack() { StackResponse response = StackResponse.getStack(_client.serializer); From fe30677297aafcd6907d01d781c1278a11f7c703 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Wed, 18 Mar 2026 11:09:10 +0530 Subject: [PATCH 5/6] Revert "feat: Added the negative path test cases for the terms support" This reverts commit 51ae63fcb52b99f5701b7bce97832a5d76b35e92. --- .../Contentstack017_TaxonomyTest.cs | 214 ------------------ 1 file changed, 214 deletions(-) diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs index 3690419..ba34b4c 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack017_TaxonomyTest.cs @@ -801,220 +801,6 @@ public void Test042_Should_Throw_When_Delete_NonExistent_Term() _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Delete(), "DeleteNonExistentTerm"); } - [TestMethod] - [DoNotParallelize] - public void Test043_Should_Throw_When_Ancestors_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test043_Should_Throw_When_Ancestors_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test044_Should_Throw_When_Descendants_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test044_Should_Throw_When_Descendants_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Descendants(), "DescendantsNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test045_Should_Throw_When_Locales_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test045_Should_Throw_When_Locales_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Locales(), "LocalesNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test046_Should_Throw_When_Move_NonExistent_Term() - { - TestOutputLogger.LogContext("TestScenario", "Test047_Should_Throw_When_Move_NonExistent_Term"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); - if (string.IsNullOrEmpty(_rootTermUid)) - { - AssertLogger.Inconclusive("Root term not available, skipping move non-existent term test."); - return; - } - var moveModel = new TermMoveModel - { - ParentUid = _rootTermUid, - Order = 1 - }; - var coll = new ParameterCollection(); - coll.Add("force", true); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveNonExistentTerm"); - } - - [TestMethod] - [DoNotParallelize] - public void Test047_Should_Throw_When_Create_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test048_Should_Throw_When_Create_Term_NonExistent_Taxonomy"); - var termModel = new TermModel - { - Uid = "some_term_uid", - Name = "No" - }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Create(termModel), "CreateTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test048_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test049_Should_Throw_When_Fetch_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Fetch(), "FetchTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test049_Should_Throw_When_Query_Terms_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test050_Should_Throw_When_Query_Terms_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms().Query().Find(), "QueryTermsNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test050_Should_Throw_When_Update_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test051_Should_Throw_When_Update_Term_NonExistent_Taxonomy"); - var updateModel = new TermModel { Name = "No" }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Update(updateModel), "UpdateTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test051_Should_Throw_When_Delete_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test052_Should_Throw_When_Delete_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Delete(), "DeleteTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test052_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test053_Should_Throw_When_Ancestors_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Ancestors(), "AncestorsTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test053_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test054_Should_Throw_When_Descendants_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Descendants(), "DescendantsTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test054_Should_Throw_When_Locales_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test055_Should_Throw_When_Locales_Term_NonExistent_Taxonomy"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Locales(), "LocalesTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test055_Should_Throw_When_Localize_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test056_Should_Throw_When_Localize_Term_NonExistent_Taxonomy"); - var localizeModel = new TermModel { Name = "No" }; - var coll = new ParameterCollection(); - coll.Add("locale", "en-us"); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Localize(localizeModel, coll), "LocalizeTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test056_Should_Throw_When_Move_Term_NonExistent_Taxonomy() - { - TestOutputLogger.LogContext("TestScenario", "Test057_Should_Throw_When_Move_Term_NonExistent_Taxonomy"); - var moveModel = new TermMoveModel - { - ParentUid = "x", - Order = 1 - }; - var coll = new ParameterCollection(); - coll.Add("force", true); - AssertLogger.ThrowsException(() => - _stack.Taxonomy("non_existent_taxonomy_uid_12345").Terms("non_existent_term_uid_12345").Move(moveModel, coll), "MoveTermNonExistentTaxonomy"); - } - - [TestMethod] - [DoNotParallelize] - public void Test057_Should_Throw_When_Create_Term_Duplicate_Uid() - { - TestOutputLogger.LogContext("TestScenario", "Test058_Should_Throw_When_Create_Term_Duplicate_Uid"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); - var termModel = new TermModel - { - Uid = _rootTermUid, - Name = "Duplicate" - }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermDuplicateUid"); - } - - [TestMethod] - [DoNotParallelize] - public void Test058_Should_Throw_When_Create_Term_Invalid_ParentUid() - { - TestOutputLogger.LogContext("TestScenario", "Test059_Should_Throw_When_Create_Term_Invalid_ParentUid"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - var termModel = new TermModel - { - Uid = "term_bad_parent_12345", - Name = "Bad Parent", - ParentUid = "non_existent_parent_uid_12345" - }; - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms().Create(termModel), "CreateTermInvalidParentUid"); - } - - [TestMethod] - [DoNotParallelize] - public void Test059_Should_Throw_When_Move_Term_To_Itself() - { - TestOutputLogger.LogContext("TestScenario", "Test060_Should_Throw_When_Move_Term_To_Itself"); - TestOutputLogger.LogContext("TaxonomyUid", _taxonomyUid ?? ""); - TestOutputLogger.LogContext("RootTermUid", _rootTermUid ?? ""); - if (string.IsNullOrEmpty(_rootTermUid)) - { - AssertLogger.Inconclusive("Root term not available, skipping self-referential move test."); - return; - } - var moveModel = new TermMoveModel - { - ParentUid = _rootTermUid, - Order = 1 - }; - var coll = new ParameterCollection(); - coll.Add("force", true); - AssertLogger.ThrowsException(() => - _stack.Taxonomy(_taxonomyUid).Terms(_rootTermUid).Move(moveModel, coll), "MoveTermToItself"); - } - private static Stack GetStack() { StackResponse response = StackResponse.getStack(_client.serializer); From ea67577285474577af199093f46ef7e3e3ada0c9 Mon Sep 17 00:00:00 2001 From: OMpawar-21 Date: Mon, 23 Mar 2026 12:22:00 +0530 Subject: [PATCH 6/6] fix: resolve Snyk Core parse error and ReDoS in test project dependencies --- .../Contentstack.Management.Core.Tests.csproj | 1 + ...entstack.Management.Core.Unit.Tests.csproj | 1 + .../contentstack.management.core.csproj | 12 +- snyk.json | 108 ++++++++++++++++++ 4 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 snyk.json diff --git a/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj b/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj index aec1149..a8efdf8 100644 --- a/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj +++ b/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj @@ -25,6 +25,7 @@ + diff --git a/Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj b/Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj index e351e54..0a1e484 100644 --- a/Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj +++ b/Contentstack.Management.Core.Unit.Tests/Contentstack.Management.Core.Unit.Tests.csproj @@ -20,6 +20,7 @@ + diff --git a/Contentstack.Management.Core/contentstack.management.core.csproj b/Contentstack.Management.Core/contentstack.management.core.csproj index be21ae3..f422b69 100644 --- a/Contentstack.Management.Core/contentstack.management.core.csproj +++ b/Contentstack.Management.Core/contentstack.management.core.csproj @@ -1,9 +1,13 @@ - - - netstandard2.0;net471;net472 - netstandard2.0 + + + netstandard2.0;net471;net472 + + + netstandard2.0 + + 8.0 enable Contentstack Management diff --git a/snyk.json b/snyk.json new file mode 100644 index 0000000..04c01de --- /dev/null +++ b/snyk.json @@ -0,0 +1,108 @@ +{ + "vulnerabilities": [], + "ok": true, + "dependencyCount": 63, + "org": "contentstack-devex", + "policy": "# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.\nversion: v1.25.1\nignore: {}\npatch: {}\n", + "isPrivate": true, + "licensesPolicy": { + "severities": {}, + "orgLicenseRules": { + "AGPL-1.0": { + "licenseType": "AGPL-1.0", + "severity": "high", + "instructions": "" + }, + "AGPL-3.0": { + "licenseType": "AGPL-3.0", + "severity": "high", + "instructions": "" + }, + "Artistic-1.0": { + "licenseType": "Artistic-1.0", + "severity": "medium", + "instructions": "" + }, + "Artistic-2.0": { + "licenseType": "Artistic-2.0", + "severity": "medium", + "instructions": "" + }, + "CDDL-1.0": { + "licenseType": "CDDL-1.0", + "severity": "medium", + "instructions": "" + }, + "CPOL-1.02": { + "licenseType": "CPOL-1.02", + "severity": "high", + "instructions": "" + }, + "EPL-1.0": { + "licenseType": "EPL-1.0", + "severity": "medium", + "instructions": "" + }, + "GPL-2.0": { + "licenseType": "GPL-2.0", + "severity": "high", + "instructions": "" + }, + "GPL-3.0": { + "licenseType": "GPL-3.0", + "severity": "high", + "instructions": "" + }, + "LGPL-2.0": { + "licenseType": "LGPL-2.0", + "severity": "medium", + "instructions": "" + }, + "LGPL-2.1": { + "licenseType": "LGPL-2.1", + "severity": "medium", + "instructions": "" + }, + "LGPL-3.0": { + "licenseType": "LGPL-3.0", + "severity": "medium", + "instructions": "" + }, + "MPL-1.1": { + "licenseType": "MPL-1.1", + "severity": "medium", + "instructions": "" + }, + "MPL-2.0": { + "licenseType": "MPL-2.0", + "severity": "medium", + "instructions": "" + }, + "MS-RL": { + "licenseType": "MS-RL", + "severity": "medium", + "instructions": "" + }, + "SimPL-2.0": { + "licenseType": "SimPL-2.0", + "severity": "high", + "instructions": "" + } + } + }, + "packageManager": "nuget", + "ignoreSettings": { + "adminOnly": false, + "reasonRequired": false, + "disregardFilesystemIgnores": false + }, + "summary": "No known vulnerabilities", + "filesystemPolicy": false, + "uniqueCount": 0, + "targetFile": "Contentstack.Management.Core/obj/project.assets.json", + "projectName": "contentstack-management-dotnet", + "foundProjectCount": 5, + "displayTargetFile": "Contentstack.Management.Core/obj/project.assets.json", + "hasUnknownVersions": false, + "path": "/Users/om.pawar/Desktop/SDKs/contentstack-management-dotnet" +}