diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c7159c1..3d2ac0b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.2" + ".": "0.1.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 754d90b..ddb1fe8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-86aec85be1021cea51f9fc0bb95248276c8b85e3ac0fd810490114599ed7cf00.yml -openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: 7fca08d9dae18513f5d7451cea11e34c +configured_endpoints: 183 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-5d75bbdcac3a0b0a8b798c0b4ef0dacfbc64ad4a20605489dc46dda7c8d1d8d8.yml +openapi_spec_hash: bb242cfd8cc43354412164c2dceae89c +config_hash: 261e1b852ca7f8364e4a283a3edd350a diff --git a/CHANGELOG.md b/CHANGELOG.md index 7093826..be543db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.1.0 (2026-09-08) + +Full Changelog: [v0.0.2...v0.1.0](https://github.com/zavudev/sdk-csharp/compare/v0.0.2...v0.1.0) + +### Features + +* **api:** api update ([9d9ab4a](https://github.com/zavudev/sdk-csharp/commit/9d9ab4ae87c2113e5f6b5ac15dfd0f92e77d6729)) +* **api:** api update ([e5056d9](https://github.com/zavudev/sdk-csharp/commit/e5056d98cb153e995d446f6db6a2108c650b32f0)) +* **api:** api update ([96ab7f3](https://github.com/zavudev/sdk-csharp/commit/96ab7f3c8699713449314334fb4fd6da77328e45)) +* **api:** api update ([4e858c7](https://github.com/zavudev/sdk-csharp/commit/4e858c781f3fed4c097fd183e7100e7a2fb820f6)) +* **api:** api update ([b4437bc](https://github.com/zavudev/sdk-csharp/commit/b4437bc578ddee38ed35c2b36bfd7c56668ac899)) +* **api:** api update ([158b835](https://github.com/zavudev/sdk-csharp/commit/158b83539d3d2e5ff856370d135046f3c86d648f)) +* **api:** api update ([ab63674](https://github.com/zavudev/sdk-csharp/commit/ab63674d56ece9623457bc26b3e7f7de61dc56af)) +* **api:** api update ([075d0c2](https://github.com/zavudev/sdk-csharp/commit/075d0c247aee199ad08c180fa65925beb52b0f08)) +* **api:** api update ([c89fc7b](https://github.com/zavudev/sdk-csharp/commit/c89fc7b716dc67adaeebc0389d47bee998137f05)) +* **api:** api update ([47de211](https://github.com/zavudev/sdk-csharp/commit/47de211deff2c722fe0158faedbf35690434fcdc)) +* **api:** manual updates ([18aecff](https://github.com/zavudev/sdk-csharp/commit/18aecff0d1bd009748ef781eb2261cc219ed6aef)) + ## 0.0.2 (2026-08-10) Full Changelog: [v0.0.1...v0.0.2](https://github.com/zavudev/sdk-csharp/compare/v0.0.1...v0.0.2) diff --git a/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateListParamsTest.cs b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateListParamsTest.cs new file mode 100644 index 0000000..b6ba8d8 --- /dev/null +++ b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateListParamsTest.cs @@ -0,0 +1 @@ +namespace Zavudev.Tests.Models.AgentTemplates; diff --git a/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateListResponseTest.cs b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateListResponseTest.cs new file mode 100644 index 0000000..c28ba8c --- /dev/null +++ b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateListResponseTest.cs @@ -0,0 +1,347 @@ +using System.Collections.Generic; +using System.Text.Json; +using Zavudev.Core; +using Zavudev.Exceptions; +using Zavudev.Models.AgentTemplates; + +namespace Zavudev.Tests.Models.AgentTemplates; + +public class AgentTemplateListResponseTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new AgentTemplateListResponse + { + Items = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ], + }; + + List expectedItems = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ]; + + Assert.Equal(expectedItems.Count, model.Items.Count); + for (int i = 0; i < expectedItems.Count; i++) + { + Assert.Equal(expectedItems[i], model.Items[i]); + } + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new AgentTemplateListResponse + { + Items = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ], + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new AgentTemplateListResponse + { + Items = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ], + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + List expectedItems = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ]; + + Assert.Equal(expectedItems.Count, deserialized.Items.Count); + for (int i = 0; i < expectedItems.Count; i++) + { + Assert.Equal(expectedItems[i], deserialized.Items[i]); + } + } + + [Fact] + public void Validation_Works() + { + var model = new AgentTemplateListResponse + { + Items = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ], + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new AgentTemplateListResponse + { + Items = + [ + new() + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }, + ], + }; + + AgentTemplateListResponse copied = new(model); + + Assert.Equal(model, copied); + } +} + +public class ItemTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new Item + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }; + + string expectedID = "fermi"; + ApiEnum expectedCategory = ItemCategory.Sales; + string expectedName = "name"; + string expectedSummary = "summary"; + long expectedToolCount = 0; + bool expectedVoice = true; + + Assert.Equal(expectedID, model.ID); + Assert.Equal(expectedCategory, model.Category); + Assert.Equal(expectedName, model.Name); + Assert.Equal(expectedSummary, model.Summary); + Assert.Equal(expectedToolCount, model.ToolCount); + Assert.Equal(expectedVoice, model.Voice); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new Item + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize(json, ModelBase.SerializerOptions); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new Item + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + Assert.NotNull(deserialized); + + string expectedID = "fermi"; + ApiEnum expectedCategory = ItemCategory.Sales; + string expectedName = "name"; + string expectedSummary = "summary"; + long expectedToolCount = 0; + bool expectedVoice = true; + + Assert.Equal(expectedID, deserialized.ID); + Assert.Equal(expectedCategory, deserialized.Category); + Assert.Equal(expectedName, deserialized.Name); + Assert.Equal(expectedSummary, deserialized.Summary); + Assert.Equal(expectedToolCount, deserialized.ToolCount); + Assert.Equal(expectedVoice, deserialized.Voice); + } + + [Fact] + public void Validation_Works() + { + var model = new Item + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Item + { + ID = "fermi", + Category = ItemCategory.Sales, + Name = "name", + Summary = "summary", + ToolCount = 0, + Voice = true, + }; + + Item copied = new(model); + + Assert.Equal(model, copied); + } +} + +public class ItemCategoryTest : TestBase +{ + [Theory] + [InlineData(ItemCategory.Sales)] + [InlineData(ItemCategory.Support)] + [InlineData(ItemCategory.FrontDesk)] + [InlineData(ItemCategory.Ops)] + public void Validation_Works(ItemCategory rawValue) + { + // force implicit conversion because Theory can't do that for us + ApiEnum value = rawValue; + value.Validate(); + } + + [Fact] + public void InvalidEnumValidationThrows_Works() + { + var value = JsonSerializer.Deserialize>( + JsonSerializer.SerializeToElement("invalid value"), + ModelBase.SerializerOptions + ); + + Assert.NotNull(value); + Assert.Throws(() => value.Validate()); + } + + [Theory] + [InlineData(ItemCategory.Sales)] + [InlineData(ItemCategory.Support)] + [InlineData(ItemCategory.FrontDesk)] + [InlineData(ItemCategory.Ops)] + public void SerializationRoundtrip_Works(ItemCategory rawValue) + { + // force implicit conversion because Theory can't do that for us + ApiEnum value = rawValue; + + string json = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize>( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } + + [Fact] + public void InvalidEnumSerializationRoundtrip_Works() + { + var value = JsonSerializer.Deserialize>( + JsonSerializer.SerializeToElement("invalid value"), + ModelBase.SerializerOptions + ); + string json = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize>( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } +} diff --git a/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateRetrieveParamsTest.cs b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateRetrieveParamsTest.cs new file mode 100644 index 0000000..9d22f68 --- /dev/null +++ b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateRetrieveParamsTest.cs @@ -0,0 +1,39 @@ +using System; +using Zavudev.Models.AgentTemplates; + +namespace Zavudev.Tests.Models.AgentTemplates; + +public class AgentTemplateRetrieveParamsTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var parameters = new AgentTemplateRetrieveParams { TemplateID = "fermi" }; + + string expectedTemplateID = "fermi"; + + Assert.Equal(expectedTemplateID, parameters.TemplateID); + } + + [Fact] + public void Url_Works() + { + AgentTemplateRetrieveParams parameters = new() { TemplateID = "fermi" }; + + var url = parameters.Url(new() { ApiKey = "My API Key" }); + + Assert.True( + TestBase.UrisEqual(new Uri("https://api.zavu.dev/v1/agent-templates/fermi"), url) + ); + } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new AgentTemplateRetrieveParams { TemplateID = "fermi" }; + + AgentTemplateRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } +} diff --git a/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateRetrieveResponseTest.cs b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateRetrieveResponseTest.cs new file mode 100644 index 0000000..8522bf9 --- /dev/null +++ b/src/Zavudev.Tests/Models/AgentTemplates/AgentTemplateRetrieveResponseTest.cs @@ -0,0 +1,523 @@ +using System.Collections.Generic; +using System.Text.Json; +using Zavudev.Core; +using Zavudev.Exceptions; +using Zavudev.Models.AgentTemplates; + +namespace Zavudev.Tests.Models.AgentTemplates; + +public class AgentTemplateRetrieveResponseTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new AgentTemplateRetrieveResponse + { + Template = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }, + }; + + Template expectedTemplate = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }; + + Assert.Equal(expectedTemplate, model.Template); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new AgentTemplateRetrieveResponse + { + Template = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new AgentTemplateRetrieveResponse + { + Template = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + Template expectedTemplate = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }; + + Assert.Equal(expectedTemplate, deserialized.Template); + } + + [Fact] + public void Validation_Works() + { + var model = new AgentTemplateRetrieveResponse + { + Template = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new AgentTemplateRetrieveResponse + { + Template = new() + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }, + }; + + AgentTemplateRetrieveResponse copied = new(model); + + Assert.Equal(model, copied); + } +} + +public class TemplateTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new Template + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }; + + string expectedID = "fermi"; + ApiEnum expectedCategory = Category.Sales; + string expectedDefaultSlug = "fermi"; + Dictionary expectedDependencies = new() { { "foo", "string" } }; + List expectedFiles = [new() { Content = "content", Path = "index.ts" }]; + string expectedName = "name"; + List expectedRequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }]; + string expectedSummary = "summary"; + bool expectedVoice = true; + + Assert.Equal(expectedID, model.ID); + Assert.Equal(expectedCategory, model.Category); + Assert.Equal(expectedDefaultSlug, model.DefaultSlug); + Assert.Equal(expectedDependencies.Count, model.Dependencies.Count); + foreach (var item in expectedDependencies) + { + Assert.True(model.Dependencies.TryGetValue(item.Key, out var value)); + + Assert.Equal(value, model.Dependencies[item.Key]); + } + Assert.Equal(expectedFiles.Count, model.Files.Count); + for (int i = 0; i < expectedFiles.Count; i++) + { + Assert.Equal(expectedFiles[i], model.Files[i]); + } + Assert.Equal(expectedName, model.Name); + Assert.Equal(expectedRequiredSecrets.Count, model.RequiredSecrets.Count); + for (int i = 0; i < expectedRequiredSecrets.Count; i++) + { + Assert.Equal(expectedRequiredSecrets[i], model.RequiredSecrets[i]); + } + Assert.Equal(expectedSummary, model.Summary); + Assert.Equal(expectedVoice, model.Voice); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new Template + { + ID = "fermi", + Category = Category.Sales, + DefaultSlug = "fermi", + Dependencies = new Dictionary() { { "foo", "string" } }, + Files = [new() { Content = "content", Path = "index.ts" }], + Name = "name", + RequiredSecrets = [new() { Hint = "hint", Key = "SENDER_ID" }], + Summary = "summary", + Voice = true, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize