diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d7b888..6db66d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,9 +36,13 @@ - Migrated `LocaleModel` and `BulkOperationModels` to use `System.Text.Json` attributes - Added/updated unit and integration test coverage for Locale and Bulk Operations - Upgraded target framework to .NET 10 and removed all build warnings - - **Note**: - - This is a beta release and APIs/modules may continue evolving during migration stabilization - - Release and Workflow setup within Bulk Operations module are currently commented out and will be uncommented once the Release and Workflow modules are migrated to System.Text.Json + - Remaining modules migrated and re-enabled — `AuditLog`, `Extension`, `Label`, `Role`, `Taxonomy`, `Term`, `Webhook`, `DeliveryToken`, `ManagementToken`, and `CustomExtension` fully re-enabled with STJ attributes; all corresponding `Stack.*()` accessor methods restored + - All `[JsonProperty]` replaced with `[JsonPropertyName]` across all model classes; `[JsonObject(ItemNullValueHandling)]` removed in favour of global `DefaultIgnoreCondition = WhenWritingNull` + - OAuth module enabled — `OAuthHandler`, `OAuthTokenService`, `OAuthAppAuthorizationService`, and `OAuthAppRevocationService` now active; auto token refresh wired into `InvokeAsync` pipeline via `EnsureOAuthTokenIsValidAsync` + - CustomWidgetModel scope serialization migrated from `JsonTextWriter` to `System.Text.Json.JsonSerializer.Serialize()` + - Asset extension upload tests — 3 previously skipped tests (`Test002_Should_Create_Dashboard`, `Test003_Should_Create_Custom_Widget`, `Test004_Should_Create_Custom_field`) now have real implementations + - Unit test coverage expanded — 991 → 1,242 passing tests; 24 previously excluded test files re-enabled covering AuditLog, Extension, Label, Role, Taxonomy, Term, Webhook, DeliveryToken, CustomExtension, and all infrastructure tests (HTTP pipeline, converters, runtime contexts, utilities) + - Integration test coverage expanded — 4 previously excluded integration test files re-enabled: ContentType Expanded (`Contentstack012b`), DeliveryToken (`Contentstack016`), Taxonomy (`Contentstack017`), Role (`Contentstack019`) ## [v0.10.0](https://github.com/contentstack/contentstack-management-dotnet/tree/v0.9.0) - Feat diff --git a/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj b/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj index e38c043..9a95597 100644 --- a/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj +++ b/Contentstack.Management.Core.Tests/Contentstack.Management.Core.Tests.csproj @@ -51,12 +51,4 @@ - - - - - - - - diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012b_ContentTypeExpandedIntegrationTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012b_ContentTypeExpandedIntegrationTest.cs index 0231a40..7103d02 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012b_ContentTypeExpandedIntegrationTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack012b_ContentTypeExpandedIntegrationTest.cs @@ -5,6 +5,7 @@ using System.Net; using System.Threading.Tasks; using Contentstack.Management.Core.Models; +using Contentstack.Management.Core.Models.CustomExtension; using Contentstack.Management.Core.Models.Fields; using Contentstack.Management.Core.Tests.Helpers; using Contentstack.Management.Core.Tests.Model; diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs index ac78fcc..c75864d 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack013_AssetTest.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Text; using Contentstack.Management.Core.Models; +using Contentstack.Management.Core.Models.CustomExtension; using Contentstack.Management.Core.Tests.Helpers; using Contentstack.Management.Core.Tests.Model; using Contentstack.Management.Core.Exceptions; @@ -404,32 +405,92 @@ public async Task Test001_Should_Create_Asset() } } - // Tests 002-004 depend on Extension/CustomExtension SDK module (excluded from current scope) [TestMethod] [DoNotParallelize] - [Ignore("Requires Extension SDK module (Models/CustomExtension) which is out of current scope")] public async Task Test002_Should_Create_Dashboard() { - Assert.Inconclusive("Extension SDK module not available in current scope."); - await System.Threading.Tasks.Task.CompletedTask; + TestOutputLogger.LogContext("TestScenario", "CreateDashboardWidget"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/extension.html"); + try + { + DashboardWidgetModel dashboard = new DashboardWidgetModel( + path, "text/html", "Integration Test Dashboard", + isEnable: true, defaultWidth: "half", tags: "dashboard,test"); + ContentstackResponse response = await _stack.Extension().UploadAsync(dashboard); + TestOutputLogger.LogContext("StackAPIKey", _stack?.APIKey ?? "null"); + + if (response.IsSuccessStatusCode) + { + AssertLogger.IsNotNull(response.OpenJsonObjectResponse()["extension"], "CreateDashboard_ResponseContainsExtension"); + } + else + { + AssertLogger.Fail("Dashboard Widget Creation Failed", response.OpenResponse()); + } + } + catch (Exception e) + { + AssertLogger.Fail("Dashboard Widget Creation Failed", e.Message); + } } [TestMethod] [DoNotParallelize] - [Ignore("Requires Extension SDK module (Models/CustomExtension) which is out of current scope")] public async Task Test003_Should_Create_Custom_Widget() { - Assert.Inconclusive("Extension SDK module not available in current scope."); - await System.Threading.Tasks.Task.CompletedTask; + TestOutputLogger.LogContext("TestScenario", "CreateCustomWidget"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/extension.html"); + try + { + var scope = new ExtensionScope { ContentTypes = new List { "$all" } }; + CustomWidgetModel widget = new CustomWidgetModel( + path, "text/html", "Integration Test Widget", + tags: "widget,test", scope: scope); + ContentstackResponse response = await _stack.Extension().UploadAsync(widget); + TestOutputLogger.LogContext("StackAPIKey", _stack?.APIKey ?? "null"); + + if (response.IsSuccessStatusCode) + { + AssertLogger.IsNotNull(response.OpenJsonObjectResponse()["extension"], "CreateCustomWidget_ResponseContainsExtension"); + } + else + { + AssertLogger.Fail("Custom Widget Creation Failed", response.OpenResponse()); + } + } + catch (Exception e) + { + AssertLogger.Fail("Custom Widget Creation Failed", e.Message); + } } [TestMethod] [DoNotParallelize] - [Ignore("Requires Extension SDK module (Models/CustomExtension) which is out of current scope")] public async Task Test004_Should_Create_Custom_field() { - Assert.Inconclusive("Extension SDK module not available in current scope."); - await System.Threading.Tasks.Task.CompletedTask; + TestOutputLogger.LogContext("TestScenario", "CreateCustomField"); + var path = Path.Combine(System.Environment.CurrentDirectory, "../../../Mock/extension.html"); + try + { + CustomFieldModel field = new CustomFieldModel( + path, "text/html", "Integration Test Field", + dataType: "text", isMultiple: false, tags: "field,test"); + ContentstackResponse response = await _stack.Extension().UploadAsync(field); + TestOutputLogger.LogContext("StackAPIKey", _stack?.APIKey ?? "null"); + + if (response.IsSuccessStatusCode) + { + AssertLogger.IsNotNull(response.OpenJsonObjectResponse()["extension"], "CreateCustomField_ResponseContainsExtension"); + } + else + { + AssertLogger.Fail("Custom Field Creation Failed", response.OpenResponse()); + } + } + catch (Exception e) + { + AssertLogger.Fail("Custom Field Creation Failed", e.Message); + } } private string _testAssetUid; diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs index 1cb0c0d..cabacb7 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack015_BulkOperationTest.cs @@ -3665,7 +3665,7 @@ private async Task CreateTestRelease() if (response.IsSuccessStatusCode && responseJson["release"] != null) _testReleaseUid = responseJson["release"]["uid"].ToString(); } - catch (Exception e) { } + catch (Exception) { } await Task.CompletedTask; } diff --git a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack019_RoleTest.cs b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack019_RoleTest.cs index f48b1f7..19be766 100644 --- a/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack019_RoleTest.cs +++ b/Contentstack.Management.Core.Tests/IntegrationTest/Contentstack019_RoleTest.cs @@ -94,7 +94,7 @@ private static bool RolesArrayContainsUid(JsonArray roles, string uid) return false; } - return roles.Any(r => r["uid"]?.ToString() == uid); + return roles.Any(r => r?["uid"]?.ToString() == uid); } /// 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 c6f1c49..0a0216b 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 @@ -54,36 +54,8 @@ - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - diff --git a/Contentstack.Management.Core.Unit.Tests/Http/ContentstackHttpResponseTest.cs b/Contentstack.Management.Core.Unit.Tests/Http/ContentstackHttpResponseTest.cs index 36c0cce..5698676 100644 --- a/Contentstack.Management.Core.Unit.Tests/Http/ContentstackHttpResponseTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Http/ContentstackHttpResponseTest.cs @@ -75,7 +75,7 @@ public void Should_Throw_Object_Disposed_Exception_On_Object_Dispose() contentstackHttpResponse.Dispose(); Assert.ThrowsException(() => contentstackHttpResponse.OpenResponse()); - Assert.ThrowsException(() => contentstackHttpResponse.OpenJObjectResponse()); + Assert.ThrowsException(() => contentstackHttpResponse.OpenJsonObjectResponse()); Assert.ThrowsException(() => contentstackHttpResponse.OpenTResponse()); contentstackHttpResponse.Dispose(); diff --git a/Contentstack.Management.Core.Unit.Tests/Models/AuditLogTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/AuditLogTest.cs index d09af8b..7357e68 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/AuditLogTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/AuditLogTest.cs @@ -52,7 +52,7 @@ public void Should_Fetch_AuditLog() ContentstackResponse response = _stack.AuditLog(_fixture.Create()).Fetch(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -61,7 +61,7 @@ public async System.Threading.Tasks.Task Should_Fetch_AuditLog_Async() ContentstackResponse response = await _stack.AuditLog(_fixture.Create()).FetchAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -70,7 +70,7 @@ public void Should_Find_AuditLog() ContentstackResponse response = _stack.AuditLog().FindAll(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -79,7 +79,7 @@ public async System.Threading.Tasks.Task Should_Find_AuditLog_Async() ContentstackResponse response = await _stack.AuditLog().FindAllAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } } diff --git a/Contentstack.Management.Core.Unit.Tests/Models/BaseModelTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/BaseModelTest.cs index c9e44d0..e6c0c57 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/BaseModelTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/BaseModelTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using AutoFixture; using Contentstack.Management.Core.Models; using Contentstack.Management.Core.Unit.Tests.Mokes; @@ -41,12 +41,12 @@ public void Initialize_ContentType() BaseModel baseModel = new BaseModel(_stack, _fixture.Create()); Assert.IsNull(baseModel.Uid); - Assert.ThrowsException(() => baseModel.Fetch()); - Assert.ThrowsExceptionAsync(() => baseModel.FetchAsync()); - Assert.ThrowsException(() => baseModel.Update(new ContentModelling())); - Assert.ThrowsExceptionAsync(() => baseModel.UpdateAsync(new ContentModelling())); - Assert.ThrowsException(() => baseModel.Delete()); - Assert.ThrowsExceptionAsync(() => baseModel.DeleteAsync()); + Assert.ThrowsException(() => baseModel.Fetch()); + Assert.ThrowsExceptionAsync(() => baseModel.FetchAsync()); + Assert.ThrowsException(() => baseModel.Update(new ContentModelling())); + Assert.ThrowsExceptionAsync(() => baseModel.UpdateAsync(new ContentModelling())); + Assert.ThrowsException(() => baseModel.Delete()); + Assert.ThrowsExceptionAsync(() => baseModel.DeleteAsync()); } [TestMethod] @@ -69,7 +69,7 @@ public void Should_Return_Mock_Response_On_Create() ContentstackResponse response = baseModel.Create(new ContentModelling()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -81,7 +81,7 @@ public async System.Threading.Tasks.Task Should_Return_Mock_Response_On_CreateAs ContentstackResponse response = await baseModel.CreateAsync(new ContentModelling()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -93,7 +93,7 @@ public void Should_Return_Mock_Response_On_Update() ContentstackResponse response = baseModel.Update(new ContentModelling()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -105,7 +105,7 @@ public async System.Threading.Tasks.Task Should_Return_Mock_Response_On_UpdateAs ContentstackResponse response = await baseModel.UpdateAsync(new ContentModelling()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -117,7 +117,7 @@ public void Should_Return_Mock_Response_On_Fetch() ContentstackResponse response = baseModel.Fetch(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -129,7 +129,7 @@ public async System.Threading.Tasks.Task Should_Return_Mock_Response_On_FetchAsy ContentstackResponse response = await baseModel.FetchAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -141,7 +141,7 @@ public void Should_Return_Mock_Response_On_Delete() ContentstackResponse response = baseModel.Delete(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -153,7 +153,7 @@ public async System.Threading.Tasks.Task Should_Return_Mock_Response_On_DeleteAs ContentstackResponse response = await baseModel.DeleteAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } } } diff --git a/Contentstack.Management.Core.Unit.Tests/Models/CustomExtensionTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/CustomExtensionTest.cs index b8aec2f..6f3cc62 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/CustomExtensionTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/CustomExtensionTest.cs @@ -9,7 +9,6 @@ using Contentstack.Management.Core.Models.CustomExtension; using Contentstack.Management.Core.Models.Fields; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; namespace Contentstack.Management.Core.Unit.Tests.Models { diff --git a/Contentstack.Management.Core.Unit.Tests/Models/ExtensionModelTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/ExtensionModelTest.cs index 9b33cff..5ed586b 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/ExtensionModelTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/ExtensionModelTest.cs @@ -1,27 +1,22 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; +using System.Collections.Generic; +using System.Text.Json; using AutoFixture; using AutoFixture.AutoMoq; using Contentstack.Management.Core.Models; using Contentstack.Management.Core.Models.Fields; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; namespace Contentstack.Management.Core.Unit.Tests.Models { [TestClass] public class ExtensionModelTest { - private JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings()); private readonly IFixture _fixture = new Fixture() .Customize(new AutoMoqCustomization()); [TestMethod] public void Initialize_ExtensionModel_For_URL() { - ExtensionModel extensionModel = new ExtensionModel() { Title = _fixture.Create(), @@ -34,14 +29,8 @@ public void Initialize_ExtensionModel_For_URL() Scope = _fixture.Create() }; - using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) - { - JsonWriter writer = new JsonTextWriter(stringWriter); - - serializer.Serialize(writer, extensionModel); - string snippet = stringWriter.ToString(); - Assert.IsNotNull(snippet); - } + string snippet = JsonSerializer.Serialize(extensionModel); + Assert.IsNotNull(snippet); } [TestMethod] @@ -59,14 +48,8 @@ public void Initialize_ExtensionModel_For_Source_Code() Scope = _fixture.Create() }; - using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) - { - JsonWriter writer = new JsonTextWriter(stringWriter); - - serializer.Serialize(writer, extensionModel); - string snippet = stringWriter.ToString(); - Assert.IsNotNull(snippet); - } + string snippet = JsonSerializer.Serialize(extensionModel); + Assert.IsNotNull(snippet); } } } diff --git a/Contentstack.Management.Core.Unit.Tests/Models/ExtensionTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/ExtensionTest.cs index e51b902..d59364a 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/ExtensionTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/ExtensionTest.cs @@ -64,7 +64,7 @@ public void Should_Upload_Custom_field() ContentstackResponse response = _stack.Extension().Upload(model); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -74,7 +74,7 @@ public async System.Threading.Tasks.Task Should_Upload_Async_Custom_field() ContentstackResponse response = await _stack.Extension().UploadAsync(model); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -83,7 +83,7 @@ public void Should_Query_Extension() ContentstackResponse response = _stack.Extension().Query().Find(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -92,7 +92,7 @@ public async System.Threading.Tasks.Task Should_Query_Extension_Async() ContentstackResponse response = await _stack.Extension().Query().FindAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -101,7 +101,7 @@ public void Should_Create_Extension() ContentstackResponse response = _stack.Extension().Create(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -110,7 +110,7 @@ public async System.Threading.Tasks.Task Should_Create_Extension_Async() ContentstackResponse response = await _stack.Extension().CreateAsync(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] public void Should_Fetch_Extension() @@ -118,7 +118,7 @@ public void Should_Fetch_Extension() ContentstackResponse response = _stack.Extension(_fixture.Create()).Fetch(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -127,7 +127,7 @@ public async System.Threading.Tasks.Task Should_Find_Extension_Async() ContentstackResponse response = await _stack.Extension(_fixture.Create()).FetchAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -136,7 +136,7 @@ public void Should_Update_Extension() ContentstackResponse response = _stack.Extension(_fixture.Create()).Update(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -145,7 +145,7 @@ public async System.Threading.Tasks.Task Should_Update_Extension_Async() ContentstackResponse response = await _stack.Extension(_fixture.Create()).UpdateAsync(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -154,7 +154,7 @@ public void Should_Delete_Extension() ContentstackResponse response = _stack.Extension(_fixture.Create()).Delete(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -163,7 +163,7 @@ public async System.Threading.Tasks.Task Should_Delete_Extension_Async() ContentstackResponse response = await _stack.Extension(_fixture.Create()).DeleteAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } } } diff --git a/Contentstack.Management.Core.Unit.Tests/Models/LabelTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/LabelTest.cs index bf52ed0..77fc4cd 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/LabelTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/LabelTest.cs @@ -30,12 +30,12 @@ public void Initialize_Label() Assert.IsNull(label.Uid); Assert.AreEqual($"/labels", label.resourcePath); - Assert.ThrowsException(() => label.Fetch()); - Assert.ThrowsExceptionAsync(() => label.FetchAsync()); - Assert.ThrowsException(() => label.Update(_fixture.Create())); - Assert.ThrowsExceptionAsync(() => label.UpdateAsync(_fixture.Create())); - Assert.ThrowsException(() => label.Delete()); - Assert.ThrowsExceptionAsync(() => label.DeleteAsync()); + Assert.ThrowsException(() => label.Fetch()); + Assert.ThrowsExceptionAsync(() => label.FetchAsync()); + Assert.ThrowsException(() => label.Update(_fixture.Create())); + Assert.ThrowsExceptionAsync(() => label.UpdateAsync(_fixture.Create())); + Assert.ThrowsException(() => label.Delete()); + Assert.ThrowsExceptionAsync(() => label.DeleteAsync()); Assert.AreEqual(label.Query().GetType(), typeof(Query)); } @@ -58,7 +58,7 @@ public void Should_Create_Label() ContentstackResponse response = _stack.Label().Create(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -67,7 +67,7 @@ public async System.Threading.Tasks.Task Should_Create_Label_Async() ContentstackResponse response = await _stack.Label().CreateAsync(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -76,7 +76,7 @@ public void Should_Query_Label() ContentstackResponse response = _stack.Label().Query().Find(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -85,7 +85,7 @@ public async System.Threading.Tasks.Task Should_Query_Label_Async() ContentstackResponse response = await _stack.Label().Query().FindAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -94,7 +94,7 @@ public void Should_Fetch_Label() ContentstackResponse response = _stack.Label(_fixture.Create()).Fetch(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -103,7 +103,7 @@ public async System.Threading.Tasks.Task Should_Find_Label_Async() ContentstackResponse response = await _stack.Label(_fixture.Create()).FetchAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -112,7 +112,7 @@ public void Should_Update_Label() ContentstackResponse response = _stack.Label(_fixture.Create()).Update(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -121,7 +121,7 @@ public async System.Threading.Tasks.Task Should_Update_Label_Async() ContentstackResponse response = await _stack.Label(_fixture.Create()).UpdateAsync(_fixture.Create()); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -130,7 +130,7 @@ public void Should_Delete_Label() ContentstackResponse response = _stack.Label(_fixture.Create()).Delete(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } [TestMethod] @@ -139,7 +139,7 @@ public async System.Threading.Tasks.Task Should_Delete_Label_Async() ContentstackResponse response = await _stack.Label(_fixture.Create()).DeleteAsync(); Assert.AreEqual(_contentstackResponse.OpenResponse(), response.OpenResponse()); - Assert.AreEqual(_contentstackResponse.OpenJObjectResponse().ToString(), response.OpenJObjectResponse().ToString()); + Assert.AreEqual(_contentstackResponse.OpenJsonObjectResponse().ToString(), response.OpenJsonObjectResponse().ToString()); } } } diff --git a/Contentstack.Management.Core.Unit.Tests/Models/RoleTest.cs b/Contentstack.Management.Core.Unit.Tests/Models/RoleTest.cs index dbc4fd7..1b0d1d6 100644 --- a/Contentstack.Management.Core.Unit.Tests/Models/RoleTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Models/RoleTest.cs @@ -31,12 +31,12 @@ public void Initialize_Role() Assert.IsNull(role.Uid); Assert.AreEqual("/roles", role.resourcePath); - Assert.ThrowsException(() => role.Fetch()); - Assert.ThrowsExceptionAsync(() => role.FetchAsync()); - Assert.ThrowsException(() => role.Update(_fixture.Create())); - Assert.ThrowsExceptionAsync(() => role.UpdateAsync(_fixture.Create())); - Assert.ThrowsException(() => role.Delete()); - Assert.ThrowsExceptionAsync(() => role.DeleteAsync()); + Assert.ThrowsException(() => role.Fetch()); + Assert.ThrowsExceptionAsync(() => role.FetchAsync()); + Assert.ThrowsException(() => role.Update(_fixture.Create())); + Assert.ThrowsExceptionAsync(() => role.UpdateAsync(_fixture.Create())); + Assert.ThrowsException(() => role.Delete()); + Assert.ThrowsExceptionAsync(() => role.DeleteAsync()); Assert.AreEqual(role.Query().GetType(), typeof(Query)); } diff --git a/Contentstack.Management.Core.Unit.Tests/Mokes/CustomJsonConverter.cs b/Contentstack.Management.Core.Unit.Tests/Mokes/CustomJsonConverter.cs index 22646e9..976b249 100644 --- a/Contentstack.Management.Core.Unit.Tests/Mokes/CustomJsonConverter.cs +++ b/Contentstack.Management.Core.Unit.Tests/Mokes/CustomJsonConverter.cs @@ -1,42 +1,33 @@ -using System; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; using Contentstack.Management.Core.Attributes; -using Newtonsoft.Json; namespace Contentstack.Management.Core.Unit.Tests.Mokes { [CsmJsonConverter("CustomAutoload")] - public class CustomJsonConverter : JsonConverter + public class CustomJsonConverter : JsonConverter { - public override bool CanConvert(Type objectType) - { - return false; // Mock converter - not actually used for conversion - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { throw new NotImplementedException(); } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { throw new NotImplementedException(); } } [CsmJsonConverter("CustomManualLoad", false)] - public class CustomConverter : JsonConverter + public class CustomConverter : JsonConverter { - public override bool CanConvert(Type objectType) - { - return false; // Mock converter - not actually used for conversion - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { throw new NotImplementedException(); } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { throw new NotImplementedException(); } diff --git a/Contentstack.Management.Core.Unit.Tests/Mokes/MockHttpResponse.cs b/Contentstack.Management.Core.Unit.Tests/Mokes/MockHttpResponse.cs index 5ae4164..c6dc73c 100644 --- a/Contentstack.Management.Core.Unit.Tests/Mokes/MockHttpResponse.cs +++ b/Contentstack.Management.Core.Unit.Tests/Mokes/MockHttpResponse.cs @@ -1,9 +1,7 @@ -using System; using System.Collections.Generic; using System.Net; using System.Text.Json; using System.Text.Json.Nodes; -using Newtonsoft.Json.Linq; using Contentstack.Management.Core; namespace Contentstack.Management.Core.Unit.Tests.Mokes @@ -67,12 +65,6 @@ public JsonObject OpenJsonObjectResponse() } } - [Obsolete("Use OpenJsonObjectResponse() instead.")] - public JObject OpenJObjectResponse() - { - return null; - } - public string OpenResponse() { return _responseContent; diff --git a/Contentstack.Management.Core.Unit.Tests/Mokes/Model/StackModel.cs b/Contentstack.Management.Core.Unit.Tests/Mokes/Model/StackModel.cs index 297a329..963e4fe 100644 --- a/Contentstack.Management.Core.Unit.Tests/Mokes/Model/StackModel.cs +++ b/Contentstack.Management.Core.Unit.Tests/Mokes/Model/StackModel.cs @@ -1,21 +1,20 @@ -using System; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Contentstack.Management.Core.Unit.Tests.Mokes.Model { public class StackModel { - [JsonProperty("api_key")] + [JsonPropertyName("api_key")] public string APIKey { get; set; } public string Name { get; set; } public string Description { get; set; } - [JsonProperty("master_locale")] + [JsonPropertyName("master_locale")] public string MasterLocale { get; set; } - [JsonProperty("org_uid")] + [JsonPropertyName("org_uid")] public string OrgUid { get; set; } } @@ -26,7 +25,7 @@ public class StackResponse public class Response { - [JsonProperty("notice")] + [JsonPropertyName("notice")] public string Notice { get; set; } } } diff --git a/Contentstack.Management.Core.Unit.Tests/Queryable/ParameterCollectionTest.cs b/Contentstack.Management.Core.Unit.Tests/Queryable/ParameterCollectionTest.cs index d534eb6..1a428a9 100644 --- a/Contentstack.Management.Core.Unit.Tests/Queryable/ParameterCollectionTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Queryable/ParameterCollectionTest.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Contentstack.Management.Core.Queryable; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace Contentstack.Management.Core.Unit.Tests.Queryable { @@ -90,13 +90,13 @@ public void Should_Add_Double_List_Value_Parameter_Collection() public void Should_Add_Query_JObject_In_Parameter_Collection() { ParameterCollection collection = new ParameterCollection(); - JObject queryObject = JObject.Parse("{ \"price_in_usd\": { \"$lt\": 600 } }"); + JsonNode queryObject = JsonNode.Parse("{ \"price_in_usd\": { \"$lt\": 600 } }"); collection.AddQuery(queryObject); Assert.IsTrue(collection.ContainsKey("query")); Assert.IsInstanceOfType(collection["query"], typeof(StringParameterValue)); - Assert.AreEqual(Uri.EscapeDataString(queryObject.ToString()), (collection["query"] as StringParameterValue).Value); + Assert.AreEqual(Uri.EscapeDataString(queryObject.ToJsonString()), (collection["query"] as StringParameterValue).Value); } } } diff --git a/Contentstack.Management.Core.Unit.Tests/Runtime/Contexts/ContextTest.cs b/Contentstack.Management.Core.Unit.Tests/Runtime/Contexts/ContextTest.cs index cce5f2f..bf561d5 100644 --- a/Contentstack.Management.Core.Unit.Tests/Runtime/Contexts/ContextTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Runtime/Contexts/ContextTest.cs @@ -1,17 +1,16 @@ -using System; +using System.Text.Json; using Contentstack.Management.Core.Http; using Contentstack.Management.Core.Runtime.Contexts; using Contentstack.Management.Core.Services; using Contentstack.Management.Core.Unit.Tests.Mokes; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; namespace Contentstack.Management.Core.Unit.Tests.Runtime.Contexts { [TestClass] public class ContextTest { - private readonly JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings()); + private readonly JsonSerializerOptions jsonSerializer = new JsonSerializerOptions(); [TestMethod] public void Initialize_ExecutionContext() diff --git a/Contentstack.Management.Core.Unit.Tests/Utils/ContentstackUtilitiesTest.cs b/Contentstack.Management.Core.Unit.Tests/Utils/ContentstackUtilitiesTest.cs index 4d9dd04..c67dc94 100644 --- a/Contentstack.Management.Core.Unit.Tests/Utils/ContentstackUtilitiesTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Utils/ContentstackUtilitiesTest.cs @@ -3,7 +3,7 @@ using Contentstack.Management.Core.Unit.Tests.Mokes; using Contentstack.Management.Core.Utils; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json.Linq; +using System.Text.Json.Nodes; namespace Contentstack.Management.Core.Unit.Tests.Utils { @@ -90,15 +90,11 @@ public void Return_Query_Parameters_On_ParameterCollection() param.Add("limit", 10); param.Add("include", "type"); - JObject q_obj = JObject.Parse("{ \"price_in_usd\": { \"$lt\": 600 } }"); + JsonNode q_obj = JsonNode.Parse("{ \"price_in_usd\": { \"$lt\": 600 } }"); param.AddQuery(q_obj); var result = ContentstackUtilities.GetQueryParameter(param); - // Normalize line endings for cross-platform compatibility (JObject.ToString() uses platform-specific line endings) - var expected = "include=type&limit=10&query=%7B%0D%0A%20%20%22price_in_usd%22%3A%20%7B%0D%0A%20%20%20%20%22%24lt%22%3A%20600%0D%0A%20%20%7D%0D%0A%7D"; - // Normalize both to use \n for comparison - var normalizedExpected = expected.Replace("%0D%0A", "%0A"); - var normalizedActual = result.Replace("%0D%0A", "%0A"); - Assert.AreEqual(normalizedExpected, normalizedActual); + var expected = "include=type&limit=10&query=%7B%22price_in_usd%22%3A%7B%22%24lt%22%3A600%7D%7D"; + Assert.AreEqual(expected, result); } [TestMethod] diff --git a/Contentstack.Management.Core.Unit.Tests/Utils/NodeJsonConverterTest.cs b/Contentstack.Management.Core.Unit.Tests/Utils/NodeJsonConverterTest.cs index c404f9d..c723f11 100644 --- a/Contentstack.Management.Core.Unit.Tests/Utils/NodeJsonConverterTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Utils/NodeJsonConverterTest.cs @@ -1,56 +1,45 @@ -using System; using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Text.Json; using Contentstack.Management.Core.Models; using Contentstack.Management.Core.Utils; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Contentstack.Management.Core.Unit.Tests.Utils { [TestClass] public class NodeJsonConverterTest { - private JsonSerializer _serializer; + private JsonSerializerOptions _options; [TestInitialize] public void Setup() { - _serializer = new JsonSerializer(); + _options = new JsonSerializerOptions(); + _options.Converters.Add(new NodeJsonConverter()); + _options.Converters.Add(new TextNodeJsonConverter()); } [TestMethod] - public void NodeJsonConverter_ReadJson_WithTypeProperty_ShouldCreateNode() + public void NodeJsonConverter_Read_WithTypeProperty_ShouldCreateNode() { - var json = @"{ - ""type"": ""paragraph"", - ""attrs"": { ""class"": ""test-class"" }, - ""children"": [] - }"; - var reader = new JsonTextReader(new System.IO.StringReader(json)); - var converter = new NodeJsonConverter(); + var json = @"{""type"":""paragraph"",""attrs"":{""class"":""test-class""},""children"":[]}"; - var result = converter.ReadJson(reader, typeof(Node), null, false, _serializer); + var result = JsonSerializer.Deserialize(json, _options); Assert.IsNotNull(result); Assert.IsInstanceOfType(result, typeof(Node)); Assert.AreEqual("paragraph", result.type); Assert.IsNotNull(result.attrs); - Assert.AreEqual("test-class", result.attrs["class"]); + Assert.AreEqual("test-class", result.attrs["class"].ToString()); Assert.IsNotNull(result.children); } [TestMethod] - public void NodeJsonConverter_ReadJson_WithoutTypeProperty_ShouldCreateTextNode() + public void NodeJsonConverter_Read_WithoutTypeProperty_ShouldCreateTextNode() { - var json = @"{ - ""text"": ""Hello World"", - ""bold"": true - }"; - var reader = new JsonTextReader(new System.IO.StringReader(json)); - var converter = new NodeJsonConverter(); + var json = @"{""text"":""Hello World"",""bold"":true}"; - var result = converter.ReadJson(reader, typeof(Node), null, false, _serializer); + var result = JsonSerializer.Deserialize(json, _options); Assert.IsNotNull(result); Assert.IsInstanceOfType(result, typeof(TextNode)); @@ -58,7 +47,7 @@ public void NodeJsonConverter_ReadJson_WithoutTypeProperty_ShouldCreateTextNode( } [TestMethod] - public void NodeJsonConverter_WriteJson_WithNode_ShouldWriteCorrectJson() + public void NodeJsonConverter_Write_WithNode_ShouldWriteCorrectJson() { var node = new Node { @@ -66,20 +55,16 @@ public void NodeJsonConverter_WriteJson_WithNode_ShouldWriteCorrectJson() attrs = new Dictionary { { "class", "test-class" } }, children = new List() }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new NodeJsonConverter(); - converter.WriteJson(writer, node, _serializer); + var result = JsonSerializer.Serialize(node, _options); - var result = stringWriter.ToString(); Assert.IsTrue(result.Contains("\"type\":\"paragraph\"")); Assert.IsTrue(result.Contains("\"attrs\"")); Assert.IsTrue(result.Contains("\"children\"")); } [TestMethod] - public void NodeJsonConverter_WriteJson_WithNullAttrs_ShouldNotWriteAttrs() + public void NodeJsonConverter_Write_WithNullAttrs_ShouldNotWriteAttrs() { var node = new Node { @@ -87,19 +72,15 @@ public void NodeJsonConverter_WriteJson_WithNullAttrs_ShouldNotWriteAttrs() attrs = null, children = new List() }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new NodeJsonConverter(); - converter.WriteJson(writer, node, _serializer); + var result = JsonSerializer.Serialize(node, _options); - var result = stringWriter.ToString(); Assert.IsTrue(result.Contains("\"type\":\"paragraph\"")); Assert.IsFalse(result.Contains("\"attrs\"")); } [TestMethod] - public void NodeJsonConverter_WriteJson_WithNullChildren_ShouldNotWriteChildren() + public void NodeJsonConverter_Write_WithNullChildren_ShouldNotWriteChildren() { var node = new Node { @@ -107,19 +88,15 @@ public void NodeJsonConverter_WriteJson_WithNullChildren_ShouldNotWriteChildren( attrs = new Dictionary(), children = null }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new NodeJsonConverter(); - converter.WriteJson(writer, node, _serializer); + var result = JsonSerializer.Serialize(node, _options); - var result = stringWriter.ToString(); Assert.IsTrue(result.Contains("\"type\":\"paragraph\"")); Assert.IsFalse(result.Contains("\"children\"")); } [TestMethod] - public void NodeJsonConverter_WriteJson_WithChildren_ShouldWriteChildrenArray() + public void NodeJsonConverter_Write_WithChildren_ShouldWriteChildrenArray() { var childNode = new Node { type = "text" }; var node = new Node @@ -128,13 +105,9 @@ public void NodeJsonConverter_WriteJson_WithChildren_ShouldWriteChildrenArray() attrs = new Dictionary(), children = new List { childNode } }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new NodeJsonConverter(); - converter.WriteJson(writer, node, _serializer); + var result = JsonSerializer.Serialize(node, _options); - var result = stringWriter.ToString(); Assert.IsTrue(result.Contains("\"children\"")); Assert.IsTrue(result.Contains("[")); Assert.IsTrue(result.Contains("]")); diff --git a/Contentstack.Management.Core.Unit.Tests/Utils/TextNodeJsonConverterTest.cs b/Contentstack.Management.Core.Unit.Tests/Utils/TextNodeJsonConverterTest.cs index 4b32022..a90209c 100644 --- a/Contentstack.Management.Core.Unit.Tests/Utils/TextNodeJsonConverterTest.cs +++ b/Contentstack.Management.Core.Unit.Tests/Utils/TextNodeJsonConverterTest.cs @@ -1,42 +1,30 @@ -using System; using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Text.Json; using Contentstack.Management.Core.Models; using Contentstack.Management.Core.Utils; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Contentstack.Management.Core.Unit.Tests.Utils { [TestClass] public class TextNodeJsonConverterTest { - private JsonSerializer _serializer; + private JsonSerializerOptions _options; [TestInitialize] public void Setup() { - _serializer = new JsonSerializer(); + _options = new JsonSerializerOptions(); + _options.Converters.Add(new TextNodeJsonConverter()); + _options.Converters.Add(new NodeJsonConverter()); } [TestMethod] - public void TextNodeJsonConverter_ReadJson_ShouldCreateTextNode() + public void TextNodeJsonConverter_Read_ShouldCreateTextNode() { - var json = @"{ - ""text"": ""Hello World"", - ""bold"": true, - ""italic"": false, - ""underline"": true, - ""strikethrough"": false, - ""inlineCode"": true, - ""subscript"": false, - ""superscript"": true, - ""break"": false - }"; - var reader = new JsonTextReader(new System.IO.StringReader(json)); - var converter = new TextNodeJsonConverter(); - - var result = converter.ReadJson(reader, typeof(TextNode), null, false, _serializer); + var json = @"{""text"":""Hello World"",""bold"":true,""italic"":false,""underline"":true,""strikethrough"":false,""inlineCode"":true,""subscript"":false,""superscript"":true,""break"":false}"; + + var result = JsonSerializer.Deserialize(json, _options); Assert.IsNotNull(result); Assert.IsInstanceOfType(result, typeof(TextNode)); @@ -52,7 +40,7 @@ public void TextNodeJsonConverter_ReadJson_ShouldCreateTextNode() } [TestMethod] - public void TextNodeJsonConverter_WriteJson_WithAllProperties_ShouldWriteCorrectJson() + public void TextNodeJsonConverter_Write_WithAllProperties_ShouldWriteCorrectJson() { var textNode = new TextNode { @@ -68,28 +56,20 @@ public void TextNodeJsonConverter_WriteJson_WithAllProperties_ShouldWriteCorrect attrs = new Dictionary { { "class", "test-class" } }, children = new List() }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new TextNodeJsonConverter(); - converter.WriteJson(writer, textNode, _serializer); + var result = JsonSerializer.Serialize(textNode, _options); - var result = stringWriter.ToString(); Assert.IsTrue(result.Contains("\"text\":\"Hello World\"")); Assert.IsTrue(result.Contains("\"bold\":true")); - // italic is false, so it won't be written by the converter Assert.IsTrue(result.Contains("\"underline\":true")); - // strikethrough is false, so it won't be written by the converter Assert.IsTrue(result.Contains("\"inlineCode\":true")); - // subscript is false, so it won't be written by the converter Assert.IsTrue(result.Contains("\"superscript\":true")); - // break is false, so it won't be written by the converter Assert.IsTrue(result.Contains("\"attrs\"")); Assert.IsTrue(result.Contains("\"children\"")); } [TestMethod] - public void TextNodeJsonConverter_WriteJson_WithOnlyText_ShouldWriteOnlyText() + public void TextNodeJsonConverter_Write_WithOnlyText_ShouldWriteOnlyText() { var textNode = new TextNode { @@ -103,13 +83,9 @@ public void TextNodeJsonConverter_WriteJson_WithOnlyText_ShouldWriteOnlyText() superscript = false, @break = false }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new TextNodeJsonConverter(); - converter.WriteJson(writer, textNode, _serializer); + var result = JsonSerializer.Serialize(textNode, _options); - var result = stringWriter.ToString(); Assert.IsTrue(result.Contains("\"text\":\"Simple text\"")); Assert.IsFalse(result.Contains("\"bold\"")); Assert.IsFalse(result.Contains("\"italic\"")); @@ -122,59 +98,37 @@ public void TextNodeJsonConverter_WriteJson_WithOnlyText_ShouldWriteOnlyText() } [TestMethod] - public void TextNodeJsonConverter_WriteJson_WithNullText_ShouldNotWriteText() + public void TextNodeJsonConverter_Write_WithNullText_ShouldNotWriteText() { var textNode = new TextNode { text = null, - bold = true, - italic = false, - underline = false, - strikethrough = false, - inlineCode = false, - subscript = false, - superscript = false, - @break = false + bold = true }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new TextNodeJsonConverter(); - converter.WriteJson(writer, textNode, _serializer); + var result = JsonSerializer.Serialize(textNode, _options); - var result = stringWriter.ToString(); Assert.IsFalse(result.Contains("\"text\"")); Assert.IsTrue(result.Contains("\"bold\":true")); } [TestMethod] - public void TextNodeJsonConverter_WriteJson_WithEmptyText_ShouldNotWriteText() + public void TextNodeJsonConverter_Write_WithEmptyText_ShouldNotWriteText() { var textNode = new TextNode { text = "", - bold = true, - italic = false, - underline = false, - strikethrough = false, - inlineCode = false, - subscript = false, - superscript = false, - @break = false + bold = true }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new TextNodeJsonConverter(); - converter.WriteJson(writer, textNode, _serializer); + var result = JsonSerializer.Serialize(textNode, _options); - var result = stringWriter.ToString(); Assert.IsFalse(result.Contains("\"text\"")); Assert.IsTrue(result.Contains("\"bold\":true")); } [TestMethod] - public void TextNodeJsonConverter_WriteJson_WithNullAttrs_ShouldNotWriteAttrs() + public void TextNodeJsonConverter_Write_WithNullAttrs_ShouldNotWriteAttrs() { var textNode = new TextNode { @@ -182,18 +136,14 @@ public void TextNodeJsonConverter_WriteJson_WithNullAttrs_ShouldNotWriteAttrs() attrs = null, children = new List() }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new TextNodeJsonConverter(); - converter.WriteJson(writer, textNode, _serializer); + var result = JsonSerializer.Serialize(textNode, _options); - var result = stringWriter.ToString(); Assert.IsFalse(result.Contains("\"attrs\"")); } [TestMethod] - public void TextNodeJsonConverter_WriteJson_WithNullChildren_ShouldNotWriteChildren() + public void TextNodeJsonConverter_Write_WithNullChildren_ShouldNotWriteChildren() { var textNode = new TextNode { @@ -201,13 +151,9 @@ public void TextNodeJsonConverter_WriteJson_WithNullChildren_ShouldNotWriteChild attrs = new Dictionary(), children = null }; - var stringWriter = new System.IO.StringWriter(); - var writer = new JsonTextWriter(stringWriter); - var converter = new TextNodeJsonConverter(); - converter.WriteJson(writer, textNode, _serializer); + var result = JsonSerializer.Serialize(textNode, _options); - var result = stringWriter.ToString(); Assert.IsFalse(result.Contains("\"children\"")); } } diff --git a/Contentstack.Management.Core.Unit.Tests/Utils/Utilities.cs b/Contentstack.Management.Core.Unit.Tests/Utils/Utilities.cs index 4dcda88..01595bf 100644 --- a/Contentstack.Management.Core.Unit.Tests/Utils/Utilities.cs +++ b/Contentstack.Management.Core.Unit.Tests/Utils/Utilities.cs @@ -1,19 +1,19 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using Newtonsoft.Json; using System.Net.Http; using System.Reflection; -using System.Collections.Generic; +using System.Text; +using System.Text.Json; namespace Contentstack.Management.Core.Unit.Tests.Utils { public class Utilities { - public static JsonSerializer GetJsonSerializer() + public static JsonSerializerOptions GetJsonSerializer() { - return JsonSerializer.Create(new JsonSerializerSettings()); + return new JsonSerializerOptions(); } public static string GetResourceText(string resourceName) diff --git a/Contentstack.Management.Core/Abstractions/IExtensionInterface.cs b/Contentstack.Management.Core/Abstractions/IExtensionInterface.cs index c1411c3..cf23781 100644 --- a/Contentstack.Management.Core/Abstractions/IExtensionInterface.cs +++ b/Contentstack.Management.Core/Abstractions/IExtensionInterface.cs @@ -3,6 +3,6 @@ public interface IExtensionInterface : IUploadInterface { string Title { get; set; } - string Tags { get; set; } + string? Tags { get; set; } } } diff --git a/Contentstack.Management.Core/ContentstackClient.cs b/Contentstack.Management.Core/ContentstackClient.cs index 2d152fc..32caf7e 100644 --- a/Contentstack.Management.Core/ContentstackClient.cs +++ b/Contentstack.Management.Core/ContentstackClient.cs @@ -39,7 +39,8 @@ public class ContentstackClient : IContentstackClient private string xUserAgent => $"contentstack-management-dotnet/{Version}"; // OAuth token storage - // private readonly Dictionary _oauthTokens = new Dictionary(); + private readonly Dictionary _oauthTokens = new Dictionary(); + private bool _isRefreshingToken = false; #endregion @@ -202,6 +203,7 @@ protected void Initialize(HttpClient? httpClient = null) SerializerOptions.Converters.Add(new FieldJsonConverter()); // Re-enabled for ContentType support SerializerOptions.Converters.Add(new NodeJsonConverter()); SerializerOptions.Converters.Add(new TextNodeJsonConverter()); + SerializerOptions.Converters.Add(new RuleJsonConverter()); } protected void BuildPipeline() @@ -251,13 +253,11 @@ internal async Task InvokeAsync(TRequest request { ThrowIfDisposed(); - /* // Check and refresh OAuth tokens if needed before making API calls if (contentstackOptions.IsOAuthToken && !string.IsNullOrEmpty(contentstackOptions.Authtoken)) { await EnsureOAuthTokenIsValidAsync(); } - */ ExecutionContext context = new ExecutionContext( new RequestContext() @@ -460,7 +460,6 @@ public Task LogoutAsync(string? authtoken = null) } #endregion - /* #region OAuth Methods /// /// Creates an OAuth handler for OAuth 2.0 authentication flow. @@ -493,9 +492,7 @@ public OAuthHandler OAuth(OAuthOptions options) return new OAuthHandler(this, options); } - */ - /* /// /// Creates an OAuth handler with default OAuth options. /// Uses the default AppId, ClientId, and RedirectUri. @@ -504,7 +501,7 @@ public OAuthHandler OAuth(OAuthOptions options) ///

         /// ContentstackClient client = new ContentstackClient();
         /// OAuthHandler oauthHandler = client.OAuth();
-        /// 
+        ///
         /// // Get authorization URL with default options
         /// string authUrl = oauthHandler.GetAuthorizationUrl();
         /// 
@@ -515,9 +512,7 @@ public OAuthHandler OAuth() var defaultOptions = new OAuthOptions(); return new OAuthHandler(this, defaultOptions); } - */ - /* /// /// Sets OAuth tokens for the client to use for authenticated requests. /// This method is called internally by the OAuthHandler after successful token exchange or refresh. @@ -586,7 +581,7 @@ public bool HasValidOAuthTokens(string clientId) /// This method should be called when logging out or switching authentication methods. /// /// The OAuth client ID to clear tokens for. - public void ClearOAuthTokens(string clientId = null) + public void ClearOAuthTokens(string? clientId = null) { if (!string.IsNullOrEmpty(clientId)) { @@ -669,7 +664,6 @@ internal void ClearAllOAuthTokens() _oauthTokens.Clear(); } #endregion - */ /// /// The Get user call returns comprehensive information of an existing user account. @@ -709,7 +703,6 @@ public Task GetUserAsync(ParameterCollection? collection = return InvokeAsync(getUser); } - /* /// /// Ensures that the current OAuth token is valid and refreshes it if needed. /// This method is called before each API request to automatically handle token refresh. @@ -777,7 +770,6 @@ private async Task EnsureOAuthTokenIsValidAsync() $"OAuth token validation failed: {ex.Message}", ex); } } - */ } } diff --git a/Contentstack.Management.Core/ContentstackResponse.cs b/Contentstack.Management.Core/ContentstackResponse.cs index 5d192c4..f68c33c 100644 --- a/Contentstack.Management.Core/ContentstackResponse.cs +++ b/Contentstack.Management.Core/ContentstackResponse.cs @@ -6,7 +6,6 @@ using System.Net.Http.Headers; using System.Text.Json; using System.Text.Json.Nodes; -using Newtonsoft.Json.Linq; namespace Contentstack.Management.Core { @@ -154,17 +153,6 @@ public JsonObject OpenJsonObjectResponse() return JsonNode.Parse(OpenResponse())!.AsObject(); } - /// - /// Backward compatibility method for non-migrated models. Will be removed in future versions. - /// - /// The JObject (Newtonsoft.Json). - [Obsolete("Use OpenJsonObjectResponse() instead. This method will be removed in future versions.")] - public JObject OpenJObjectResponse() - { - ThrowIfDisposed(); - return JObject.Parse(OpenResponse()); - } - /// /// String format response. /// diff --git a/Contentstack.Management.Core/IResponse.cs b/Contentstack.Management.Core/IResponse.cs index bb80386..5a0ac54 100644 --- a/Contentstack.Management.Core/IResponse.cs +++ b/Contentstack.Management.Core/IResponse.cs @@ -1,7 +1,5 @@ -using System; using System.Net; using System.Text.Json.Nodes; -using Newtonsoft.Json.Linq; namespace Contentstack.Management.Core { @@ -22,12 +20,6 @@ public interface IResponse JsonObject OpenJsonObjectResponse(); - /// - /// Backward compatibility method for non-migrated models. Will be removed in future versions. - /// - [Obsolete("Use OpenJsonObjectResponse() instead. This method will be removed in future versions.")] - JObject OpenJObjectResponse(); - TResponse? OpenTResponse(); } } diff --git a/Contentstack.Management.Core/Models/AuditLog.cs b/Contentstack.Management.Core/Models/AuditLog.cs index 1e2d082..9b68b57 100644 --- a/Contentstack.Management.Core/Models/AuditLog.cs +++ b/Contentstack.Management.Core/Models/AuditLog.cs @@ -9,11 +9,11 @@ namespace Contentstack.Management.Core.Models public class AuditLog { internal Stack stack; - public string Uid { get; set; } + public string? Uid { get; set; } internal string resourcePath; - internal AuditLog(Stack stack, string uid = null) + internal AuditLog(Stack stack, string? uid = null) { stack.ThrowIfAPIKeyEmpty(); @@ -33,12 +33,12 @@ internal AuditLog(Stack stack, string uid = null) /// /// /// The . - public virtual ContentstackResponse FindAll(ParameterCollection collection = null) + public virtual ContentstackResponse FindAll(ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidNotEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, collection: collection); + var service = new FetchDeleteService(stack, resourcePath, collection: collection); return stack.client.InvokeSync(service); } @@ -53,12 +53,12 @@ public virtual ContentstackResponse FindAll(ParameterCollection collection = nul /// /// /// The . - public virtual Task FindAllAsync(ParameterCollection collection = null) + public virtual Task FindAllAsync(ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidNotEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, collection: collection); + var service = new FetchDeleteService(stack, resourcePath, collection: collection); return stack.client.InvokeAsync(service); } @@ -73,12 +73,12 @@ public virtual Task FindAllAsync(ParameterCollection colle /// /// /// The . - public virtual ContentstackResponse Fetch(ParameterCollection collection = null) + public virtual ContentstackResponse Fetch(ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, collection: collection); + var service = new FetchDeleteService(stack, resourcePath, collection: collection); return stack.client.InvokeSync(service); } @@ -93,12 +93,12 @@ public virtual ContentstackResponse Fetch(ParameterCollection collection = null) /// /// /// The . - public virtual Task FetchAsync(ParameterCollection collection = null) + public virtual Task FetchAsync(ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, collection: collection); + var service = new FetchDeleteService(stack, resourcePath, collection: collection); return stack.client.InvokeAsync(service); } diff --git a/Contentstack.Management.Core/Models/CustomExtension/CustomFieldModel.cs b/Contentstack.Management.Core/Models/CustomExtension/CustomFieldModel.cs index e39c5fe..b445a0c 100644 --- a/Contentstack.Management.Core/Models/CustomExtension/CustomFieldModel.cs +++ b/Contentstack.Management.Core/Models/CustomExtension/CustomFieldModel.cs @@ -10,25 +10,25 @@ public class CustomFieldModel : IExtensionInterface { public string Title { get; set; } public string DataType { get; set; } - public string Tags { get; set; } + public string? Tags { get; set; } public bool Multiple { get; set; } public string ContentType { get; set; } internal ByteArrayContent byteArray; - public CustomFieldModel(string filePath, string contentType, string title, string dataType, bool isMultiple = false, string tags = null) : + public CustomFieldModel(string filePath, string contentType, string title, string dataType, bool isMultiple = false, string? tags = null) : this(File.OpenRead(filePath), contentType, title, dataType, isMultiple, tags) { } - public CustomFieldModel(Stream stream, string contentType, string title, string dataType, bool isMultiple = false, string tags = null) : + public CustomFieldModel(Stream stream, string contentType, string title, string dataType, bool isMultiple = false, string? tags = null) : this(getBytes(stream), contentType, title, dataType, isMultiple, tags) { } - public CustomFieldModel(byte[] bytes, string contentType, string title, string dataType, bool isMultiple = false, string tags = null) : + public CustomFieldModel(byte[] bytes, string contentType, string title, string dataType, bool isMultiple = false, string? tags = null) : this(getByteArray(bytes), contentType, title, dataType, isMultiple, tags) { } - public CustomFieldModel(ByteArrayContent byteArray, string contentType, string title, string dataType, bool isMultiple = false, string tags = null) + public CustomFieldModel(ByteArrayContent byteArray, string contentType, string title, string dataType, bool isMultiple = false, string? tags = null) { if (byteArray == null) diff --git a/Contentstack.Management.Core/Models/CustomExtension/CustomWidgetModel.cs b/Contentstack.Management.Core/Models/CustomExtension/CustomWidgetModel.cs index 6b6753f..b9684f0 100644 --- a/Contentstack.Management.Core/Models/CustomExtension/CustomWidgetModel.cs +++ b/Contentstack.Management.Core/Models/CustomExtension/CustomWidgetModel.cs @@ -1,36 +1,35 @@ using System; -using System.Globalization; using System.IO; using System.Net.Http; using System.Net.Http.Headers; +using System.Text.Json; using Contentstack.Management.Core.Abstractions; using Contentstack.Management.Core.Utils; -using Newtonsoft.Json; namespace Contentstack.Management.Core.Models.CustomExtension { public class CustomWidgetModel : IExtensionInterface { public string Title { get; set; } - public string Tags { get; set; } - public ExtensionScope Scope { get; set; } + public string? Tags { get; set; } + public ExtensionScope? Scope { get; set; } public string ContentType { get; set; } internal ByteArrayContent byteArray; - public CustomWidgetModel(string filePath, string contentType, string title, string tags = null, ExtensionScope scope = null) : + public CustomWidgetModel(string filePath, string contentType, string title, string? tags = null, ExtensionScope? scope = null) : this(File.OpenRead(filePath), contentType, title, tags, scope) { } - public CustomWidgetModel(Stream stream, string contentType, string title, string tags = null, ExtensionScope scope = null) : + public CustomWidgetModel(Stream stream, string contentType, string title, string? tags = null, ExtensionScope? scope = null) : this(getBytes(stream), contentType, title, tags, scope) { } - public CustomWidgetModel(byte[] bytes, string contentType, string title, string tags = null, ExtensionScope scope = null) : + public CustomWidgetModel(byte[] bytes, string contentType, string title, string? tags = null, ExtensionScope? scope = null) : this(getByteArray(bytes), contentType, title, tags, scope) { } - public CustomWidgetModel(ByteArrayContent byteArray, string contentType, string title, string tags = null, ExtensionScope scope = null) + public CustomWidgetModel(ByteArrayContent byteArray, string contentType, string title, string? tags = null, ExtensionScope? scope = null) { if (byteArray == null) { @@ -74,18 +73,11 @@ public HttpContent GetHttpContent() } if (Scope != null) { - using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture)) - { - JsonWriter writer = new JsonTextWriter(stringWriter); - - JsonSerializer.Create().Serialize(writer, Scope); - string snippet = stringWriter.ToString(); - StringContent jsonPart = new StringContent(snippet); - jsonPart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); - jsonPart.Headers.ContentType = new MediaTypeHeaderValue("application/json"); - - content.Add(jsonPart, "extension[scope]", snippet); - } + string snippet = JsonSerializer.Serialize(Scope); + StringContent jsonPart = new StringContent(snippet); + jsonPart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data"); + jsonPart.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + content.Add(jsonPart, "extension[scope]", snippet); } content.Add(new StringContent("widget"), "extension[type]"); return content; diff --git a/Contentstack.Management.Core/Models/CustomExtension/DashboardWidgetModel.cs b/Contentstack.Management.Core/Models/CustomExtension/DashboardWidgetModel.cs index b75c43b..450b168 100644 --- a/Contentstack.Management.Core/Models/CustomExtension/DashboardWidgetModel.cs +++ b/Contentstack.Management.Core/Models/CustomExtension/DashboardWidgetModel.cs @@ -9,26 +9,26 @@ namespace Contentstack.Management.Core.Models.CustomExtension public class DashboardWidgetModel : IExtensionInterface { public string Title { get; set; } - public string Tags { get; set; } + public string? Tags { get; set; } public string ContentType { get; set; } - public string DefaultWidth { get; set; } + public string? DefaultWidth { get; set; } public bool Enable { get; set; } internal ByteArrayContent byteArray; - public DashboardWidgetModel(string filePath, string contentType, string title, bool isEnable = false, string defaultWidth = null, string tags = null) : + public DashboardWidgetModel(string filePath, string contentType, string title, bool isEnable = false, string? defaultWidth = null, string? tags = null) : this(File.OpenRead(filePath), contentType, title, isEnable, defaultWidth, tags) { } - public DashboardWidgetModel(Stream stream, string contentType, string title, bool isEnable = false, string defaultWidth = null, string tags = null) : + public DashboardWidgetModel(Stream stream, string contentType, string title, bool isEnable = false, string? defaultWidth = null, string? tags = null) : this(getBytes(stream), contentType, title, isEnable, defaultWidth, tags) { } - public DashboardWidgetModel(byte[] bytes, string contentType, string title, bool isEnable = false, string defaultWidth = null, string tags = null) : + public DashboardWidgetModel(byte[] bytes, string contentType, string title, bool isEnable = false, string? defaultWidth = null, string? tags = null) : this(getByteArray(bytes), contentType, title, isEnable, defaultWidth, tags) { } - public DashboardWidgetModel(ByteArrayContent byteArray, string contentType, string title, bool isEnable = false, string defaultWidth = null, string tags = null) + public DashboardWidgetModel(ByteArrayContent byteArray, string contentType, string title, bool isEnable = false, string? defaultWidth = null, string? tags = null) { if (byteArray == null) diff --git a/Contentstack.Management.Core/Models/Extension.cs b/Contentstack.Management.Core/Models/Extension.cs index 7364ebf..8066147 100644 --- a/Contentstack.Management.Core/Models/Extension.cs +++ b/Contentstack.Management.Core/Models/Extension.cs @@ -10,11 +10,11 @@ namespace Contentstack.Management.Core.Models public class Extension { internal Stack stack; - public string Uid { get; set; } + public string? Uid { get; set; } internal string resourcePath; - internal Extension(Stack stack, string uid = null) + internal Extension(Stack stack, string? uid = null) { stack.ThrowIfAPIKeyEmpty(); @@ -55,7 +55,7 @@ public virtual ContentstackResponse Upload(IExtensionInterface model) { ThrowIfUidNotEmpty(); - var service = new UploadService(stack.client.serializer, stack, resourcePath, model); + var service = new UploadService(stack, resourcePath, model); return stack.client.InvokeSync(service); } @@ -76,7 +76,7 @@ public virtual Task UploadAsync(IExtensionInterface model) ThrowIfUidNotEmpty(); stack.ThrowIfNotLoggedIn(); - var service = new UploadService(stack.client.serializer, stack, resourcePath, model); + var service = new UploadService(stack, resourcePath, model); return stack.client.InvokeAsync(service); } @@ -96,7 +96,7 @@ public virtual ContentstackResponse Create(ExtensionModel model) { ThrowIfUidNotEmpty(); - var service = new CreateUpdateService(stack.client.serializer, stack, resourcePath, model, "extension"); + var service = new CreateUpdateService(stack, resourcePath, model, "extension"); return stack.client.InvokeSync(service); } @@ -117,7 +117,7 @@ public virtual Task CreateAsync(ExtensionModel model) ThrowIfUidNotEmpty(); stack.ThrowIfNotLoggedIn(); - var service = new CreateUpdateService(stack.client.serializer, stack, resourcePath, model, "extension"); + var service = new CreateUpdateService(stack, resourcePath, model, "extension"); return stack.client.InvokeAsync, ContentstackResponse>(service); } @@ -137,7 +137,7 @@ public virtual ContentstackResponse Update(ExtensionModel model) { ThrowIfUidEmpty(); - var service = new CreateUpdateService(stack.client.serializer, stack, resourcePath, model, "extension", "PUT"); + var service = new CreateUpdateService(stack, resourcePath, model, "extension", "PUT"); return stack.client.InvokeSync(service); } @@ -153,12 +153,12 @@ public virtual ContentstackResponse Update(ExtensionModel model) /// /// /// The . - public virtual Task UpdateAsync(ExtensionModel model, ParameterCollection collection = null) + public virtual Task UpdateAsync(ExtensionModel model, ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new CreateUpdateService(stack.client.serializer, stack, resourcePath, model, "extension", "PUT"); + var service = new CreateUpdateService(stack, resourcePath, model, "extension", "PUT"); return stack.client.InvokeAsync, ContentstackResponse>(service); } @@ -173,12 +173,12 @@ public virtual Task UpdateAsync(ExtensionModel model, Para /// /// /// The . - public virtual ContentstackResponse Fetch(ParameterCollection collection = null) + public virtual ContentstackResponse Fetch(ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, collection: collection); + var service = new FetchDeleteService(stack, resourcePath, collection: collection); return stack.client.InvokeSync(service); } @@ -193,12 +193,12 @@ public virtual ContentstackResponse Fetch(ParameterCollection collection = null) /// /// /// The . - public virtual Task FetchAsync(ParameterCollection collection = null) + public virtual Task FetchAsync(ParameterCollection? collection = null) { stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, collection: collection); + var service = new FetchDeleteService(stack, resourcePath, collection: collection); return stack.client.InvokeAsync(service); } @@ -218,7 +218,7 @@ public virtual ContentstackResponse Delete() stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, "DELETE"); + var service = new FetchDeleteService(stack, resourcePath, "DELETE"); return stack.client.InvokeSync(service); } @@ -238,7 +238,7 @@ public virtual Task DeleteAsync() stack.ThrowIfNotLoggedIn(); ThrowIfUidEmpty(); - var service = new FetchDeleteService(stack.client.serializer, stack, resourcePath, "DELETE"); + var service = new FetchDeleteService(stack, resourcePath, "DELETE"); return stack.client.InvokeAsync(service); } #region Throw Error diff --git a/Contentstack.Management.Core/Models/ExtensionModel.cs b/Contentstack.Management.Core/Models/ExtensionModel.cs index 51f7a15..11df489 100644 --- a/Contentstack.Management.Core/Models/ExtensionModel.cs +++ b/Contentstack.Management.Core/Models/ExtensionModel.cs @@ -1,34 +1,33 @@ -using Newtonsoft.Json; -using System.Collections.Generic; +using System.Collections.Generic; +using System.Text.Json.Serialization; namespace Contentstack.Management.Core.Models { - [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] public class ExtensionModel { - [JsonProperty(propertyName: "title")] + [JsonPropertyName("title")] public string? Title { get; set; } - [JsonProperty(propertyName: "data_type")] + [JsonPropertyName("data_type")] public string? DataType { get; set; } - [JsonProperty(propertyName: "tags")] + [JsonPropertyName("tags")] public List? Tags { get; set; } - [JsonProperty(propertyName: "src")] + [JsonPropertyName("src")] public string? Src { get; set; } - [JsonProperty(propertyName: "srcdoc")] + [JsonPropertyName("srcdoc")] public string? Srcdoc { get; set; } - [JsonProperty(propertyName: "type")] + [JsonPropertyName("type")] public string? Type { get; set; } - [JsonProperty(propertyName: "config")] + [JsonPropertyName("config")] public string? Config { get; set; } - [JsonProperty(propertyName: "multiple")] + [JsonPropertyName("multiple")] public bool Multiple { get; set; } - [JsonProperty(propertyName: "scope")] + [JsonPropertyName("scope")] public ExtensionScope? Scope { get; set; } } public class ExtensionScope { - [JsonProperty(propertyName: "content_types")] + [JsonPropertyName("content_types")] public List? ContentTypes { get; set; } } } diff --git a/Contentstack.Management.Core/Models/LabelModel.cs b/Contentstack.Management.Core/Models/LabelModel.cs index 0a5f372..7db530a 100644 --- a/Contentstack.Management.Core/Models/LabelModel.cs +++ b/Contentstack.Management.Core/Models/LabelModel.cs @@ -1,16 +1,15 @@ using System.Collections.Generic; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Contentstack.Management.Core.Models { - [JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] public class LabelModel { - [JsonProperty(propertyName: "name")] + [JsonPropertyName("name")] public string? Name { get; set; } - [JsonProperty(propertyName: "parent")] + [JsonPropertyName("parent")] public List? Parent { get; set; } - [JsonProperty(propertyName: "content_types")] + [JsonPropertyName("content_types")] public List? ContentTypes { get; set; } } } diff --git a/Contentstack.Management.Core/Models/OAuthAppAuthorizationResponse.cs b/Contentstack.Management.Core/Models/OAuthAppAuthorizationResponse.cs index e8fa02d..17a1454 100644 --- a/Contentstack.Management.Core/Models/OAuthAppAuthorizationResponse.cs +++ b/Contentstack.Management.Core/Models/OAuthAppAuthorizationResponse.cs @@ -1,5 +1,4 @@ -using System; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Contentstack.Management.Core.Models { @@ -8,8 +7,7 @@ namespace Contentstack.Management.Core.Models /// public class OAuthAppAuthorizationResponse { - - [JsonProperty("data")] + [JsonPropertyName("data")] public OAuthAppAuthorizationData[]? Data { get; set; } } @@ -18,20 +16,16 @@ public class OAuthAppAuthorizationResponse /// public class OAuthAppAuthorizationData { - - [JsonProperty("authorization_uid")] + [JsonPropertyName("authorization_uid")] public string? AuthorizationUid { get; set; } - - [JsonProperty("user")] + [JsonPropertyName("user")] public OAuthUser? User { get; set; } } - public class OAuthUser { - - [JsonProperty("uid")] + [JsonPropertyName("uid")] public string? Uid { get; set; } } } diff --git a/Contentstack.Management.Core/Models/OAuthResponse.cs b/Contentstack.Management.Core/Models/OAuthResponse.cs index 5d5b1a0..187172c 100644 --- a/Contentstack.Management.Core/Models/OAuthResponse.cs +++ b/Contentstack.Management.Core/Models/OAuthResponse.cs @@ -1,5 +1,4 @@ -using System; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Contentstack.Management.Core.Models { @@ -8,24 +7,19 @@ namespace Contentstack.Management.Core.Models ///
public class OAuthResponse { - - [JsonProperty("access_token")] + [JsonPropertyName("access_token")] public string? AccessToken { get; set; } - - [JsonProperty("refresh_token")] + [JsonPropertyName("refresh_token")] public string? RefreshToken { get; set; } - - [JsonProperty("expires_in")] + [JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } - - [JsonProperty("organization_uid")] + [JsonPropertyName("organization_uid")] public string? OrganizationUid { get; set; } - - [JsonProperty("user_uid")] + [JsonPropertyName("user_uid")] public string? UserUid { get; set; } } } diff --git a/Contentstack.Management.Core/Models/RoleModel.cs b/Contentstack.Management.Core/Models/RoleModel.cs index f8c3de1..9e657b2 100644 --- a/Contentstack.Management.Core/Models/RoleModel.cs +++ b/Contentstack.Management.Core/Models/RoleModel.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Text.Json.Serialization; + namespace Contentstack.Management.Core.Models { public class RoleModel @@ -26,7 +27,7 @@ public class Rule public bool Restrict { get; } } - public class ContentTypeRules: Rule + public class ContentTypeRules : Rule { [JsonPropertyName("module")] public string Module { get; } = "content_type"; diff --git a/Contentstack.Management.Core/Models/Stack.cs b/Contentstack.Management.Core/Models/Stack.cs index 12d0352..18750a4 100644 --- a/Contentstack.Management.Core/Models/Stack.cs +++ b/Contentstack.Management.Core/Models/Stack.cs @@ -663,7 +663,6 @@ public GlobalField GlobalField(string? uid = null, string? apiVersion = null) return new GlobalField(this, uid, apiVersion); } - /* /// /// let you create custom fields and custom widgets that lets you customize Contentstack's default UI and behavior. /// @@ -676,7 +675,7 @@ public GlobalField GlobalField(string? uid = null, string? apiVersion = null) /// /// /// The - public Extension Extension(string uid = null) + public Extension Extension(string? uid = null) { ThrowIfNotLoggedIn(); ThrowIfAPIKeyEmpty(); @@ -696,14 +695,13 @@ public Extension Extension(string uid = null) /// /// /// The - public Label Label(string uid = null) + public Label Label(string? uid = null) { ThrowIfNotLoggedIn(); ThrowIfAPIKeyEmpty(); return new Label(this, uid); } - */ /// /// allows you to organize and categorize content using a hierarchical structure of terms. @@ -919,15 +917,13 @@ public Webhook Webhook(string? uid = null) /// /// /// The - /* - public AuditLog AuditLog(string uid = null) + public AuditLog AuditLog(string? uid = null) { ThrowIfNotLoggedIn(); ThrowIfAPIKeyEmpty(); return new AuditLog(this, uid); } - */ /// /// A allows you to manage variant groups and their associated content types. diff --git a/Contentstack.Management.Core/Queryable/ParameterCollection.cs b/Contentstack.Management.Core/Queryable/ParameterCollection.cs index 1d701d9..b54a1ef 100644 --- a/Contentstack.Management.Core/Queryable/ParameterCollection.cs +++ b/Contentstack.Management.Core/Queryable/ParameterCollection.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Text.Json.Nodes; using Contentstack.Management.Core.Exceptions; using Contentstack.Management.Core.Utils; -using Newtonsoft.Json.Linq; namespace Contentstack.Management.Core.Queryable { @@ -66,9 +66,9 @@ public void Add(string key, List values) /// Adds a parameter with a queryObj value. /// /// - public void AddQuery(JObject queryObj) + public void AddQuery(JsonNode queryObj) { - Add("query", new StringParameterValue(Uri.EscapeDataString(queryObj.ToString()))); + Add("query", new StringParameterValue(Uri.EscapeDataString(queryObj.ToJsonString()))); } /// @@ -99,7 +99,7 @@ private IEnumerable> GetParametersEnumerable() yield return new KeyValuePair(name, stringParameterValue.Value); break; case JObjectParameterValue jObjectParameterValue: - yield return new KeyValuePair(name, jObjectParameterValue.Value.ToString()); + yield return new KeyValuePair(name, jObjectParameterValue.Value.ToJsonString()); break; case StringListParameterValue stringListParameterValue: var sortedStringListParameterValue = stringListParameterValue.Value; diff --git a/Contentstack.Management.Core/Queryable/QueryParamValue.cs b/Contentstack.Management.Core/Queryable/QueryParamValue.cs index 05f15c5..456bf5a 100644 --- a/Contentstack.Management.Core/Queryable/QueryParamValue.cs +++ b/Contentstack.Management.Core/Queryable/QueryParamValue.cs @@ -1,6 +1,5 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.Text.Json.Nodes; namespace Contentstack.Management.Core.Queryable { @@ -112,20 +111,20 @@ public DoubleListParameterValue(List values) } /// - /// Double list parameter value. + /// JSON object parameter value. /// public class JObjectParameterValue : QueryParamValue { /// - /// List of doubles value of the parameter. + /// JsonNode value of the parameter. /// - public JObject Value { get; set; } + public JsonNode Value { get; set; } /// - /// Constructs ParameterValue for a list of doubles. + /// Constructs ParameterValue for a JsonNode query object. /// /// - public JObjectParameterValue(JObject values) + public JObjectParameterValue(JsonNode values) { Value = values; } diff --git a/Contentstack.Management.Core/Services/OAuth/OAuthAppAuthorizationService.cs b/Contentstack.Management.Core/Services/OAuth/OAuthAppAuthorizationService.cs index 1570c21..ce2a0d5 100644 --- a/Contentstack.Management.Core/Services/OAuth/OAuthAppAuthorizationService.cs +++ b/Contentstack.Management.Core/Services/OAuth/OAuthAppAuthorizationService.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; +using System.Text.Json; using Contentstack.Management.Core.Models; using Contentstack.Management.Core.Http; @@ -12,7 +12,7 @@ namespace Contentstack.Management.Core.Services.OAuth internal class OAuthAppAuthorizationService : ContentstackService { private readonly string _appId; - private readonly string _organizationUid; + private readonly string? _organizationUid; /// /// Initializes a new instance of the OAuthAppAuthorizationService class. @@ -20,7 +20,7 @@ internal class OAuthAppAuthorizationService : ContentstackService /// The JSON serializer. /// The OAuth app ID. /// The organization UID for OAuth operations. - internal OAuthAppAuthorizationService(JsonSerializer serializer, string appId, string organizationUid = null) + internal OAuthAppAuthorizationService(JsonSerializerOptions serializer, string appId, string? organizationUid = null) : base(serializer) { if (string.IsNullOrEmpty(appId)) @@ -49,7 +49,7 @@ private void InitializeService() /// Whether to add accept media headers. /// The API version to use. /// The HTTP request for OAuth app authorization operations. - public override IHttpRequest CreateHttpRequest(System.Net.Http.HttpClient httpClient, ContentstackClientOptions config, bool addAcceptMediaHeader = false, string apiVersion = null) + public override IHttpRequest CreateHttpRequest(System.Net.Http.HttpClient httpClient, ContentstackClientOptions config, bool addAcceptMediaHeader = false, string? apiVersion = null) { // Create a custom config with Developer Hub hostname for OAuth app authorization operations // OAuth endpoints don't use API versioning, so we set Version to empty diff --git a/Contentstack.Management.Core/Services/OAuth/OAuthAppRevocationService.cs b/Contentstack.Management.Core/Services/OAuth/OAuthAppRevocationService.cs index 3ae5cdb..d8c8386 100644 --- a/Contentstack.Management.Core/Services/OAuth/OAuthAppRevocationService.cs +++ b/Contentstack.Management.Core/Services/OAuth/OAuthAppRevocationService.cs @@ -1,5 +1,5 @@ using System; -using Newtonsoft.Json; +using System.Text.Json; using Contentstack.Management.Core.Http; namespace Contentstack.Management.Core.Services.OAuth @@ -11,7 +11,7 @@ internal class OAuthAppRevocationService : ContentstackService { private readonly string _appId; private readonly string _authorizationId; - private readonly string _organizationUid; + private readonly string? _organizationUid; /// /// Initializes a new instance of the OAuthAppRevocationService class. @@ -20,7 +20,7 @@ internal class OAuthAppRevocationService : ContentstackService /// The OAuth app ID. /// The authorization ID to revoke. /// The organization UID for OAuth operations. - internal OAuthAppRevocationService(JsonSerializer serializer, string appId, string authorizationId, string organizationUid = null) + internal OAuthAppRevocationService(JsonSerializerOptions serializer, string appId, string authorizationId, string? organizationUid = null) : base(serializer) { if (string.IsNullOrEmpty(appId)) @@ -52,7 +52,7 @@ private void InitializeService() /// Whether to add accept media headers. /// The API version to use. /// The HTTP request for OAuth app revocation operations. - public override IHttpRequest CreateHttpRequest(System.Net.Http.HttpClient httpClient, ContentstackClientOptions config, bool addAcceptMediaHeader = false, string apiVersion = null) + public override IHttpRequest CreateHttpRequest(System.Net.Http.HttpClient httpClient, ContentstackClientOptions config, bool addAcceptMediaHeader = false, string? apiVersion = null) { // Create a custom config with Developer Hub hostname for OAuth app revocation operations // OAuth endpoints don't use API versioning, so we set Version to empty diff --git a/Contentstack.Management.Core/Services/OAuth/OAuthTokenService.cs b/Contentstack.Management.Core/Services/OAuth/OAuthTokenService.cs index 533870b..5535414 100644 --- a/Contentstack.Management.Core/Services/OAuth/OAuthTokenService.cs +++ b/Contentstack.Management.Core/Services/OAuth/OAuthTokenService.cs @@ -2,8 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Net; -using Newtonsoft.Json; +using System.Text.Json; using Contentstack.Management.Core.Http; using Contentstack.Management.Core.Models; @@ -29,7 +28,7 @@ internal class OAuthTokenService : ContentstackService /// The JSON serializer to use. /// The request body parameters for the OAuth token request. /// Thrown when serializer or requestBody is null. - internal OAuthTokenService(JsonSerializer serializer, Dictionary requestBody) + internal OAuthTokenService(JsonSerializerOptions serializer, Dictionary requestBody) : base(serializer) { if (requestBody == null) @@ -69,7 +68,7 @@ public override void ContentBody() /// Whether to add accept media headers. /// The API version to use. /// The HTTP request for OAuth token operations. - public override IHttpRequest CreateHttpRequest(System.Net.Http.HttpClient httpClient, ContentstackClientOptions config, bool addAcceptMediaHeader = false, string apiVersion = null) + public override IHttpRequest CreateHttpRequest(System.Net.Http.HttpClient httpClient, ContentstackClientOptions config, bool addAcceptMediaHeader = false, string? apiVersion = null) { // Create a custom config with Developer Hub hostname for OAuth token operations // OAuth token endpoints don't use API versioning, so we set Version to empty @@ -148,12 +147,12 @@ public override void OnResponse(IResponse httpResponse, ContentstackClientOption /// The PKCE code verifier (optional, for PKCE flow). /// An OAuth token service configured for authorization code exchange. public static OAuthTokenService CreateForAuthorizationCode( - JsonSerializer serializer, + JsonSerializerOptions serializer, string authorizationCode, string clientId, string redirectUri, - string clientSecret = null, - string codeVerifier = null) + string? clientSecret = null, + string? codeVerifier = null) { if (string.IsNullOrEmpty(authorizationCode)) throw new ArgumentException("Authorization code cannot be null or empty.", nameof(authorizationCode)); @@ -196,7 +195,7 @@ public static OAuthTokenService CreateForAuthorizationCode( /// The redirect URI used in the original authorization request. /// An OAuth token service configured for token refresh. public static OAuthTokenService CreateForTokenRefresh( - JsonSerializer serializer, + JsonSerializerOptions serializer, string refreshToken, string clientId, string redirectUri) @@ -229,10 +228,10 @@ public static OAuthTokenService CreateForTokenRefresh( /// The OAuth client secret (optional, for traditional OAuth flow). /// An OAuth token service configured for token refresh. public static OAuthTokenService CreateForRefreshToken( - JsonSerializer serializer, + JsonSerializerOptions serializer, string refreshToken, string clientId, - string clientSecret = null) + string? clientSecret = null) { if (string.IsNullOrEmpty(refreshToken)) throw new ArgumentException("Refresh token cannot be null or empty.", nameof(refreshToken)); diff --git a/Contentstack.Management.Core/Utils/RuleJsonConverter.cs b/Contentstack.Management.Core/Utils/RuleJsonConverter.cs new file mode 100644 index 0000000..8f0e048 --- /dev/null +++ b/Contentstack.Management.Core/Utils/RuleJsonConverter.cs @@ -0,0 +1,52 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Contentstack.Management.Core.Models; + +namespace Contentstack.Management.Core.Utils +{ + /// + /// Polymorphic converter for so that derived types + /// (BranchRules, ContentTypeRules, etc.) are serialized with their own + /// properties when stored in a List<Rule>. + /// + /// System.Text.Json only serializes the declared type by default, which + /// drops subclass-only fields like "module" and "branches" from the payload, + /// causing the Management API to return HTTP 422. + /// + /// Register this converter in JsonSerializerOptions.Converters (not via + /// [JsonConverter] attribute) so that WithoutConverter<T>() can remove it + /// during recursive serialization and prevent infinite recursion. + /// + internal class RuleJsonConverter : JsonConverter + { + public override void Write(Utf8JsonWriter writer, Rule value, JsonSerializerOptions options) + { + var opts = options.WithoutConverter(); + JsonSerializer.Serialize(writer, (object)value, value.GetType(), opts); + } + + public override Rule? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + using var doc = JsonDocument.ParseValue(ref reader); + var opts = options.WithoutConverter(); + + if (doc.RootElement.TryGetProperty("module", out var moduleProp)) + { + return moduleProp.GetString() switch + { + "branch" => doc.RootElement.Deserialize(opts), + "branch_alias" => doc.RootElement.Deserialize(opts), + "content_type" => doc.RootElement.Deserialize(opts), + "asset" => doc.RootElement.Deserialize(opts), + "folder" => doc.RootElement.Deserialize(opts), + "environment" => doc.RootElement.Deserialize(opts), + "taxonomy" => doc.RootElement.Deserialize(opts), + _ => doc.RootElement.Deserialize(opts), + }; + } + + return doc.RootElement.Deserialize(opts); + } + } +} diff --git a/Contentstack.Management.Core/contentstack.management.core.csproj b/Contentstack.Management.Core/contentstack.management.core.csproj index e508703..619e855 100644 --- a/Contentstack.Management.Core/contentstack.management.core.csproj +++ b/Contentstack.Management.Core/contentstack.management.core.csproj @@ -66,51 +66,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -123,16 +82,12 @@ - - + - - -