diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5798e86 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,230 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = true +dotnet_style_allow_statement_immediately_after_block_experimental = true + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false +csharp_style_var_for_built_in_types = false +csharp_style_var_when_type_is_apparent = false + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true +csharp_style_expression_bodied_constructors = false +csharp_style_expression_bodied_indexers = true +csharp_style_expression_bodied_lambdas = true +csharp_style_expression_bodied_local_functions = false +csharp_style_expression_bodied_methods = false +csharp_style_expression_bodied_operators = false +csharp_style_expression_bodied_properties = true + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true +csharp_style_pattern_matching_over_is_with_cast_check = true +csharp_style_prefer_extended_property_pattern = true +csharp_style_prefer_not_pattern = true +csharp_style_prefer_pattern_matching = true +csharp_style_prefer_switch_expression = true + +# Null-checking preferences +csharp_style_conditional_delegate_call = true + +# Modifier preferences +csharp_prefer_static_local_function = true +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true +csharp_style_prefer_readonly_struct_member = true + +# Code-block preferences +csharp_prefer_braces = true +csharp_prefer_simple_using_statement = true +csharp_style_namespace_declarations = block_scoped +csharp_style_prefer_method_group_conversion = true +csharp_style_prefer_primary_constructors = true +csharp_style_prefer_top_level_statements = true + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true +csharp_style_implicit_object_creation_when_type_is_apparent = true +csharp_style_inlined_variable_declaration = true +csharp_style_prefer_index_operator = true +csharp_style_prefer_local_over_anonymous_function = true +csharp_style_prefer_null_check_over_type_check = true +csharp_style_prefer_range_operator = true +csharp_style_prefer_tuple_swap = true +csharp_style_prefer_utf8_string_literals = true +csharp_style_throw_expression = true +csharp_style_unused_value_assignment_preference = discard_variable +csharp_style_unused_value_expression_statement_preference = discard_variable + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true +csharp_style_allow_embedded_statements_on_same_line_experimental = true + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..f00a087 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "ms-dotnettools.csdevkit", + "EditorConfig.EditorConfig", + "oderwat.indent-rainbow", + "aliasadidev.nugetpackagemanagergui" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3ba0bbc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "editor.formatOnSave": true, + "dotnet.defaultSolution": "./Onspring.API.SDK.sln", + "dotnet.unitTests.runSettingsPath": "./Onspring.API.SDK.Tests/runsettings/internal.runsettings", + "cSpell.words": [ + "netstandard", + "Szalay" + ], +} diff --git a/Onspring.API.SDK.Tests/Infrastructure/TestDataFactory.cs b/Onspring.API.SDK.Tests/Infrastructure/TestDataFactory.cs index ca09c20..c25c1a4 100644 --- a/Onspring.API.SDK.Tests/Infrastructure/TestDataFactory.cs +++ b/Onspring.API.SDK.Tests/Infrastructure/TestDataFactory.cs @@ -32,5 +32,91 @@ public static ResultRecord GetFullyFilledOutRecord(int appId, int recordId) } }; } + + public static List GetPagesOfApps(int totalApps, int pageSize) => GetPages( + totalApps, + pageSize, + i => new App { Id = i, Name = "App" }, + (pageNumber, totalPages, totalRecords, items) => new GetPagedAppsResponse + { + PageNumber = pageNumber, + TotalPages = totalPages, + TotalRecords = totalRecords, + Items = items + } + ); + + public static List GetPagesOfFields(int totalFields, int pageSize) => GetPages( + totalFields, + pageSize, + i => new Field { Id = i, Name = "Field" }, + (pageNumber, totalPages, totalRecords, items) => new GetPagedFieldsResponse + { + PageNumber = pageNumber, + TotalPages = totalPages, + TotalRecords = totalRecords, + Items = items + } + ); + + public static List GetPagesOfReports(int totalReports, int pageSize) => GetPages( + totalReports, + pageSize, + i => new Report { Id = i, Name = "Report" }, + (pageNumber, totalPages, totalRecords, items) => new GetReportsForAppResponse + { + PageNumber = pageNumber, + TotalPages = totalPages, + TotalRecords = totalRecords, + Items = items + } + ); + + public static List GetPagesOfRecords(int totalRecords, int pageSize) => GetPages( + totalRecords, + pageSize, + i => new ResultRecord { RecordId = i }, + (pageNumber, totalPages, totalRecords, items) => new GetPagedRecordsResponse + { + PageNumber = pageNumber, + TotalPages = totalPages, + TotalRecords = totalRecords, + Items = items + } + ); + + public static List GetPages( + int totalItems, + int pageSize, + Func createItem, + Func, TResponse> createResponse + ) where TResponse : class + { + var pages = new List(); + var totalPages = (int)Math.Ceiling((double)totalItems / pageSize); + + for (var i = 1; i <= totalPages; i++) + { + var items = new List(); + + for (var j = 1; j <= pageSize; j++) + { + var itemIndex = (i - 1) * pageSize + j; + + if (itemIndex > totalItems) + { + break; + } + + items.Add(createItem(itemIndex)); + } + + var response = createResponse(i, totalPages, totalItems, items); + pages.Add(response); + } + + return pages; + } + } } diff --git a/Onspring.API.SDK.Tests/Onspring.API.SDK.Tests.csproj b/Onspring.API.SDK.Tests/Onspring.API.SDK.Tests.csproj index 59477c5..ff8f40b 100644 --- a/Onspring.API.SDK.Tests/Onspring.API.SDK.Tests.csproj +++ b/Onspring.API.SDK.Tests/Onspring.API.SDK.Tests.csproj @@ -1,7 +1,7 @@ - + - net5.0 + net9.0 false @@ -11,34 +11,51 @@ - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + true + ./TestResults/coverage/$(MSBuildProjectName)/ + opencover + + + + + + $(MSBuildProjectDirectory)\runsettings\internal.runsettings - + - - Always - - - Always - - - Always - + + Always + + + Always + + + Always + diff --git a/Onspring.API.SDK.Tests/TestServer/Controllers/FieldsController.cs b/Onspring.API.SDK.Tests/TestServer/Controllers/FieldsController.cs index 394c95f..88666c2 100644 --- a/Onspring.API.SDK.Tests/TestServer/Controllers/FieldsController.cs +++ b/Onspring.API.SDK.Tests/TestServer/Controllers/FieldsController.cs @@ -161,6 +161,17 @@ private static List GetTestFields() Status = "Enabled", Type = "Reference", Multiplicity = "SingleSelect", + }, + new + { + AppId = 1, + Id = 1, + IsRequired = false, + IsUnique = false, + Name = "Delegation", + Status = "Enabled", + Type = "SurveyDelegation", + Multiplicity = "SingleSelect", } }; } diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientAppsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientAppsTests.cs new file mode 100644 index 0000000..437331b --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientAppsTests.cs @@ -0,0 +1,167 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientAppsTests + { + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetApp() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetApps() + .WithId(1) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetAppsByIds() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetApps() + .WithIds(new[] { 1, 2, 3 }) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetApps() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetApps() + .ForPage(1) + .WithPageSize(25) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetAllApps_WhenUsingDefaultPageSize_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfApps = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfApps(numberOfApps, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/apps?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var appsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfApps() + .SendAsync(); + + var responsePages = new List(); + + await foreach (var response in appsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + + [TestMethod] + public async Task GetAllApps_WhenUsingCustomPageSize_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfApps = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfApps(numberOfApps, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/apps?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var appsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfApps() + .SendAsync(o => o.PageSize = pageSize); + + var responsePages = new List(); + + await foreach (var response in appsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientDiagnosticTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientDiagnosticTests.cs new file mode 100644 index 0000000..1dbcbc5 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientDiagnosticTests.cs @@ -0,0 +1,34 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientDiagnosticTests + { + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task CanConnectAsync() + { + var canConnect = await _apiClient + .CreateRequest() + .ToCheckConnection() + .SendAsync(); + + Assert.IsTrue(canConnect, "Unable to connect"); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientFieldTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientFieldTests.cs new file mode 100644 index 0000000..78a884f --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientFieldTests.cs @@ -0,0 +1,195 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientFieldTests + { + private const int _appIdWithFields = 1; + private static readonly int[] _fields = new[] { 1, 2, 3, 4, 5 }; + + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetField() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetFields() + .WithId(_fields.First()) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetFields() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetFields() + .WithIds(_fields) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetFieldsFromApp() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetFields() + .FromApp(_appIdWithFields) + .ForPage(1) + .WithPageSize(50) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetFieldsFromApp_WithOptions() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetFields() + .FromApp(_appIdWithFields) + .SendAsync(options => + { + options.PageNumber = 1; + options.PageSize = 25; + }); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetAllFields_WhenUsingDefaultPageSize_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfFields = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfFields(numberOfFields, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When( + HttpMethod.Get, + $"{testAddress}/fields/appId/{_appIdWithFields}?PageNumber={page.PageNumber}&PageSize={pageSize}" + ) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var fieldsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfFields() + .FromApp(_appIdWithFields) + .SendAsync(); + + var responsePages = new List(); + + await foreach (var response in fieldsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + + [TestMethod] + public async Task GetAllFields_WhenUsingCustomPageSize_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfFields = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfFields(numberOfFields, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When( + HttpMethod.Get, + $"{testAddress}/fields/appId/{_appIdWithFields}?PageNumber={page.PageNumber}&PageSize={pageSize}" + ) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var appsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfFields() + .FromApp(_appIdWithFields) + .SendAsync(o => o.PageSize = pageSize); + + var responsePages = new List(); + + await foreach (var response in appsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientFilesTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientFilesTests.cs new file mode 100644 index 0000000..2cb0ca6 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientFilesTests.cs @@ -0,0 +1,89 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientFilesTests + { + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetFile() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetFile() + .FromRecord(1) + .InField(1) + .WithId(1) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetFileInfo() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetFileInfo() + .FromRecord(1) + .InField(1) + .WithId(1) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task DeleteFile() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToDeleteFile() + .FromRecord(1) + .InField(1) + .WithId(1) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task AddFile() + { + var filePath = TestHelper.GetDefaultImagePath(); + var fileStream = File.OpenRead(filePath); + + var apiResponse = await _apiClient + .CreateRequest() + .ToAddFile() + .ToRecord(1) + .InField(1) + .WithName("image") + .WithStream(fileStream) + .WithType("image/png") + .WithNotes("This is a test file") + .WithModifiedDate(DateTime.UtcNow) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientListsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientListsTests.cs new file mode 100644 index 0000000..7bff45d --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientListsTests.cs @@ -0,0 +1,74 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientListsTests + { + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task AddListValue() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToSaveListValue() + .InList(1) + .WithId(null) + .WithName("Test") + .WithNumericValue(0) + .WithColor("#db3e3e") + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + Assert.IsInstanceOfType(apiResponse.Value.Id); + } + + [TestMethod] + public async Task UpdateListValue() + { + var testId = Guid.NewGuid(); + + var apiResponse = await _apiClient + .CreateRequest() + .ToSaveListValue() + .InList(1) + .WithId(testId) + .WithName("Test") + .WithNumericValue(0) + .WithColor("#db3e3e") + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + Assert.AreEqual(testId, apiResponse.Value.Id); + } + + [TestMethod] + public async Task DeleteListValue() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToDeleteListValue() + .InList(1) + .WithId(Guid.NewGuid()) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientRecordsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientRecordsTests.cs new file mode 100644 index 0000000..b99c29d --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientRecordsTests.cs @@ -0,0 +1,508 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientRecordsTests + { + private const int _appIdWithRecords = 1; + private const int _fieldId = 1; + + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetRecordsByApp() + { + var pagingRequest = new PagingRequest(1, 10); + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .ForPage(pagingRequest.PageNumber) + .WithPageSize(pagingRequest.PageSize) + .WithFieldIds(new[] { 1, 2, 3 }) + .WithFormat(DataFormat.Formatted) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value.Items); + } + + [TestMethod] + public async Task GetRecordsByApp_UsingOptions() + { + var pagingRequest = new PagingRequest(1, 10); + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .ForPage(1) + .SendAsync(opts => + { + opts.PageSize = pagingRequest.PageSize; + opts.Format = DataFormat.Formatted; + opts.FieldIds = new[] { 1, 2, 3 }; + }); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value.Items); + } + + [TestMethod] + public async Task GetRecordById() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithId(1) + .WithFieldIds(new[] { 1, 2, 3 }) + .WithFormat(DataFormat.Formatted) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value); + } + + [TestMethod] + public async Task GetRecordById_UsingOptions() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithId(1) + .SendAsync(options => + { + options.FieldIds = new[] { 1, 2, 3 }; + options.Format = DataFormat.Formatted; + }); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value); + } + + [TestMethod] + public async Task GetRecordsByIds() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithIds(new[] { 1, 2, 3 }) + .WithFieldIds(new[] { 1, 2, 3 }) + .WithFormat(DataFormat.Formatted) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value.Items); + } + + [TestMethod] + public async Task GetRecordsByIds_UsingOptions() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithIds(new[] { 1, 2, 3 }) + .SendAsync(options => + { + options.Format = DataFormat.Formatted; + options.FieldIds = new[] { 1, 2, 3 }; + }); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value.Items); + } + + [TestMethod] + public async Task QueryRecords() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithFilter($"{1} eq {1}") + .ForPage(1) + .WithPageSize(50) + .WithFieldIds(new[] { 1, 2, 3 }) + .WithFormat(DataFormat.Formatted) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value.Items); + } + + [TestMethod] + public async Task QueryRecords_UsingOptions() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithFilter(filter => + { + filter.FieldId = 1; + filter.Operator = FilterOperator.Equal; + filter.Value = 1; + }) + .SendAsync(options => + { + options.PageNumber = 1; + options.PageSize = 50; + options.FieldIds = new[] { 1, 2, 3 }; + options.Format = DataFormat.Formatted; + }); + + AssertHelper.AssertSuccess(apiResponse); + AssertHelper.AssertCasting(apiResponse.Value.Items); + } + + [TestMethod] + public async Task DeleteRecord() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToDeleteRecords() + .FromApp(1) + .WithId(1) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task DeleteRecords() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToDeleteRecords() + .FromApp(1) + .WithIds(new[] { 1, 2, 3 }) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task AddRecord() + { + var record = TestDataFactory.GetFullyFilledOutRecord(_appIdWithRecords, 1); + + var apiResponse = await _apiClient + .CreateRequest() + .ToSaveRecord() + .InApp(record.AppId) + .WithId(null) + .WithValues(record.FieldData) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task UpdateRecord() + { + var record = TestDataFactory.GetFullyFilledOutRecord(_appIdWithRecords, 1); + + var apiResponse = await _apiClient + .CreateRequest() + .ToSaveRecord() + .InApp(record.AppId) + .WithId(record.RecordId) + .WithValues(record.FieldData) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetAllRecords_WhenUsingDefaultOptions_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfRecords = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfRecords(numberOfRecords, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When( + HttpMethod.Get, + $"{testAddress}/records/appId/{_appIdWithRecords}" + ) + .WithQueryString(new Dictionary + { + { "PageNumber", page.PageNumber.ToString() }, + { "PageSize", pageSize.ToString() }, + { "dataFormat", DataFormat.Raw.ToString() } + }) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var recordsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfRecords() + .FromApp(_appIdWithRecords) + .SendAsync(); + + var responsePages = new List(); + + await foreach (var response in recordsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + [TestMethod] + public async Task GetAllRecords_WhenUsingCustomOptions_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfRecords = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfRecords(numberOfRecords, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When( + HttpMethod.Get, + $"{testAddress}/records/appId/{_appIdWithRecords}" + ) + .WithQueryString(new Dictionary + { + { "PageNumber", page.PageNumber.ToString() }, + { "PageSize", pageSize.ToString() }, + { "dataFormat", DataFormat.Formatted.ToString() }, + { "fieldIds", "1,2,3" } + }) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var recordsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfRecords() + .FromApp(_appIdWithRecords) + .SendAsync(o => + { + o.FieldIds = [1, 2, 3]; + o.DataFormat = DataFormat.Formatted; + o.PageSize = pageSize; + }); + + var responsePages = new List(); + + await foreach (var response in recordsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + [TestMethod] + public async Task GetAllRecordsByQuery_WhenUsingDefaultOptions_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var testFilter = "testFilter"; + var numberOfRecords = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfRecords(numberOfRecords, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When( + HttpMethod.Post, + $"{testAddress}/records/query" + ) + .WithQueryString(new Dictionary + { + { "PageNumber", page.PageNumber.ToString() }, + { "PageSize", pageSize.ToString() } + }) + .WithJsonContent(req => + { + return req.AppId == _appIdWithRecords + && req.Filter == testFilter + && req.FieldIds.SequenceEqual([]) + && req.DataFormat == DataFormat.Raw; + }) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var recordsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfRecords() + .FromApp(_appIdWithRecords) + .WithFilter(testFilter) + .SendAsync(); + + var responsePages = new List(); + + await foreach (var response in recordsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + [TestMethod] + public async Task GetAllRecordsByQuery_WhenUsingCustomOptions_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var testFilter = "testFilter"; + var numberOfRecords = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfRecords(numberOfRecords, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When( + HttpMethod.Post, + $"{testAddress}/records/query" + ) + .WithQueryString(new Dictionary + { + { "PageNumber", page.PageNumber.ToString() }, + { "PageSize", pageSize.ToString() } + }) + .WithJsonContent(req => + { + return req.AppId == _appIdWithRecords + && req.Filter == testFilter + && req.FieldIds.SequenceEqual([1, 2, 3]) + && req.DataFormat == DataFormat.Formatted; + }) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var recordsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfRecords() + .FromApp(_appIdWithRecords) + .WithFilter(testFilter) + .SendAsync(o => + { + o.FieldIds = [1, 2, 3]; + o.DataFormat = DataFormat.Formatted; + o.PageSize = pageSize; + }); + + var responsePages = new List(); + + await foreach (var response in recordsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientReportsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientReportsTests.cs new file mode 100644 index 0000000..9250394 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/Fluent/OnspringClientReportsTests.cs @@ -0,0 +1,209 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientReportsTests + { + private const int _appIdWithReports = 1; + private const int _reportId = 1; + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetReportsForAppAsync() + { + var pagingRequest = new PagingRequest(1, 10); + + var getResponse = await _apiClient.CreateRequest() + .ToGetReports() + .FromApp(_appIdWithReports) + .ForPage(pagingRequest.PageNumber) + .WithPageSize(pagingRequest.PageSize) + .SendAsync(); + + AssertHelper.AssertSuccess(getResponse); + AssertHelper.AssertPaging(pagingRequest, getResponse.Value); + } + + [TestMethod] + public async Task GetReportsForAppAsync_WithOptions() + { + var pagingRequest = new PagingRequest(1, 10); + + var getResponse = await _apiClient.CreateRequest() + .ToGetReports() + .FromApp(_appIdWithReports) + .SendAsync(options => + { + options.PageNumber = pagingRequest.PageNumber; + options.PageSize = pagingRequest.PageSize; + }); + + AssertHelper.AssertSuccess(getResponse); + AssertHelper.AssertPaging(pagingRequest, getResponse.Value); + } + + [TestMethod] + public async Task GetReportData() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetReportData() + .FromReport(_reportId) + .WithFormat(DataFormat.Formatted) + .WithDataType(ReportDataType.ChartData) + .SendAsync(); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetReportData_WithOptions() + { + var apiResponse = await _apiClient + .CreateRequest() + .ToGetReportData() + .FromReport(_reportId) + .SendAsync(options => + { + options.Format = DataFormat.Formatted; + options.DataType = ReportDataType.ChartData; + }); + + AssertHelper.AssertSuccess(apiResponse); + } + + [TestMethod] + public async Task GetAllReports_WhenUsingDefaultPageSize_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfReports(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/reports/appId/{_appIdWithReports}") + .WithQueryString(new Dictionary + { + { "PageNumber", page.PageNumber.ToString() }, + { "PageSize", pageSize.ToString() } + }) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfReports() + .FromApp(_appIdWithReports) + .SendAsync(); + + var responsePages = new List(); + + await foreach (var response in reportsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + + [TestMethod] + public async Task GetAllReports_WhenUsingCustomPageSize_ItShouldReturnAllPages() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfReports(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/reports/appId/{_appIdWithReports}") + .WithQueryString(new Dictionary + { + { "PageNumber", page.PageNumber.ToString() }, + { "PageSize", pageSize.ToString() } + }) + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponses = apiClient + .CreateRequest() + .ToGetAllPages() + .OfReports() + .FromApp(_appIdWithReports) + .SendAsync(o => o.PageSize = pageSize); + + var responsePages = new List(); + + await foreach (var response in reportsResponses) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientAppsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientAppsTests.cs new file mode 100644 index 0000000..efe53e5 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientAppsTests.cs @@ -0,0 +1,204 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientAppsTests + { + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetAppsAsync() + { + var appsResponse = await _apiClient.GetAppsAsync(); + + AssertHelper.AssertSuccess(appsResponse); + Assert.IsTrue(appsResponse.Value.Items.Any(), "No items returned."); + } + + [TestMethod] + public async Task GetApps_WithPaging() + { + var pagingRequest = new Models.PagingRequest(1, 50); + var appsResponse = await _apiClient.GetAppsAsync(pagingRequest); + + AssertHelper.AssertSuccess(appsResponse); + AssertHelper.AssertPaging(pagingRequest, appsResponse.Value); + } + + [TestMethod] + public async Task GetAppByIdAsync() + { + var appResponse = await _apiClient.GetAppAsync(1); + + AssertHelper.AssertSuccess(appResponse); + } + + [TestMethod] + public async Task GetAppById_Unauthorized() + { + var appResponse = await _apiClient.GetAppAsync(401); + + AssertHelper.AssertError(appResponse, HttpStatusCode.Unauthorized); + } + + [TestMethod] + public async Task GetAppById_Forbidden() + { + var appResponse = await _apiClient.GetAppAsync(403); + + AssertHelper.AssertError(appResponse, HttpStatusCode.Forbidden, true); + } + + [TestMethod] + public async Task GetAppById_NotFound() + { + var appResponse = await _apiClient.GetAppAsync(404); + + AssertHelper.AssertError(appResponse, HttpStatusCode.NotFound, true); + } + + [TestMethod] + public async Task GetAppsBatchAsync() + { + var ids = new[] { 1, 2, 3 }; + var getAppsResponse = await _apiClient.GetAppsAsync(ids); + + AssertHelper.AssertSuccess(getAppsResponse); + Assert.IsTrue(getAppsResponse.Value.Items.Any(), "No items returned."); + Assert.AreEqual(ids.Length, getAppsResponse.Value.Count, "Count was not correct."); + } + + [TestMethod] + public async Task GetAppsBatch_Unauthorized() + { + var ids = new[] { 401 }; + var getAppsResponse = await _apiClient.GetAppsAsync(ids); + + AssertHelper.AssertError(getAppsResponse, HttpStatusCode.Unauthorized); + } + + [TestMethod] + public async Task GetAppsBatch_Forbidden() + { + var ids = new[] { 403 }; + var getAppsResponse = await _apiClient.GetAppsAsync(ids); + + AssertHelper.AssertError(getAppsResponse, HttpStatusCode.Forbidden); + } + + [TestMethod] + public async Task GetAllAppsAsync_WhenUsingDefaultPageSize_ReturnsAllApps() + { + var testAddress = "https://localhost"; + + var numberOfApps = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfApps(numberOfApps, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/apps?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var appsResponse = apiClient.GetAllAppsAsync(); + + var responsePages = new List(); + + await foreach (var response in appsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + + [TestMethod] + public async Task GetAllAppsAsync_WhenUsingSpecificPageSize_ReturnsAllApps() + { + var testAddress = "https://localhost"; + + var mockHttp = new MockHttpMessageHandler(); + + var numberOfApps = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfApps(numberOfApps, pageSize); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/apps?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var appsResponse = apiClient.GetAllAppsAsync(pageSize); + + var responsePages = new List(); + + await foreach (var response in appsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientConfigurationTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientConfigurationTests.cs similarity index 93% rename from Onspring.API.SDK.Tests/Tests/OnspringClientConfigurationTests.cs rename to Onspring.API.SDK.Tests/Tests/Integration/OnspringClientConfigurationTests.cs index 3450a59..2214b83 100644 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientConfigurationTests.cs +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientConfigurationTests.cs @@ -2,7 +2,7 @@ using System; using System.Diagnostics.CodeAnalysis; -namespace Onspring.API.SDK.Tests.Tests +namespace Onspring.API.SDK.Tests.Tests.Integration { [TestClass, ExcludeFromCodeCoverage] public class OnspringClientConfigurationTests @@ -36,4 +36,4 @@ public void ParameteredCtor_GetParams() Assert.AreEqual(baseAddress, clientConfig.BaseAddress, "BaseAddress was not correct"); } } -} +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientDiagnosticTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientDiagnosticTests.cs similarity index 92% rename from Onspring.API.SDK.Tests/Tests/OnspringClientDiagnosticTests.cs rename to Onspring.API.SDK.Tests/Tests/Integration/OnspringClientDiagnosticTests.cs index e9ae9a0..93dbc00 100644 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientDiagnosticTests.cs +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientDiagnosticTests.cs @@ -4,7 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; -namespace Onspring.API.SDK.Tests.Tests +namespace Onspring.API.SDK.Tests.Tests.Integration { [TestClass, ExcludeFromCodeCoverage] public class OnspringClientDiagnosticTests @@ -27,4 +27,4 @@ public async Task CanConnectAsync() Assert.IsTrue(canConnect, "Unable to connect"); } } -} +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientFieldTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientFieldTests.cs new file mode 100644 index 0000000..6971338 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientFieldTests.cs @@ -0,0 +1,146 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientFieldTests + { + private const int _appIdWithFields = 1; + private static readonly int[] _fields = new[] { 1, 2, 3, 4, 5 }; + + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetFieldAsync() + { + var getResponse = await _apiClient.GetFieldAsync(_fields.First()); + AssertHelper.AssertSuccess(getResponse); + } + + [TestMethod] + public async Task GetFieldsAsync() + { + var getResponse = await _apiClient.GetFieldsAsync(_fields); + AssertHelper.AssertSuccess(getResponse); + } + + [TestMethod] + public async Task GetFieldsForAppAsync() + { + var getResponse = await _apiClient.GetFieldsForAppAsync(_appIdWithFields); + AssertHelper.AssertSuccess(getResponse); + } + + [TestMethod] + public async Task GetAllFieldsForAppAsync_WhenUsingDefaultPageSize_ReturnsAllFields() + { + var testAddress = "https://localhost"; + + var numberOfFields = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfFields(numberOfFields, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/fields/appId/1?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var fieldsResponse = apiClient.GetAllFieldsForAppAsync(1); + + var responsePages = new List(); + + await foreach (var response in fieldsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + + [TestMethod] + public async Task GetAllFieldsForAppAsync_WhenUsingSpecificPageSize_ReturnsAllFields() + { + var testAddress = "https://localhost"; + + var numberOfFields = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfFields(numberOfFields, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/fields/appId/1?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var fieldsResponse = apiClient.GetAllFieldsForAppAsync(appId: 1, pageSize: 1); + + var responsePages = new List(); + + await foreach (var response in fieldsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientFilesTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientFilesTests.cs similarity index 95% rename from Onspring.API.SDK.Tests/Tests/OnspringClientFilesTests.cs rename to Onspring.API.SDK.Tests/Tests/Integration/OnspringClientFilesTests.cs index 16e57f8..2b19a07 100644 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientFilesTests.cs +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientFilesTests.cs @@ -8,7 +8,7 @@ using System.IO; using System.Threading.Tasks; -namespace Onspring.API.SDK.Tests.Tests +namespace Onspring.API.SDK.Tests.Tests.Integration { [TestClass, ExcludeFromCodeCoverage] public class OnspringClientFilesTests @@ -60,4 +60,4 @@ public async Task SaveReadDeleteFileAsync() AssertHelper.AssertSuccess(deleteResponse); } } -} +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientListsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientListsTests.cs similarity index 95% rename from Onspring.API.SDK.Tests/Tests/OnspringClientListsTests.cs rename to Onspring.API.SDK.Tests/Tests/Integration/OnspringClientListsTests.cs index 8c61d61..c406e63 100644 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientListsTests.cs +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientListsTests.cs @@ -7,7 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; -namespace Onspring.API.SDK.Tests.Tests +namespace Onspring.API.SDK.Tests.Tests.Integration { [TestClass, ExcludeFromCodeCoverage] public class OnspringClientListsTests @@ -56,4 +56,4 @@ public async Task AddUpdateRemoveListItemAsync() AssertHelper.AssertSuccess(deleteResponse); } } -} +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientRecordsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientRecordsTests.cs new file mode 100644 index 0000000..3934097 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientRecordsTests.cs @@ -0,0 +1,365 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientRecordsTests + { + private const int _appIdWithRecords = 1; + private const int _fieldId = 1; + + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetRecordsByApp() + { + var getRequest = new GetRecordsByAppRequest(_appIdWithRecords); + var getResponse = await _apiClient.GetRecordsForAppAsync(getRequest); + AssertHelper.AssertSuccess(getResponse); + } + + [TestMethod] + public async Task CrudAsync() + { + // Prepare initial record. + var record = TestDataFactory.GetFullyFilledOutRecord(_appIdWithRecords, default); + + // Insert + var insertResponse = await _apiClient.SaveRecordAsync(record); // Used for single delete + var secondInsertResponse = await _apiClient.SaveRecordAsync(record); // Used for batch delete + AssertHelper.AssertSuccess(insertResponse); + + // Update + record.RecordId = insertResponse.Value.Id; + UpdateRecordFields(record); + + var updateResponse = await _apiClient.SaveRecordAsync(record); + AssertHelper.AssertSuccess(updateResponse); + + // Reads + // Get by ID + var getRequest = new GetRecordRequest(_appIdWithRecords, insertResponse.Value.Id) + { + FieldIds = { _fieldId }, + }; + var getResponse = await _apiClient.GetRecordAsync(getRequest); + AssertHelper.AssertSuccess(getResponse); + AssertHelper.AssertCasting(getResponse.Value); + + // Get batch + var getBatchRequest = new GetRecordsRequest + { + AppId = _appIdWithRecords, + RecordIds = { insertResponse.Value.Id, secondInsertResponse.Value.Id }, + FieldIds = { _fieldId }, + }; + var batchGetResponse = await _apiClient.GetRecordsAsync(getBatchRequest); + AssertHelper.AssertSuccess(batchGetResponse); + AssertHelper.AssertCasting(batchGetResponse.Value.Items); + + // Get by app + var pagingRequest = new PagingRequest(1, 10); + var getByAppRequest = new GetRecordsByAppRequest(_appIdWithRecords, pagingRequest) + { + FieldIds = { _fieldId }, + }; + var getByAppResponse = await _apiClient.GetRecordsForAppAsync(getByAppRequest); + AssertHelper.AssertSuccess(getByAppResponse); + AssertHelper.AssertCasting(getByAppResponse.Value.Items); + + // Query + var queryRequest = new QueryRecordsRequest + { + AppId = _appIdWithRecords, + }; + var queryResponse = await _apiClient.QueryRecordsAsync(queryRequest); + AssertHelper.AssertSuccess(queryResponse); + AssertHelper.AssertCasting(queryResponse.Value.Items); + + // Delete + // Single delete + var deleteResponse = await _apiClient.DeleteRecordAsync(_appIdWithRecords, insertResponse.Value.Id); + AssertHelper.AssertSuccess(deleteResponse); + + // Batch delete + var batchDeleteRequest = new DeleteRecordsRequest(_appIdWithRecords, new[] { secondInsertResponse.Value.Id }); + var batchDeleteResponse = await _apiClient.DeleteRecordsAsync(batchDeleteRequest); + AssertHelper.AssertSuccess(batchDeleteResponse); + } + + [TestMethod] + public async Task GetAllRecordsForAppAsync_WhenUsingDefaultPageSize_ReturnsAllRecords() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfRecords(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/records/appId/1?dataFormat={DataFormat.Raw}&PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponse = apiClient.GetAllRecordsForAppAsync(new GetRecordsByAppRequest(1)); + + var responsePages = new List(); + + await foreach (var response in reportsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + [TestMethod] + public async Task GetAllRecordsForAppAsync_WhenUsingSpecificPageSize_ReturnsAllRecords() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfRecords(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/records/appId/1?dataFormat={DataFormat.Raw}&PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponse = apiClient.GetAllRecordsForAppAsync(new GetRecordsByAppRequest(1, new PagingRequest(1, pageSize))); + + var responsePages = new List(); + + await foreach (var response in reportsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + [TestMethod] + public async Task GetAllRecordsByQueryAsync_WhenUsingDefaultPageSize_ReturnsAllRecords() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfRecords(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Post, $"{testAddress}/records/query?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponse = apiClient.GetAllRecordsByQueryAsync(new QueryRecordsRequest { AppId = 1 }); + + var responsePages = new List(); + + await foreach (var response in reportsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + [TestMethod] + public async Task GetAllRecordsByQueryAsync_WhenUsingSpecificPageSize_ReturnsAllRecords() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfRecords(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Post, $"{testAddress}/records/query?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponse = apiClient.GetAllRecordsByQueryAsync(new QueryRecordsRequest { AppId = 1 }, pageSize); + + var responsePages = new List(); + + await foreach (var response in reportsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].RecordId, responsePage.Items[0].RecordId); + } + } + + private static void UpdateRecordFields(ResultRecord record) + { + var random = new Random(); + foreach (var field in record.FieldData) + { + switch (field.Type) + { + case Enums.ResultValueType.String: + field.SetString("My new string value."); + break; + case Enums.ResultValueType.Integer: + field.SetInteger(random.Next()); + break; + case Enums.ResultValueType.Decimal: + field.SetDecimal(random.Next()); + break; + case Enums.ResultValueType.Date: + field.SetNullableDateTime(DateTime.UtcNow); + break; + case Enums.ResultValueType.TimeSpan: + field.SetTimeSpanData(new TimeSpanData + { + Increment = Enums.TimeSpanIncrement.Days, + }); + break; + case Enums.ResultValueType.Guid: + field.SetNullableGuid(Guid.NewGuid()); + break; + case Enums.ResultValueType.StringList: + field.SetStringList(new List { Guid.NewGuid().ToString() }); + break; + case Enums.ResultValueType.IntegerList: + field.SetIntegerList(new List { random.Next(), random.Next(), random.Next(), }); + break; + case Enums.ResultValueType.GuidList: + field.SetGuidList(new List { Guid.NewGuid() }); + break; + case Enums.ResultValueType.AttachmentList: + field.SetAttachmentList(new List + { + new AttachmentFile + { + FileId = 1, + FileName = "Update attachment list file name", + Notes = "Updated notes." + } + }); + break; + case Enums.ResultValueType.ScoringGroupList: + field.SetScoringGroupList(new List + { + new ScoringGroup + { + ListValueId = Guid.NewGuid(), + MaximumScore = 1m, + Name = "Updated test scoring group", + Score = 1m, + } + }); + break; + case Enums.ResultValueType.FileList: + field.SetFileList(new List { random.Next(), random.Next(), random.Next(), }); + break; + default: + break; + } + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientReportsTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientReportsTests.cs new file mode 100644 index 0000000..9302d9a --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientReportsTests.cs @@ -0,0 +1,140 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Tests.Infrastructure; +using Onspring.API.SDK.Tests.Infrastructure.Helpers; +using Onspring.API.SDK.Tests.Infrastructure.Http; +using RichardSzalay.MockHttp; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientReportsTests + { + private const int _appIdWithReports = 1; + private const int _reportId = 1; + private static OnspringClient _apiClient; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var testConfiguration = TestConfiguration.LoadFromContext(testContext); + var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); + + _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); + } + + [TestMethod] + public async Task GetReportAsync() + { + var getResponse = await _apiClient.GetReportAsync(_reportId); + AssertHelper.AssertSuccess(getResponse); + } + + [TestMethod] + public async Task GetReportsForAppAsync() + { + var pagingRequest = new PagingRequest(1, 10); + var getResponse = await _apiClient.GetReportsForAppAsync(_appIdWithReports); + AssertHelper.AssertSuccess(getResponse); + AssertHelper.AssertPaging(pagingRequest, getResponse.Value); + } + + [TestMethod] + public async Task GetAllReportsForAppAsync_WhenUsingDefaultPageSize_ReturnsAllReports() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 50; + var pages = TestDataFactory.GetPagesOfReports(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/reports/appId/1?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponse = apiClient.GetAllReportsForAppAsync(1); + + var responsePages = new List(); + + await foreach (var response in reportsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + + [TestMethod] + public async Task GetAllReportsForAppAsync_WhenUsingSpecificPageSize_ReturnsAllReports() + { + var testAddress = "https://localhost"; + + var numberOfReports = 3; + var pageSize = 1; + var pages = TestDataFactory.GetPagesOfReports(numberOfReports, pageSize); + + var mockHttp = new MockHttpMessageHandler(); + + foreach (var page in pages) + { + mockHttp + .When(HttpMethod.Get, $"{testAddress}/reports/appId/1?PageNumber={page.PageNumber}&PageSize={pageSize}") + .Respond( + "application/json", + JsonSerializer.Serialize(page) + ); + } + + var mockHttpClient = mockHttp.ToHttpClient(); + mockHttpClient.BaseAddress = new(testAddress); + + var apiClient = new OnspringClient("test", mockHttpClient); + + var reportsResponse = apiClient.GetAllReportsForAppAsync(appId: 1, pageSize: 1); + + var responsePages = new List(); + + await foreach (var response in reportsResponse) + { + AssertHelper.AssertSuccess(response); + responsePages.Add(response.Value); + } + + foreach (var page in pages) + { + var responsePage = responsePages.Single(x => x.PageNumber == page.PageNumber); + + Assert.AreEqual(page.PageNumber, responsePage.PageNumber); + Assert.AreEqual(page.Items.Count, responsePage.Items.Count); + Assert.AreEqual(page.Items[0].Id, responsePage.Items[0].Id); + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientTests.cs b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientTests.cs similarity index 85% rename from Onspring.API.SDK.Tests/Tests/OnspringClientTests.cs rename to Onspring.API.SDK.Tests/Tests/Integration/OnspringClientTests.cs index 4ef17d4..97dbcc7 100644 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientTests.cs +++ b/Onspring.API.SDK.Tests/Tests/Integration/OnspringClientTests.cs @@ -1,10 +1,11 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Interfaces.Fluent; using Onspring.API.SDK.Tests.Infrastructure; using System; using System.Diagnostics.CodeAnalysis; using System.Net.Http; -namespace Onspring.API.SDK.Tests.Tests +namespace Onspring.API.SDK.Tests.Tests.Integration { [TestClass, ExcludeFromCodeCoverage] public class OnspringClientTests @@ -100,5 +101,13 @@ public void InvalidConstructor_HttpClient_NoBaseAddress() { var _ = new OnspringClient(_testConfiguration.ApiKey, new HttpClient()); } + + [TestMethod] + public void CreateRequest_WhenCalled_ItShouldReturnAnInstanceOfAnOnspringRequest() + { + var client = new OnspringClient(_testConfiguration.ApiKey, new HttpClient { BaseAddress = new Uri(_testConfiguration.BaseAddress) }); + var request = client.CreateRequest(); + Assert.IsInstanceOfType(request); + } } -} +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientAppsTests.cs b/Onspring.API.SDK.Tests/Tests/OnspringClientAppsTests.cs deleted file mode 100644 index ecb9076..0000000 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientAppsTests.cs +++ /dev/null @@ -1,106 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Onspring.API.SDK.Tests.Infrastructure; -using Onspring.API.SDK.Tests.Infrastructure.Helpers; -using Onspring.API.SDK.Tests.Infrastructure.Http; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Onspring.API.SDK.Tests.Tests -{ - [TestClass, ExcludeFromCodeCoverage] - public class OnspringClientAppsTests - { - private static OnspringClient _apiClient; - - [ClassInitialize] - public static void ClassInit(TestContext testContext) - { - var testConfiguration = TestConfiguration.LoadFromContext(testContext); - var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); - - _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); - } - - [TestMethod] - public async Task GetAppsAsync() - { - var appsResponse = await _apiClient.GetAppsAsync(); - - AssertHelper.AssertSuccess(appsResponse); - Assert.IsTrue(appsResponse.Value.Items.Any(), "No items returned."); - } - - [TestMethod] - public async Task GetApps_WithPaging() - { - var pagingRequest = new Models.PagingRequest(1, 50); - var appsResponse = await _apiClient.GetAppsAsync(pagingRequest); - - AssertHelper.AssertSuccess(appsResponse); - AssertHelper.AssertPaging(pagingRequest, appsResponse.Value); - } - - [TestMethod] - public async Task GetAppByIdAsync() - { - var appResponse = await _apiClient.GetAppAsync(1); - - AssertHelper.AssertSuccess(appResponse); - } - - [TestMethod] - public async Task GetAppById_Unauthorized() - { - var appResponse = await _apiClient.GetAppAsync(401); - - AssertHelper.AssertError(appResponse, HttpStatusCode.Unauthorized); - } - - [TestMethod] - public async Task GetAppById_Forbidden() - { - var appResponse = await _apiClient.GetAppAsync(403); - - AssertHelper.AssertError(appResponse, HttpStatusCode.Forbidden, true); - } - - [TestMethod] - public async Task GetAppById_NotFound() - { - var appResponse = await _apiClient.GetAppAsync(404); - - AssertHelper.AssertError(appResponse, HttpStatusCode.NotFound, true); - } - - [TestMethod] - public async Task GetAppsBatchAsync() - { - var ids = new[] { 1, 2, 3 }; - var getAppsResponse = await _apiClient.GetAppsAsync(ids); - - AssertHelper.AssertSuccess(getAppsResponse); - Assert.IsTrue(getAppsResponse.Value.Items.Any(), "No items returned."); - Assert.AreEqual(ids.Length, getAppsResponse.Value.Count, "Count was not correct."); - } - - [TestMethod] - public async Task GetAppsBatch_Unauthorized() - { - var ids = new[] { 401 }; - var getAppsResponse = await _apiClient.GetAppsAsync(ids); - - AssertHelper.AssertError(getAppsResponse, HttpStatusCode.Unauthorized); - } - - [TestMethod] - public async Task GetAppsBatch_Forbidden() - { - var ids = new[] { 403 }; - var getAppsResponse = await _apiClient.GetAppsAsync(ids); - - AssertHelper.AssertError(getAppsResponse, HttpStatusCode.Forbidden); - } - } -} diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientFieldTests.cs b/Onspring.API.SDK.Tests/Tests/OnspringClientFieldTests.cs deleted file mode 100644 index 82ef52b..0000000 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientFieldTests.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Onspring.API.SDK.Tests.Infrastructure; -using Onspring.API.SDK.Tests.Infrastructure.Helpers; -using Onspring.API.SDK.Tests.Infrastructure.Http; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading.Tasks; - -namespace Onspring.API.SDK.Tests.Tests -{ - [TestClass, ExcludeFromCodeCoverage] - public class OnspringClientFieldTests - { - private const int _appIdWithFields = 1; - private static readonly int[] _fields = new[] { 1, 2, 3, 4, 5 }; - - private static OnspringClient _apiClient; - - [ClassInitialize] - public static void ClassInit(TestContext testContext) - { - var testConfiguration = TestConfiguration.LoadFromContext(testContext); - var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); - - _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); - } - - [TestMethod] - public async Task GetFieldAsync() - { - var getResponse = await _apiClient.GetFieldAsync(_fields.First()); - AssertHelper.AssertSuccess(getResponse); - } - - [TestMethod] - public async Task GetFieldsAsync() - { - var getResponse = await _apiClient.GetFieldsAsync(_fields); - AssertHelper.AssertSuccess(getResponse); - } - - [TestMethod] - public async Task GetFieldsForAppAsync() - { - var getResponse = await _apiClient.GetFieldsForAppAsync(_appIdWithFields); - AssertHelper.AssertSuccess(getResponse); - } - } -} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientRecordsTests.cs b/Onspring.API.SDK.Tests/Tests/OnspringClientRecordsTests.cs deleted file mode 100644 index 8a123cb..0000000 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientRecordsTests.cs +++ /dev/null @@ -1,177 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Onspring.API.SDK.Models; -using Onspring.API.SDK.Tests.Infrastructure; -using Onspring.API.SDK.Tests.Infrastructure.Helpers; -using Onspring.API.SDK.Tests.Infrastructure.Http; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading.Tasks; - -namespace Onspring.API.SDK.Tests.Tests -{ - [TestClass, ExcludeFromCodeCoverage] - public class OnspringClientRecordsTests - { - private const int _appIdWithRecords = 1; - private const int _fieldId = 1; - - private static OnspringClient _apiClient; - - [ClassInitialize] - public static void ClassInit(TestContext testContext) - { - var testConfiguration = TestConfiguration.LoadFromContext(testContext); - var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); - - _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); - } - - [TestMethod] - public async Task GetRecordsByApp() - { - var getRequest = new GetRecordsByAppRequest(_appIdWithRecords); - var getResponse = await _apiClient.GetRecordsForAppAsync(getRequest); - AssertHelper.AssertSuccess(getResponse); - } - - [TestMethod] - public async Task CrudAsync() - { - // Prepare initial record. - var record = TestDataFactory.GetFullyFilledOutRecord(_appIdWithRecords, default); - - // Insert - var insertResponse = await _apiClient.SaveRecordAsync(record); // Used for single delete - var secondInsertResponse = await _apiClient.SaveRecordAsync(record); // Used for batch delete - AssertHelper.AssertSuccess(insertResponse); - - // Update - record.RecordId = insertResponse.Value.Id; - UpdateRecordFields(record); - - var updateResponse = await _apiClient.SaveRecordAsync(record); - AssertHelper.AssertSuccess(updateResponse); - - // Reads - // Get by ID - var getRequest = new GetRecordRequest(_appIdWithRecords, insertResponse.Value.Id) - { - FieldIds = { _fieldId }, - }; - var getResponse = await _apiClient.GetRecordAsync(getRequest); - AssertHelper.AssertSuccess(getResponse); - AssertHelper.AssertCasting(getResponse.Value); - - // Get batch - var getBatchRequest = new GetRecordsRequest - { - AppId = _appIdWithRecords, - RecordIds = { insertResponse.Value.Id, secondInsertResponse.Value.Id }, - FieldIds = { _fieldId }, - }; - var batchGetResponse = await _apiClient.GetRecordsAsync(getBatchRequest); - AssertHelper.AssertSuccess(batchGetResponse); - AssertHelper.AssertCasting(batchGetResponse.Value.Items); - - // Get by app - var pagingRequest = new PagingRequest(1, 10); - var getByAppRequest = new GetRecordsByAppRequest(_appIdWithRecords, pagingRequest) - { - FieldIds = { _fieldId }, - }; - var getByAppResponse = await _apiClient.GetRecordsForAppAsync(getByAppRequest); - AssertHelper.AssertSuccess(getByAppResponse); - AssertHelper.AssertCasting(getByAppResponse.Value.Items); - - // Query - var queryRequest = new QueryRecordsRequest - { - AppId = _appIdWithRecords, - }; - var queryResponse = await _apiClient.QueryRecordsAsync(queryRequest); - AssertHelper.AssertSuccess(queryResponse); - AssertHelper.AssertCasting(queryResponse.Value.Items); - - // Delete - // Single delete - var deleteResponse = await _apiClient.DeleteRecordAsync(_appIdWithRecords, insertResponse.Value.Id); - AssertHelper.AssertSuccess(deleteResponse); - - // Batch delete - var batchDeleteRequest = new DeleteRecordsRequest(_appIdWithRecords, new[] { secondInsertResponse.Value.Id }); - var batchDeleteResponse = await _apiClient.DeleteRecordsAsync(batchDeleteRequest); - AssertHelper.AssertSuccess(batchDeleteResponse); - } - - private static void UpdateRecordFields(ResultRecord record) - { - var random = new Random(); - foreach (var field in record.FieldData) - { - switch (field.Type) - { - case Enums.ResultValueType.String: - field.SetString("My new string value."); - break; - case Enums.ResultValueType.Integer: - field.SetInteger(random.Next()); - break; - case Enums.ResultValueType.Decimal: - field.SetDecimal(random.Next()); - break; - case Enums.ResultValueType.Date: - field.SetNullableDateTime(DateTime.UtcNow); - break; - case Enums.ResultValueType.TimeSpan: - field.SetTimeSpanData(new TimeSpanData - { - Increment = Enums.TimeSpanIncrement.Days, - }); - break; - case Enums.ResultValueType.Guid: - field.SetNullableGuid(Guid.NewGuid()); - break; - case Enums.ResultValueType.StringList: - field.SetStringList(new List { Guid.NewGuid().ToString() }); - break; - case Enums.ResultValueType.IntegerList: - field.SetIntegerList(new List { random.Next(), random.Next(), random.Next(), }); - break; - case Enums.ResultValueType.GuidList: - field.SetGuidList(new List { Guid.NewGuid() }); - break; - case Enums.ResultValueType.AttachmentList: - field.SetAttachmentList(new List - { - new AttachmentFile - { - FileId = 1, - FileName = "Update attachment list file name", - Notes = "Updated notes." - } - }); - break; - case Enums.ResultValueType.ScoringGroupList: - field.SetScoringGroupList(new List - { - new ScoringGroup - { - ListValueId = Guid.NewGuid(), - MaximumScore = 1m, - Name = "Updated test scoring group", - Score = 1m, - } - }); - break; - case Enums.ResultValueType.FileList: - field.SetFileList(new List { random.Next(), random.Next(), random.Next(), }); - break; - default: - break; - } - } - } - } -} diff --git a/Onspring.API.SDK.Tests/Tests/OnspringClientReportsTests.cs b/Onspring.API.SDK.Tests/Tests/OnspringClientReportsTests.cs deleted file mode 100644 index f0296b1..0000000 --- a/Onspring.API.SDK.Tests/Tests/OnspringClientReportsTests.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Onspring.API.SDK.Models; -using Onspring.API.SDK.Tests.Infrastructure; -using Onspring.API.SDK.Tests.Infrastructure.Helpers; -using Onspring.API.SDK.Tests.Infrastructure.Http; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; - -namespace Onspring.API.SDK.Tests.Tests -{ - [TestClass, ExcludeFromCodeCoverage] - public class OnspringClientReportsTests - { - private const int _appIdWithReports = 1; - private const int _reportId = 1; - - private static OnspringClient _apiClient; - - [ClassInitialize] - public static void ClassInit(TestContext testContext) - { - var testConfiguration = TestConfiguration.LoadFromContext(testContext); - var httpClient = HttpClientFactory.GetHttpClient(testConfiguration); - - _apiClient = new OnspringClient(testConfiguration.ApiKey, httpClient); - } - - [TestMethod] - public async Task GetReportAsync() - { - var getResponse = await _apiClient.GetReportAsync(_reportId); - AssertHelper.AssertSuccess(getResponse); - } - - [TestMethod] - public async Task GetReportsForAppAsync() - { - var pagingRequest = new PagingRequest(1, 10); - var getResponse = await _apiClient.GetReportsForAppAsync(_appIdWithReports); - AssertHelper.AssertSuccess(getResponse); - AssertHelper.AssertPaging(pagingRequest, getResponse.Value); - } - } -} diff --git a/Onspring.API.SDK.Tests/Tests/Unit/FilterOperatorTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/FilterOperatorTests.cs new file mode 100644 index 0000000..4db13fe --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/FilterOperatorTests.cs @@ -0,0 +1,310 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Enums; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit +{ + [TestClass, ExcludeFromCodeCoverage] + public class FilterOperatorTests + { + [TestMethod] + public void Equal_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.Equal; + Assert.IsInstanceOfType(op); + Assert.AreEqual(1, op.Id); + Assert.AreEqual("eq", op.Name); + } + + [TestMethod] + public void Equal_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.Equal == FilterOperator.Equal; + Assert.IsTrue(result); + } + + [TestMethod] + public void Equal_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.Equal == FilterOperator.NotEqual; + Assert.IsFalse(result); + } + + [TestMethod] + public void Equal_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.Equal}"; + Assert.AreEqual("eq", op); + } + + [TestMethod] + public void NotEqual_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.NotEqual; + Assert.IsInstanceOfType(op); + Assert.AreEqual(2, op.Id); + Assert.AreEqual("ne", op.Name); + } + + [TestMethod] + public void NotEqual_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.NotEqual == FilterOperator.NotEqual; + Assert.IsTrue(result); + } + + [TestMethod] + public void NotEqual_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.NotEqual == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void NotEqual_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.NotEqual}"; + Assert.AreEqual("ne", op); + } + + [TestMethod] + public void Contains_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.Contains; + Assert.IsInstanceOfType(op); + Assert.AreEqual(3, op.Id); + Assert.AreEqual("contains", op.Name); + } + + [TestMethod] + public void Contains_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.Contains == FilterOperator.Contains; + Assert.IsTrue(result); + } + + [TestMethod] + public void Contains_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.Contains == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void Contains_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.Contains}"; + Assert.AreEqual("contains", op); + } + + [TestMethod] + public void IsNull_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.IsNull; + Assert.IsInstanceOfType(op); + Assert.AreEqual(4, op.Id); + Assert.AreEqual("isnull", op.Name); + } + + [TestMethod] + public void IsNull_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.IsNull == FilterOperator.IsNull; + Assert.IsTrue(result); + } + + [TestMethod] + public void IsNull_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.IsNull == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void IsNull_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.IsNull}"; + Assert.AreEqual("isnull", op); + } + + [TestMethod] + public void NotNull_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.NotNull; + Assert.IsInstanceOfType(op); + Assert.AreEqual(5, op.Id); + Assert.AreEqual("notnull", op.Name); + } + + [TestMethod] + public void NotNull_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.NotNull == FilterOperator.NotNull; + Assert.IsTrue(result); + } + + [TestMethod] + public void NotNull_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.NotNull == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void NotNull_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.NotNull}"; + Assert.AreEqual("notnull", op); + } + + [TestMethod] + public void GreaterThan_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.GreaterThan; + Assert.IsInstanceOfType(op); + Assert.AreEqual(6, op.Id); + Assert.AreEqual("gt", op.Name); + } + + [TestMethod] + public void GreaterThan_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.GreaterThan == FilterOperator.GreaterThan; + Assert.IsTrue(result); + } + + [TestMethod] + public void GreaterThan_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.GreaterThan == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void GreaterThan_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.GreaterThan}"; + Assert.AreEqual("gt", op); + } + + [TestMethod] + public void LessThan_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.LessThan; + Assert.IsInstanceOfType(op); + Assert.AreEqual(7, op.Id); + Assert.AreEqual("lt", op.Name); + } + + [TestMethod] + public void LessThan_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.LessThan == FilterOperator.LessThan; + Assert.IsTrue(result); + } + + [TestMethod] + public void LessThan_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.LessThan == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void LessThan_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.LessThan}"; + Assert.AreEqual("lt", op); + } + + [TestMethod] + public void And_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.And; + Assert.IsInstanceOfType(op); + Assert.AreEqual(8, op.Id); + Assert.AreEqual("and", op.Name); + } + + [TestMethod] + public void And_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.And == FilterOperator.And; + Assert.IsTrue(result); + } + + [TestMethod] + public void And_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.And == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void And_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.And}"; + Assert.AreEqual("and", op); + } + + [TestMethod] + public void Or_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.Or; + Assert.IsInstanceOfType(op); + Assert.AreEqual(9, op.Id); + Assert.AreEqual("or", op.Name); + } + + [TestMethod] + public void Or_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.Or == FilterOperator.Or; + Assert.IsTrue(result); + } + + [TestMethod] + public void Or_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.Or == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void Or_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.Or}"; + Assert.AreEqual("or", op); + } + + [TestMethod] + public void Not_WhenCalled_ItShouldReturnCorrectOperator() + { + var op = FilterOperator.Not; + Assert.IsInstanceOfType(op); + Assert.AreEqual(10, op.Id); + Assert.AreEqual("not", op.Name); + } + + [TestMethod] + public void Not_WhenComparedToItself_ItShouldReturnTrue() + { + var result = FilterOperator.Not == FilterOperator.Not; + Assert.IsTrue(result); + } + + [TestMethod] + public void Not_WhenComparedToAnotherOperator_ItShouldReturnFalse() + { + var result = FilterOperator.Not == FilterOperator.Equal; + Assert.IsFalse(result); + } + + [TestMethod] + public void Not_WhenToStringIsCalled_ItShouldReturnProperName() + { + var op = $"{FilterOperator.Not}"; + Assert.AreEqual("not", op); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/FilterTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/FilterTests.cs new file mode 100644 index 0000000..b3e50e8 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/FilterTests.cs @@ -0,0 +1,146 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit +{ + [TestClass, ExcludeFromCodeCoverage] + public class FilterTests + { + [TestMethod] + public void Filter_ParameterlessConstructorWhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var filter = new Filter(); + Assert.AreEqual(0, filter.FieldId); + Assert.AreEqual(null, filter.Operator); + Assert.AreEqual(null, filter.Value); + } + + [TestMethod] + public void Filter_WhenActionInvokedOn_ItShouldAnInstanceWithPropertiesSet() + { + var fieldId = 1; + var op = FilterOperator.Equal; + var value = 1; + var filter = new Filter(); + var action = (Filter filter) => + { + filter.FieldId = 1; + filter.Operator = op; + filter.Value = value; + }; + + action.Invoke(filter); + + Assert.AreEqual(fieldId, filter.FieldId); + Assert.AreEqual(op, filter.Operator); + Assert.AreEqual(value, filter.Value); + } + + [TestMethod] + public void Filter_ConstructorWhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var fieldId = 1; + var op = FilterOperator.Equal; + var value = 1; + + var filter = new Filter(fieldId, op, value); + + Assert.AreEqual(fieldId, filter.FieldId); + Assert.AreEqual(op, filter.Operator); + Assert.AreEqual(value, filter.Value); + } + + [TestMethod] + public void Filter_ConstructorWhenCalledAndOperatorIsNotANullOperatorAndValueIsNull_ItShouldThrowException() + { + var action = () => new Filter(1, FilterOperator.And, null); + Assert.ThrowsException(action); + } + + [TestMethod] + public void Filter_ConstructorWhenCalledAndOperatorIsNotNullOperatorAndValueIsNull_ItShouldReturnAnInstanceWithPropertiesSet() + { + var fieldId = 1; + var op = FilterOperator.NotNull; + object value = null; + + var filter = new Filter(fieldId, op, value); + + Assert.AreEqual(fieldId, filter.FieldId); + Assert.AreEqual(op, filter.Operator); + Assert.AreEqual(value, filter.Value); + } + + [TestMethod] + public void Filter_ConstructorWhenCalledAndOperatorIsIsNullOperatorAndValueIsNull_ItShouldReturnAnInstanceWithPropertiesSet() + { + var fieldId = 1; + var op = FilterOperator.IsNull; + object value = null; + + var filter = new Filter(fieldId, op, value); + + Assert.AreEqual(fieldId, filter.FieldId); + Assert.AreEqual(op, filter.Operator); + Assert.AreEqual(value, filter.Value); + } + + [TestMethod] + public void Filter_WhenValueIsSetToNullAndOperatorIsNotANullOperator_ItShouldThrowAnException() + { + var filter = new Filter(1, FilterOperator.Equal, 1); + var action = () => filter.Value = null; + Assert.ThrowsException(action); + } + + [TestMethod] + public void Filter_WhenValueIsSetToNullAndOperatorIsNotNullOperator_ItShouldSetValueProperty() + { + var filter = new Filter(1, FilterOperator.NotNull, 1); + filter.Value = null; + Assert.AreEqual(null, filter.Value); + } + + [TestMethod] + public void Filter_WhenValueIsSetToNullAndOperatorIsIsNullOperator_ItShouldSetValueProperty() + { + var filter = new Filter(1, FilterOperator.IsNull, 1); + filter.Value = null; + Assert.AreEqual(null, filter.Value); + } + + [TestMethod] + public void Filter_ToStringWhenCalledAndValueIsNull_ItShouldReturnProperFilterString() + { + var filter = new Filter(1, FilterOperator.NotNull, null); + Assert.AreEqual("1 notnull", filter.ToString()); + } + + [TestMethod] + public void Filter_ToStringWhenCalledAndValueIsDateTime_ItShouldReturnProperFilterString() + { + var date = DateTime.UtcNow; + var filter = new Filter(1, FilterOperator.Equal, date); + Assert.AreEqual($"1 eq datetime'{date:O}'", $"{filter}"); + } + + [TestMethod] + public void Filter_ToStringWhenCalledAndValueIsString_ItShouldReturnProperFilterString() + { + var stringValue = "hello"; + var filter = new Filter(1, FilterOperator.Equal, stringValue); + Assert.AreEqual($"1 eq '{stringValue}'", filter.ToString()); + } + + [TestMethod] + public void Filter_ToStringWhenCalledAndValueIsNumber_ItShouldReturnProperFilterString() + { + var num = 1; + var filter = new Filter(1, FilterOperator.Equal, num); + Assert.AreEqual($"1 eq {num}", filter.ToString()); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAllAppsPagesRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAllAppsPagesRequestBuilderTests.cs new file mode 100644 index 0000000..bac1c7a --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAllAppsPagesRequestBuilderTests.cs @@ -0,0 +1,60 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllAppsPagesRequestBuilderTests + { + private static IOnspringClient _client; + private static GetAllAppsPagesRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllAppsPagesRequestBuilder(_client); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstance() + { + var builder = new GetAllAppsPagesRequestBuilder(_client); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetPageSize() + { + var pageSize = 100; + + var builder = new GetAllAppsPagesRequestBuilder(_client).WithPageSize(pageSize); + + Assert.AreEqual(pageSize, builder.PageSize); + } + + [TestMethod] + public void SendAsync_WhenCalled_ItShouldReturnAnAsyncEnumerableApiResponse() + { + var result = _builder.SendAsync(); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + + [TestMethod] + public void SendAsyncWithOptions_WhenCalled_ItShouldReturnAnAsyncEnumerableApiResponse() + { + var result = _builder.SendAsync(options => options.PageSize = 100); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppByIdRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppByIdRequestBuilderTests.cs new file mode 100644 index 0000000..27b693e --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppByIdRequestBuilderTests.cs @@ -0,0 +1,53 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAppByIdRequestBuilderTests + { + private static readonly int _appId = 1; + private static IOnspringClient _client; + private static GetAppByIdRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAppByIdRequestBuilder(_client, _appId); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var builder = new GetAppByIdRequestBuilder(_client, _appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new App(), + }; + + _client + .GetAppAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppsByIdsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppsByIdsRequestBuilderTests.cs new file mode 100644 index 0000000..c80aa51 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppsByIdsRequestBuilderTests.cs @@ -0,0 +1,54 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAppsByIdsRequestBuilderTests + { + private static readonly IEnumerable _appIds = new[] { 1, 2, 3 }; + private static IOnspringClient _client; + private static GetAppsByIdsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAppsByIdsRequestBuilder(_client, _appIds); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var builder = new GetAppsByIdsRequestBuilder(_client, _appIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appIds, builder.AppIds); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetAppsResponse(), + }; + + _client + .GetAppsAsync(Arg.Any>()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppsRequestBuilderTests.cs new file mode 100644 index 0000000..0d2d975 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetAppsRequestBuilderTests.cs @@ -0,0 +1,53 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAppsRequestBuilderTests + { + private static readonly int _pageNumber = 1; + private static readonly int _appId = 1; + private static readonly IEnumerable _appIds = new[] { 1, 2, 3 }; + private static IOnspringClient _client; + private static GetAppsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAppsRequestBuilder(_client); + } + + [TestMethod] + public void ForPage_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var builder = _builder.ForPage(_pageNumber); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_pageNumber, builder.PageNumber); + } + + [TestMethod] + public void WithIds_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var builder = _builder.WithIds(_appIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appIds, builder.AppIds); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var builder = _builder.WithId(_appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetPagedAppsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetPagedAppsRequestBuilderTests.cs new file mode 100644 index 0000000..494e8eb --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Apps/GetPagedAppsRequestBuilderTests.cs @@ -0,0 +1,64 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + + public class GetPagedAppsRequestBuilderTests + { + private static readonly int _pageNumber = 1; + private static IOnspringClient _client; + private static GetPagedAppsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetPagedAppsRequestBuilder(_client, _pageNumber); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var builder = new GetPagedAppsRequestBuilder(_client, _pageNumber); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_pageNumber, builder.PageNumber); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetPageSizeProperty() + { + var pageSize = 5; + + _builder.WithPageSize(pageSize); + + Assert.AreEqual(pageSize, _builder.PageSize); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedAppsResponse(), + }; + + _client + .GetAppsAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilderTests.cs new file mode 100644 index 0000000..aeec49e --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilderTests.cs @@ -0,0 +1,62 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllFieldsPagesByAppRequestBuilderTests + { + private static readonly int _appId = 1; + private static IOnspringClient _client; + private static GetAllFieldsPagesByAppRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllFieldsPagesByAppRequestBuilder(_client, _appId); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnInstanceWithPropertiesSet() + { + var builder = new GetAllFieldsPagesByAppRequestBuilder(_client, _appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldReturnInstanceWithPageSizeSet() + { + var pageSize = 100; + + var result = _builder.WithPageSize(pageSize); + + Assert.IsInstanceOfType(result); + Assert.AreEqual(pageSize, result.PageSize); + } + + [TestMethod] + public void SendAsync_WhenCalled_ItShouldReturnAsyncEnumerable() + { + var result = _builder.SendAsync(); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + + [TestMethod] + public void SendAsyncWithOptions_WhenCalled_ItShouldReturnAsyncEnumerable() + { + var result = _builder.SendAsync(options => options.PageSize = 100); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetAllFieldsPagesRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetAllFieldsPagesRequestBuilderTests.cs new file mode 100644 index 0000000..d4d0e90 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetAllFieldsPagesRequestBuilderTests.cs @@ -0,0 +1,37 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllFieldsPagesRequestBuilderTests + { + private static IOnspringClient _client; + private static GetAllFieldsPagesRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllFieldsPagesRequestBuilder(_client); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnInstance() + { + var builder = new GetAllFieldsPagesRequestBuilder(_client); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void FromApp_WhenCalled_ItShouldReturnInstance() + { + var result = _builder.FromApp(1); + + Assert.IsInstanceOfType(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldByIdRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldByIdRequestBuilderTests.cs new file mode 100644 index 0000000..3b3c9fc --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldByIdRequestBuilderTests.cs @@ -0,0 +1,53 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetFieldByIdRequestBuilderTests + { + private static readonly int _fieldId = 1; + private static IOnspringClient _client; + private static GetFieldByIdRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetFieldByIdRequestBuilder(_client, _fieldId); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnInstanceWithPropertiesSet() + { + var builder = new GetFieldByIdRequestBuilder(_client, _fieldId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_fieldId, builder.FieldId); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new Field(), + }; + + _client + .GetFieldAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsByAppRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsByAppRequestBuilderTests.cs new file mode 100644 index 0000000..e4b63d7 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsByAppRequestBuilderTests.cs @@ -0,0 +1,93 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetFieldsByAppRequestBuilderTests + { + private static readonly int _appId = 1; + private static readonly int _pageNumber = 2; + private static readonly int _pageSize = 25; + private static IOnspringClient _client; + private static GetFieldsByAppRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetFieldsByAppRequestBuilder(_client, _appId); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnInstanceWithPropertiesSet() + { + var builder = new GetFieldsByAppRequestBuilder(_client, _appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + } + + [TestMethod] + public void ForPage_WhenCalled_ItShouldSetPageNumberProperty() + { + _builder.ForPage(_pageNumber); + + Assert.AreEqual(_pageNumber, _builder.PageNumber); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetPageSizeProperty() + { + _builder.WithPageSize(_pageSize); + + Assert.AreEqual(_pageSize, _builder.PageSize); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedFieldsResponse(), + }; + + _client + .GetFieldsForAppAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedFieldsResponse(), + }; + + _client + .GetFieldsForAppAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(options => + { + options.PageNumber = 2; + options.PageSize = 25; + }); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsByIdsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsByIdsRequestBuilderTests.cs new file mode 100644 index 0000000..77ba7a5 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsByIdsRequestBuilderTests.cs @@ -0,0 +1,54 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetFieldsByIdsRequestBuilderTests + { + private static readonly IEnumerable _fieldIds = new[] { 1, 2, 3 }; + private static IOnspringClient _client; + private static GetFieldsByIdsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetFieldsByIdsRequestBuilder(_client, _fieldIds); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnInstanceWithPropertiesSet() + { + var builder = new GetFieldsByIdsRequestBuilder(_client, _fieldIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_fieldIds, builder.FieldIds); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetFieldsResponse(), + }; + + _client + .GetFieldsAsync(Arg.Any>()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsRequestBuilderTests.cs new file mode 100644 index 0000000..31525b2 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Fields/GetFieldsRequestBuilderTests.cs @@ -0,0 +1,53 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetFieldsRequestBuilderTests + { + private static readonly int _appId = 1; + private static readonly int _fieldId = 1; + private static readonly IEnumerable _fieldIds = new[] { 1, 2, 3 }; + private static IOnspringClient _client; + private static GetFieldsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetFieldsRequestBuilder(_client); + } + + [TestMethod] + public void FromApp_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var builder = _builder.FromApp(_appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var builder = _builder.WithId(_fieldId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.FieldId); + } + + [TestMethod] + public void WithIds_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var builder = _builder.WithIds(_fieldIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_fieldIds, builder.FieldIds); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Add/AddFileRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Add/AddFileRequestBuilderTests.cs new file mode 100644 index 0000000..37118c1 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Add/AddFileRequestBuilderTests.cs @@ -0,0 +1,114 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class AddFileRequestBuilderTests + { + private static readonly int _recordId = 1; + private static readonly int _fieldId = 1; + private static readonly string _name = "name"; + private static readonly Stream _stream = new MemoryStream(); + private static readonly string _type = "text/plain"; + private static readonly string _notes = "notes"; + private static readonly DateTime _modifiedDate = DateTime.UtcNow; + private static IOnspringClient _client; + private static AddFileRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new AddFileRequestBuilder(_client); + } + + [TestMethod] + public void ToRecord_WhenCalled_ItShouldSetRecordIdProperty() + { + _builder.ToRecord(_recordId); + + Assert.AreEqual(_recordId, _builder.RecordId); + } + + [TestMethod] + public void InField_WhenCalled_ItShouldSetFieldIdProperty() + { + _builder.InField(_fieldId); + + Assert.AreEqual(_fieldId, _builder.FieldId); + } + + [TestMethod] + public void WithName_WhenCalled_ItShouldSetNameProperty() + { + _builder.WithName(_name); + + Assert.AreEqual(_name, _builder.Name); + } + + [TestMethod] + public void WithStream_WhenCalled_ItShouldSetStreamProperty() + { + _builder.WithStream(_stream); + + Assert.AreEqual(_stream, _builder.FileStream); + } + + [TestMethod] + public void WithType_WhenCalled_ItShouldSetTypeProperty() + { + _builder.WithType(_type); + + Assert.AreEqual(_type, _builder.Type); + } + + [TestMethod] + public void WithNotes_WhenCalled_ItShouldSetNotesProperty() + { + _builder.WithNotes(_notes); + + Assert.AreEqual(_notes, _builder.Notes); + } + + [TestMethod] + public void WithModifiedDate_WhenCalled_ItShouldSetModifiedDateProperty() + { + _builder.WithModifiedDate(null); + + Assert.AreEqual(null, _builder.ModifiedDate); + + _builder.WithModifiedDate(_modifiedDate); + + Assert.AreEqual(_modifiedDate, _builder.ModifiedDate); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse> + { + StatusCode = HttpStatusCode.Created, + Value = new CreatedWithIdResponse + { + Id = 1, + } + }; + + _client + .SaveFileAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Delete/DeleteFileRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Delete/DeleteFileRequestBuilderTests.cs new file mode 100644 index 0000000..c90df3c --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Delete/DeleteFileRequestBuilderTests.cs @@ -0,0 +1,64 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class DeleteFileRequestBuilderTests + { + private static readonly int _recordId = 1; + private static readonly int _fieldId = 1; + private static readonly int _fileId = 1; + private static IOnspringClient _client; + private static DeleteFileRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new DeleteFileRequestBuilder(_client); + } + + [TestMethod] + public void FromRecord_WhenCalled_ItShouldSetRecordIdProperties() + { + _builder.FromRecord(_recordId); + + Assert.AreEqual(_recordId, _builder.RecordId); + } + + [TestMethod] + public void InField_WhenCalled_ItShouldSetFieldIdProperties() + { + _builder.InField(_fieldId); + + Assert.AreEqual(_fieldId, _builder.FieldId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldSetFileIdProperties() + { + _builder.WithId(_fileId); + + Assert.AreEqual(_fileId, _builder.FileId); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse(); + + _client + .DeleteFileAsync(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Get/GetFileInfoRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Get/GetFileInfoRequestBuilderTests.cs new file mode 100644 index 0000000..1a8587a --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Get/GetFileInfoRequestBuilderTests.cs @@ -0,0 +1,69 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetFileInfoRequestBuilderTests + { + private static readonly int _recordId = 1; + private static readonly int _fieldId = 1; + private static readonly int _fileId = 1; + private static IOnspringClient _client; + private static GetFileInfoRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetFileInfoRequestBuilder(_client); + } + + [TestMethod] + public void FromRecord_WhenCalled_ItShouldSetRecordIdProperties() + { + _builder.FromRecord(_recordId); + + Assert.AreEqual(_recordId, _builder.RecordId); + } + + [TestMethod] + public void InField_WhenCalled_ItShouldSetFieldIdProperties() + { + _builder.InField(_fieldId); + + Assert.AreEqual(_fieldId, _builder.FieldId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldSetFileIdProperties() + { + _builder.WithId(_fileId); + + Assert.AreEqual(_fileId, _builder.FileId); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetFileInfoResponse(), + }; + + _client + .GetFileInfoAsync(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Get/GetFileRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Get/GetFileRequestBuilderTests.cs new file mode 100644 index 0000000..061641a --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Files/Get/GetFileRequestBuilderTests.cs @@ -0,0 +1,69 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetFileRequestBuilderTests + { + private static readonly int _recordId = 1; + private static readonly int _fieldId = 1; + private static readonly int _fileId = 1; + private static IOnspringClient _client; + private static GetFileRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetFileRequestBuilder(_client); + } + + [TestMethod] + public void FromRecord_WhenCalled_ItShouldSetRecordIdProperties() + { + _builder.FromRecord(_recordId); + + Assert.AreEqual(_recordId, _builder.RecordId); + } + + [TestMethod] + public void InField_WhenCalled_ItShouldSetFieldIdProperties() + { + _builder.InField(_fieldId); + + Assert.AreEqual(_fieldId, _builder.FieldId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldSetFileIdProperties() + { + _builder.WithId(_fileId); + + Assert.AreEqual(_fileId, _builder.FileId); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetFileResponse(), + }; + + _client + .GetFileAsync(Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Lists/Delete/DeleteListValueRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Lists/Delete/DeleteListValueRequestBuilderTests.cs new file mode 100644 index 0000000..163f057 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Lists/Delete/DeleteListValueRequestBuilderTests.cs @@ -0,0 +1,57 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class DeleteListValueRequestBuilderTests + { + private static readonly int _listId = 1; + private static readonly Guid _id = Guid.NewGuid(); + + private static IOnspringClient _client; + private static DeleteListValueRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new DeleteListValueRequestBuilder(_client); + } + + [TestMethod] + public void InList_WhenCalled_ItShouldSetListIdProperty() + { + _builder.InList(_listId); + + Assert.AreEqual(_listId, _builder.ListId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldSetIdProperty() + { + _builder.WithId(_id); + + Assert.AreEqual(_id, _builder.Id); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnApiResponse() + { + var apiResponse = new ApiResponse(); + + _client + .DeleteListItemAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Lists/Save/SaveListValueRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Lists/Save/SaveListValueRequestBuilderTests.cs new file mode 100644 index 0000000..eb4a330 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Lists/Save/SaveListValueRequestBuilderTests.cs @@ -0,0 +1,88 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class SaveListValueRequestBuilderTests + { + private static readonly int _listId = 1; + private static readonly Guid? _id = Guid.NewGuid(); + private static readonly string _name = "Name"; + private static readonly decimal _numValue = 1; + private static readonly string _color = "#db3e3e"; + private static IOnspringClient _client; + private static SaveListValueRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new SaveListValueRequestBuilder(_client); + } + + [TestMethod] + public void InList_WhenCalled_ItShouldSetListIdProperty() + { + _builder.InList(_listId); + + Assert.AreEqual(_listId, _builder.ListId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldSetIdProperty() + { + _builder.WithId(_id); + + Assert.AreEqual(_id, _builder.Id); + } + + [TestMethod] + public void WithName_WhenCalled_ItShouldSetNameProperty() + { + _builder.WithName(_name); + + Assert.AreEqual(_name, _builder.Name); + } + + [TestMethod] + public void WithColor_WhenCalled_ItShouldSetColorProperty() + { + _builder.WithColor(_color); + + Assert.AreEqual(_color, _builder.Color); + } + + [TestMethod] + public void WithNumericValue_WhenCalled_ItShouldSetNumericValueProperty() + { + _builder.WithNumericValue(_numValue); + + Assert.AreEqual(_numValue, _builder.NumericValue); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new SaveListItemResponse(Guid.NewGuid()), + }; + + _client + .SaveListItemAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/OnspringRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/OnspringRequestBuilderTests.cs new file mode 100644 index 0000000..a9ad801 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/OnspringRequestBuilderTests.cs @@ -0,0 +1,109 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringRequestTests + { + private static OnspringRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var apiClientMock = Substitute.For(); + _builder = new OnspringRequestBuilder(apiClientMock); + } + + [TestMethod] + public void ToGetRecords_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToGetRecords(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToCheckConnection_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToCheckConnection(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToSaveRecord_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToSaveRecord(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToDeleteRecords_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToDeleteRecords(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToGetReports_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToGetReports(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToGetReportData_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToGetReportData(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToGetFile_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToGetFile(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToGetFileInfo_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToGetFileInfo(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToDeleteFile_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToDeleteFile(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToAddFile_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToAddFile(); + + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void ToGetFields_WhenCalled_ShouldReturnBuilderInstance() + { + var builder = _builder.ToGetFields(); + + Assert.IsInstanceOfType(builder); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Ping/ConnectionRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Ping/ConnectionRequestBuilderTests.cs new file mode 100644 index 0000000..767907b --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Ping/ConnectionRequestBuilderTests.cs @@ -0,0 +1,32 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Integration.Fluent +{ + public class ConnectionRequestBuilderTests + { + private static IOnspringClient _client; + private static ConnectionRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new ConnectionRequestBuilder(_client); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnBooleanConnectionIndicator() + { + var canConnect = false; + + _client.CanConnectAsync().Returns(canConnect); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(canConnect, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordByIdRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordByIdRequestBuilderTests.cs new file mode 100644 index 0000000..aca041b --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordByIdRequestBuilderTests.cs @@ -0,0 +1,51 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class DeleteRecordByIdRequestBuilderTests + { + private static IOnspringClient _client; + private static DeleteRecordByIdRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new DeleteRecordByIdRequestBuilder(_client, 1, 1); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var appId = 1; + var recordId = 1; + var builder = new DeleteRecordByIdRequestBuilder(_client, appId, recordId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + Assert.AreEqual(recordId, builder.RecordId); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse(); + + _client + .DeleteRecordAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsByAppRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsByAppRequestBuilderTests.cs new file mode 100644 index 0000000..1343791 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsByAppRequestBuilderTests.cs @@ -0,0 +1,56 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class DeleteRecordsByAppRequestBuilderTests + { + private static IOnspringClient _client; + private static DeleteRecordsByAppRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new DeleteRecordsByAppRequestBuilder(_client, 1); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var appId = 1; + var builder = new DeleteRecordsByAppRequestBuilder(_client, appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + } + + [TestMethod] + public void WithId_WhenCalled_ItShouldReturnCorrectBuilderInstanceWithPropertiesSet() + { + var recordId = 1; + + var builder = _builder.WithId(recordId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_builder.AppId, builder.AppId); + Assert.AreEqual(recordId, builder.RecordId); + } + + [TestMethod] + public void WithIds_WhenCalled_ItShouldReturnCorrectBuilderInstanceWithPropertiesSet() + { + var recordIds = new[] { 1, 2, 3 }; + + var builder = _builder.WithIds(recordIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_builder.AppId, builder.AppId); + Assert.AreEqual(recordIds, builder.RecordIds); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsByIdsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsByIdsRequestBuilderTests.cs new file mode 100644 index 0000000..2db6b3e --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsByIdsRequestBuilderTests.cs @@ -0,0 +1,50 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class DeleteRecordsByIdsRequestBuilderTests + { + private static IOnspringClient _client; + private static DeleteRecordsByIdsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new DeleteRecordsByIdsRequestBuilder(_client, 1, new[] { 1, 2, 3 }); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var appId = 1; + var recordIds = new[] { 1, 2, 3 }; + var builder = new DeleteRecordsByIdsRequestBuilder(_client, appId, recordIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + Assert.AreEqual(recordIds, builder.RecordIds); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse(); + + _client + .DeleteRecordsAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsRequestBuilderTests.cs new file mode 100644 index 0000000..5e6dba2 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Delete/DeleteRecordsRequestBuilderTests.cs @@ -0,0 +1,31 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class DeleteRecordsRequestBuilderTests + { + private static DeleteRecordsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var apiClientMock = Substitute.For(); + _builder = new DeleteRecordsRequestBuilder(apiClientMock); + } + + [TestMethod] + public void FromApp_WhenCalled_ShouldReturnADeleteRecordsByAppRequestBuilderInstanceWithAppIdSetToCorrectValue() + { + var appId = 1; + var builder = _builder.FromApp(appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilderTests.cs new file mode 100644 index 0000000..f44404d --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilderTests.cs @@ -0,0 +1,127 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllRecordsPagesByAppRequestBuilderTests + { + private static readonly int _appId = 1; + private static IOnspringClient _client; + private static GetAllRecordsPagesByAppRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstance() + { + var builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + Assert.AreEqual(50, builder.PageSize); + Assert.AreEqual(DataFormat.Raw, builder.DataFormat); + Assert.AreEqual(0, builder.FieldIds.Count()); + } + + [TestMethod] + public void WithDataFormat_WhenCalled_ItShouldReturnAnInstance() + { + var dataFormat = DataFormat.Raw; + var builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId) + .WithDataFormat(dataFormat); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(dataFormat, builder.DataFormat); + } + + [TestMethod] + public void WithFields_WhenCalled_ItShouldReturnAnInstance() + { + var fieldIds = new[] { 1, 2, 3 }; + var builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId) + .WithFields(fieldIds); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(fieldIds, builder.FieldIds); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldReturnAnInstance() + { + var pageSize = 100; + var builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId) + .WithPageSize(pageSize); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(pageSize, builder.PageSize); + } + + [TestMethod] + public void WithFilter_WhenCalledWithFilterString_ItShouldReturnAnInstanceWithPropertiesSet() + { + var filter = "filter"; + var builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId) + .WithFilter(filter); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(filter, builder.Filter); + } + + [TestMethod] + public void WithFilter_WhenCalledWithFilterAction_ItShouldReturnAnInstanceWithPropertiesSet() + { + var filter = new Filter(1, FilterOperator.Equal, "value"); + var builder = new GetAllRecordsPagesByAppRequestBuilder(_client, _appId) + .WithFilter(f => + { + f.FieldId = filter.FieldId; + f.Operator = filter.Operator; + f.Value = filter.Value; + }); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(filter.ToString(), builder.Filter); + } + + [TestMethod] + public void SendAsync_WhenCalled_ItShouldReturnAnAsyncEnumerable() + { + var result = _builder.SendAsync(); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + + [TestMethod] + public void SendAsync_WhenCalledWithOptions_ItShouldReturnAnAsyncEnumerable() + { + var result = _builder.SendAsync(o => + { + o.PageSize = 100; + o.FieldIds = [1, 2, 3]; + o.DataFormat = DataFormat.Formatted; + }); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesByQueryRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesByQueryRequestBuilderTests.cs new file mode 100644 index 0000000..a897126 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesByQueryRequestBuilderTests.cs @@ -0,0 +1,183 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllRecordsPagesByQueryRequestBuilderTests + { + private static readonly int _appId = 1; + private static IOnspringClient _client; + private static GetAllRecordsPagesByQueryRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstance() + { + var builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(_appId, builder.AppId); + Assert.AreEqual(50, builder.PageSize); + Assert.AreEqual(DataFormat.Raw, builder.DataFormat); + Assert.AreEqual(0, builder.FieldIds.Count()); + } + + [TestMethod] + public void WithDataFormat_WhenCalled_ItShouldReturnAnInstance() + { + var dataFormat = DataFormat.Formatted; + var builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + + builder.WithDataFormat(dataFormat); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(dataFormat, builder.DataFormat); + } + + [TestMethod] + public void WithFields_WhenCalled_ItShouldReturnAnInstance() + { + var fieldIds = new[] { 1, 2, 3 }; + var builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + + builder.WithFields(fieldIds); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(fieldIds, builder.FieldIds); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldReturnAnInstance() + { + var pageSize = 100; + var builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + + builder.WithPageSize(pageSize); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(pageSize, builder.PageSize); + } + + [TestMethod] + public void WithFilter_WhenCalledWithFilterString_ItShouldReturnAnInstanceWithPropertiesSet() + { + var filter = "filter"; + var builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + + builder.WithFilter(filter); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(filter, builder.Filter); + } + + [TestMethod] + public void WithFilter_WhenCalledWithFilterAction_ItShouldReturnAnInstanceWithPropertiesSet() + { + var filter = new Filter(1, FilterOperator.Equal, "value"); + var builder = new GetAllRecordsPagesByQueryRequestBuilder( + _client, + _appId, + 50, + [], + DataFormat.Raw, + null + ); + + builder.WithFilter(f => + { + f.FieldId = filter.FieldId; + f.Operator = filter.Operator; + f.Value = filter.Value; + }); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + Assert.AreEqual(filter.ToString(), builder.Filter); + } + + [TestMethod] + public void SendAsync_WhenCalled_ItShouldReturnAnAsyncEnumerable() + { + var result = _builder.SendAsync(); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + + [TestMethod] + public void SendAsync_WhenCalledWithOptions_ItShouldReturnAnAsyncEnumerable() + { + var result = _builder + .WithFilter("filter") + .SendAsync(o => + { + o.PageSize = 100; + o.FieldIds = [1, 2, 3]; + o.DataFormat = DataFormat.Formatted; + }); + + Assert.IsNotNull(result); + Assert.IsInstanceOfType>>(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesRequestBuilderTests.cs new file mode 100644 index 0000000..da5eeea --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetAllRecordsPagesRequestBuilderTests.cs @@ -0,0 +1,40 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllRecordsPagesRequestBuilderTests + { + private static IOnspringClient _client; + private static GetAllRecordsPagesRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllRecordsPagesRequestBuilder(_client); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstance() + { + var builder = new GetAllRecordsPagesRequestBuilder(_client); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + } + + [TestMethod] + public void FromApp_WhenCalled_ItShouldReturnAnInstance() + { + var appId = 1; + var builder = _builder.FromApp(appId); + + Assert.IsNotNull(builder); + Assert.IsInstanceOfType(builder); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordByIdRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordByIdRequestBuilderTests.cs new file mode 100644 index 0000000..76921fb --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordByIdRequestBuilderTests.cs @@ -0,0 +1,101 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetRecordByIdRequestBuilderTests + { + private static IOnspringClient _client; + private static GetRecordByIdRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetRecordByIdRequestBuilder(_client, 1, 1); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var appId = 1; + var recordId = 1; + var builder = new GetRecordByIdRequestBuilder(_client, appId, recordId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + Assert.AreEqual(recordId, builder.RecordId); + Assert.AreEqual(Enumerable.Empty(), builder.FieldIds); + Assert.AreEqual(DataFormat.Raw, builder.Format); + } + + [TestMethod] + public void WithFieldIds_WhenCalled_ItShouldSetInstancesFieldIds() + { + var fieldIds = new[] { 1, 2, 4, }; + + _builder.WithFieldIds(fieldIds); + + Assert.AreEqual(fieldIds, _builder.FieldIds); + } + + [TestMethod] + public void WithFormat_WhenCalled_ItShouldSetInstancesFormat() + { + var fieldIds = new[] { 1, 2, 4, }; + + _builder.WithFormat(DataFormat.Formatted); + + Assert.AreEqual(DataFormat.Formatted, _builder.Format); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new ResultRecord(), + }; + + _client + .GetRecordAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new ResultRecord(), + }; + + _client + .GetRecordAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder + .SendAsync(options => + { + options.Format = DataFormat.Raw; + }); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilderTests.cs new file mode 100644 index 0000000..e17bd52 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilderTests.cs @@ -0,0 +1,114 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetRecordsByAppPagedRequestBuilderTests + { + private static IOnspringClient _client; + private static GetRecordsByAppPagedRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetRecordsByAppPagedRequestBuilder(_client, 1, 1); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var appId = 1; + var pageNumber = 1; + var builder = new GetRecordsByAppPagedRequestBuilder(_client, appId, pageNumber); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + Assert.AreEqual(pageNumber, builder.PageNumber); + Assert.AreEqual(Enumerable.Empty(), builder.FieldIds); + Assert.AreEqual(DataFormat.Raw, builder.Format); + Assert.AreEqual(50, builder.PageSize); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetInstancesPageSize() + { + var pageSize = 1; + + _builder.WithPageSize(pageSize); + + Assert.AreEqual(pageSize, _builder.PageSize); + } + + + [TestMethod] + public void WithFieldIds_WhenCalled_ItShouldSetInstancesFieldIds() + { + var fieldIds = new int[] { 1, 2, 4 }; + + _builder.WithFieldIds(fieldIds); + + Assert.AreEqual(fieldIds, _builder.FieldIds); + } + + [TestMethod] + public void WithFormat_WhenCalled_ItShouldSetInstancesFormat() + { + var format = DataFormat.Formatted; + + _builder.WithFormat(format); + + Assert.AreEqual(format, _builder.Format); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedRecordsResponse(), + }; + + _client + .GetRecordsForAppAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedRecordsResponse(), + }; + + _client + .GetRecordsForAppAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(options => + { + options.PageSize = 10; + options.FieldIds = new[] { 1, 2, 3 }; + options.Format = DataFormat.Raw; + }); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByAppRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByAppRequestBuilderTests.cs new file mode 100644 index 0000000..19017bf --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByAppRequestBuilderTests.cs @@ -0,0 +1,106 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetRecordsByAppRequestBuilderTests + { + private static IOnspringClient _client; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + } + + [TestMethod] + public void Constructor_WhenCalled_ReturnsInstanceOfBuilder() + { + var appId = 1; + var builder = new GetRecordsByAppRequestBuilder(_client, appId); + + Assert.AreEqual(appId, builder.AppId); + } + + [TestMethod] + public void ForPage_WhenCalled_ReturnsInstanceOfPagedAppBuilderWithPropetiesSet() + { + var appId = 1; + var pageNumber = 1; + var builder = new GetRecordsByAppRequestBuilder(_client, appId); + + var pagedBuilder = builder.ForPage(pageNumber); + + Assert.IsInstanceOfType(pagedBuilder); + Assert.AreEqual(appId, pagedBuilder.AppId); + Assert.AreEqual(pageNumber, pagedBuilder.PageNumber); + } + + [TestMethod] + public void WithId_WhenCalled_ReturnsRecordByIdBuilderWithPropertiesSet() + { + var appId = 1; + var recordId = 1; + var builder = new GetRecordsByAppRequestBuilder(_client, appId); + + var recordByIdBuilder = builder.WithId(recordId); + + Assert.IsInstanceOfType(recordByIdBuilder); + Assert.AreEqual(appId, recordByIdBuilder.AppId); + Assert.AreEqual(recordId, recordByIdBuilder.RecordId); + } + + [TestMethod] + public void WithIds_WhenCalled_ReturnsRecordsByIdsBuilderWithPropertiesSet() + { + var appId = 1; + var recordIds = new[] { 1, 2, 3 }; + var builder = new GetRecordsByAppRequestBuilder(_client, appId); + + var recordsByIdsBuilder = builder.WithIds(recordIds); + + Assert.IsInstanceOfType(recordsByIdsBuilder); + Assert.AreEqual(appId, recordsByIdsBuilder.AppId); + Assert.AreEqual(recordIds, recordsByIdsBuilder.RecordIds); + } + + [TestMethod] + public void WithFilter_WhenCalledWithFilterString_ReturnsQueryRecordsBuilderWithPropertiesSet() + { + var appId = 1; + var filter = new Filter(1, FilterOperator.Equal, 1); + var builder = new GetRecordsByAppRequestBuilder(_client, appId); + + var queryRecordsBuilder = builder.WithFilter(filter.ToString()); + + Assert.IsInstanceOfType(queryRecordsBuilder); + Assert.AreEqual(appId, queryRecordsBuilder.AppId); + Assert.AreEqual(filter.ToString(), queryRecordsBuilder.Filter); + } + + [TestMethod] + public void WithFilter_WhenCalledWithFilterAction_ReturnsQueryRecordsBuilderWithPropertiesSet() + { + var appId = 1; + var filter = new Filter(1, FilterOperator.Equal, 1); + var builder = new GetRecordsByAppRequestBuilder(_client, appId); + + var queryRecordsBuilder = builder.WithFilter(f => + { + f.FieldId = filter.FieldId; + f.Operator = filter.Operator; + f.Value = filter.Value; + }); + + Assert.IsInstanceOfType(queryRecordsBuilder); + Assert.AreEqual(appId, queryRecordsBuilder.AppId); + Assert.AreEqual(filter.ToString(), queryRecordsBuilder.Filter); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByIdsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByIdsRequestBuilderTests.cs new file mode 100644 index 0000000..5365ec9 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsByIdsRequestBuilderTests.cs @@ -0,0 +1,101 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetRecordsByIdsRequestBuilderTests + { + private static IOnspringClient _client; + private static GetRecordsByIdsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetRecordsByIdsRequestBuilder(_client, 1, new[] { 1, 2, 3 }); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var appId = 1; + var recordIds = new[] { 1, 2, 3 }; + var builder = new GetRecordsByIdsRequestBuilder(_client, appId, recordIds); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + Assert.AreEqual(recordIds, builder.RecordIds); + Assert.AreEqual(Enumerable.Empty(), builder.FieldIds); + Assert.AreEqual(DataFormat.Raw, builder.Format); + } + + [TestMethod] + public void WithFieldIds_WhenCalled_ItShouldSetInstancesFieldIds() + { + var fieldIds = new[] { 1, 2, 3 }; + + _builder.WithFieldIds(fieldIds); + + Assert.AreEqual(fieldIds, _builder.FieldIds); + } + + [TestMethod] + public void WithFormat_WhenCalled_ItShouldSetInstancesFormat() + { + var format = DataFormat.Formatted; + + _builder.WithFormat(format); + + Assert.AreEqual(format, _builder.Format); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetRecordsResponse(), + }; + + _client + .GetRecordsAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetRecordsResponse(), + }; + + _client + .GetRecordsAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(options => + { + options.FieldIds = new[] { 1, 2, 3 }; + options.Format = DataFormat.Raw; + }); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsRequestBuilderTests.cs new file mode 100644 index 0000000..5063cf4 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/GetRecordsRequestBuilderTests.cs @@ -0,0 +1,31 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetRecordsRequestBuilderTests + { + private static GetRecordsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + var apiClientMock = Substitute.For(); + _builder = new GetRecordsRequestBuilder(apiClientMock); + } + + [TestMethod] + public void FromApp_WhenCalled_ShouldReturnAGetRecordsByAppRequestBuilderInstanceWithAppIdSetToCorrectValue() + { + var appId = 1; + var builder = _builder.FromApp(appId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(appId, builder.AppId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilderTests.cs new file mode 100644 index 0000000..232e0e0 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilderTests.cs @@ -0,0 +1,123 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class QueryRecordsByAppPagedRequestBuilderTests + { + private static IOnspringClient _client; + private static QueryRecordsByAppPagedRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new QueryRecordsByAppPagedRequestBuilder(_client, 1, "filter"); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnInstanceWithPropertiesSet() + { + var appId = 1; + var filter = "filter"; + var builder = new QueryRecordsByAppPagedRequestBuilder(_client, appId, filter); + + Assert.AreEqual(appId, builder.AppId); + Assert.AreEqual(filter, builder.Filter); + Assert.AreEqual(1, builder.PageNumber); + Assert.AreEqual(50, builder.PageSize); + Assert.AreEqual(Enumerable.Empty(), builder.FieldIds); + Assert.AreEqual(DataFormat.Raw, builder.Format); + } + + [TestMethod] + public void ForPage_WhenCalled_ItShouldSetPageNumberProperty() + { + var pageNumber = 2; + + _builder.ForPage(pageNumber); + + Assert.AreEqual(pageNumber, _builder.PageNumber); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetPageSizeProperty() + { + var pageSize = 1; + + _builder.WithPageSize(pageSize); + + Assert.AreEqual(pageSize, _builder.PageSize); + } + + [TestMethod] + public void WithFieldIds_WhenCalled_ItShouldSetFieldIdsProperty() + { + var fieldIds = new int[] { 1, 2, 3 }; + + _builder.WithFieldIds(fieldIds); + + Assert.AreEqual(fieldIds, _builder.FieldIds); + } + + [TestMethod] + public void WithFormat_WhenCalled_ItShouldSetFormatProperty() + { + var format = DataFormat.Raw; + + _builder.WithFormat(format); + + Assert.AreEqual(format, _builder.Format); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedRecordsResponse(), + }; + + _client + .QueryRecordsAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetPagedRecordsResponse(), + }; + + _client + .QueryRecordsAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(options => + { + options.PageNumber = 2; + options.PageSize = 100; + options.Format = DataFormat.Formatted; + options.FieldIds = new[] { 1 }; + }); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Save/SaveRecordRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Save/SaveRecordRequestBuilderTests.cs new file mode 100644 index 0000000..5e867b6 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Records/Save/SaveRecordRequestBuilderTests.cs @@ -0,0 +1,82 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class SaveRecordRequestBuilderTests + { + private static IOnspringClient _client; + private static SaveRecordRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new SaveRecordRequestBuilder(_client); + } + + [TestMethod] + public void InApp_WhenCalled_ItShouldSetAppId() + { + var appId = 1; + + _builder.InApp(appId); + + Assert.AreEqual(appId, _builder.AppId); + } + + [TestMethod] + public void WithId_WhenCalledWithNull_ItShouldSetRecordId() + { + int? recordId = null; + + _builder.WithId(recordId); + + Assert.AreEqual(recordId, _builder.RecordId); + } + + [TestMethod] + public void WithId_WhenCalledWithIdValue_ItShouldSetRecordId() + { + int? recordId = 1; + + _builder.WithId(recordId); + + Assert.AreEqual(recordId, _builder.RecordId); + } + + [TestMethod] + public void WithValues_WhenCalled_ItShouldSetValues() + { + var values = new[] { new RecordFieldValue() }; + + _builder.WithValues(values); + + Assert.AreEqual(values, _builder.Values); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.Created, + Value = new SaveRecordResponse(), + }; + + _client + .SaveRecordAsync(Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetAllReportsPagesByAppRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetAllReportsPagesByAppRequestBuilderTests.cs new file mode 100644 index 0000000..ae76528 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetAllReportsPagesByAppRequestBuilderTests.cs @@ -0,0 +1,62 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllReportsPagesByAppRequestBuilderTests + { + private static readonly int _appId = 1; + private static IOnspringClient _client; + private static GetAllReportsPagesByAppRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllReportsPagesByAppRequestBuilder(_client, _appId); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + Assert.AreEqual(_appId, _builder.AppId); + Assert.AreEqual(50, _builder.PageSize); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetPageSizeProperty() + { + var pageSize = 100; + + var builder = new GetAllReportsPagesByAppRequestBuilder(_client, _appId) + .WithPageSize(pageSize); + + Assert.AreEqual(pageSize, builder.PageSize); + } + + [TestMethod] + public void SendAsync_WhenCalled_ItShouldReturnAsyncEnumerable() + { + var result = _builder.SendAsync(); + + Assert.IsInstanceOfType>>(result); + } + + [TestMethod] + public void SendAsync_WhenCalledWithOptions_ItShouldReturnAsyncEnumerable() + { + var result = _builder.SendAsync(o => o.PageSize = 100); + + Assert.IsInstanceOfType>>(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetAllReportsPagesRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetAllReportsPagesRequestBuilderTests.cs new file mode 100644 index 0000000..315674f --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetAllReportsPagesRequestBuilderTests.cs @@ -0,0 +1,42 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetAllReportsPagesRequestBuilderTests + { + private static readonly int _appId = 1; + private static IOnspringClient _client; + private static GetAllReportsPagesRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetAllReportsPagesRequestBuilder(_client); + } + + [TestMethod] + public void Constructor_WhenCalled_ItShouldReturnBuilderInstance() + { + Assert.IsInstanceOfType(_builder); + } + + [TestMethod] + public void FromApp_WhenCalled_ItShouldReturnGetAllReportsPagesByAppRequestBuilderInstance() + { + var result = _builder.FromApp(_appId); + + Assert.IsInstanceOfType(result); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetReportRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetReportRequestBuilderTests.cs new file mode 100644 index 0000000..60d0142 --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetReportRequestBuilderTests.cs @@ -0,0 +1,119 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetReportRequestBuilderTests + { + private static readonly int _reportId = 1; + private static IOnspringClient _client; + private static GetReportRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetReportRequestBuilder(_client); + } + + [TestMethod] + public void FromReport_WhenCalled_ItShouldReturnBuilderInstanceWithPropertiesSet() + { + var reportId = 1; + + var builder = _builder.FromReport(reportId); + + Assert.IsInstanceOfType(builder); + Assert.AreEqual(reportId, builder.ReportId); + Assert.AreEqual(DataFormat.Raw, builder.Format); + Assert.AreEqual(ReportDataType.ReportData, builder.DataType); + } + + [TestMethod] + public void WithFormat_WhenCalled_ItShouldSetFormatProperty() + { + var format = DataFormat.Formatted; + + _builder.WithFormat(format); + + Assert.AreEqual(format, _builder.Format); + } + + [TestMethod] + public void WithDataType_WhenCalled_ItShouldSetDataTypeProperty() + { + var dataType = ReportDataType.ChartData; + + _builder.WithDataType(dataType); + + Assert.AreEqual(dataType, _builder.DataType); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new ReportData(), + }; + + _client + .GetReportAsync( + Arg.Any(), + Arg.Any(), + Arg.Any() + ) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnAnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new ReportData(), + }; + + _client + .GetReportAsync( + Arg.Any(), + Arg.Any(), + Arg.Any() + ) + .Returns(apiResponse); + + var format = DataFormat.Formatted; + var dataType = ReportDataType.ChartData; + + var result = await _builder.SendAsync(options => + { + options.Format = format; + options.DataType = dataType; + }); + + Assert.AreEqual(apiResponse, result); + + await _client + .Received() + .GetReportAsync( + _reportId, + dataType, + format + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetReportsRequestBuilderTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetReportsRequestBuilderTests.cs new file mode 100644 index 0000000..f688a2b --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/Fluent/Reports/GetReportsRequestBuilderTests.cs @@ -0,0 +1,100 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System.Diagnostics.CodeAnalysis; +using System.Net; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Tests.Tests.Unit.Fluent +{ + [TestClass, ExcludeFromCodeCoverage] + public class GetReportsRequestBuilderTests + { + private static readonly int _appId = 1; + private static readonly int _pageNumber = 2; + private static readonly int _pageSize = 100; + private static IOnspringClient _client; + private static GetReportsRequestBuilder _builder; + + [ClassInitialize] + public static void ClassInit(TestContext testContext) + { + _client = Substitute.For(); + _builder = new GetReportsRequestBuilder(_client); + } + + [TestMethod] + public void FromApp_WhenCalled_ItShouldSetAppIdProperty() + { + _builder.FromApp(_appId); + + Assert.AreEqual(_appId, _builder.AppId); + } + + [TestMethod] + public void ForPage_WhenCalled_ItShouldSetPageNumberProperty() + { + _builder.ForPage(_pageNumber); + + Assert.AreEqual(_pageNumber, _builder.PageNumber); + } + + [TestMethod] + public void WithPageSize_WhenCalled_ItShouldSetPageSizeProperty() + { + _builder.WithPageSize(_pageSize); + + Assert.AreEqual(_pageSize, _builder.PageSize); + } + + [TestMethod] + public async Task SendAsync_WhenCalled_ItShouldReturnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetReportsForAppResponse(), + }; + + _client + .GetReportsForAppAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(); + + Assert.AreEqual(apiResponse, result); + } + + [TestMethod] + public async Task SendAsync_WhenCalledWithOptions_ItShouldReturnApiResponse() + { + var apiResponse = new ApiResponse + { + StatusCode = HttpStatusCode.OK, + Value = new GetReportsForAppResponse(), + }; + + _client + .GetReportsForAppAsync(Arg.Any(), Arg.Any()) + .Returns(apiResponse); + + var result = await _builder.SendAsync(options => + { + options.PageNumber = _pageNumber; + options.PageSize = _pageSize; + }); + + Assert.AreEqual(apiResponse, result); + + await _client + .Received() + .GetReportsForAppAsync( + _appId, + Arg.Is( + pr => pr.PageNumber == _pageNumber && pr.PageSize == _pageSize + ) + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK.Tests/Tests/Unit/OnspringClientTests.cs b/Onspring.API.SDK.Tests/Tests/Unit/OnspringClientTests.cs new file mode 100644 index 0000000..1945a7b --- /dev/null +++ b/Onspring.API.SDK.Tests/Tests/Unit/OnspringClientTests.cs @@ -0,0 +1,19 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Onspring.API.SDK.Interfaces.Fluent; +using System.Diagnostics.CodeAnalysis; + +namespace Onspring.API.SDK.Tests.Tests.Unit +{ + [TestClass, ExcludeFromCodeCoverage] + public class OnspringClientTests + { + [TestMethod] + public void CreateRequest_WhenCalled_ItShouldReturnAnOnspringRequestInstance() + { + var client = new OnspringClient("https://api.onspring.com", "key"); + var request = client.CreateRequest(); + + Assert.IsInstanceOfType(request); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Enums/FilterOperator.cs b/Onspring.API.SDK/Enums/FilterOperator.cs new file mode 100644 index 0000000..b1f7b7b --- /dev/null +++ b/Onspring.API.SDK/Enums/FilterOperator.cs @@ -0,0 +1,137 @@ +using System; + +namespace Onspring.API.SDK.Enums +{ + /// + /// Represents a base class for enumerations with common properties. + /// + public abstract class Enumeration : IComparable + { + /// + /// Gets the name of the enumeration. + /// + public string Name { get; private set; } + + /// + /// Gets the unique identifier of the enumeration. + /// + public int Id { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier of the enumeration. + /// The name of the enumeration. + protected Enumeration(int id, string name) => (Id, Name) = (id, name); + + /// + /// Converts the enumeration to its string representation (the name). + /// + /// The name of the enumeration. + public override string ToString() => Name; + + /// + /// Determines whether the current object is equal to another object. + /// + /// The object to compare with. + /// True if the objects are equal; otherwise, false. + public override bool Equals(object obj) + { + if (obj is Enumeration otherValue) + { + var typeMatches = GetType().Equals(obj.GetType()); + var valueMatches = Id.Equals(otherValue.Id); + + return typeMatches && valueMatches; + } + + return false; + } + + /// + /// Gets a hash code for the enumeration. + /// + /// A hash code for the enumeration. + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + /// + /// Compares the current instance with another object and returns an integer + /// that indicates whether the current instance precedes, follows, or is equivalent + /// to the other object. + /// + /// An object to compare with this instance. + /// + /// A value that indicates the relative order of the objects being compared. + /// + public int CompareTo(object other) => Id.CompareTo(((Enumeration)other).Id); + } + + /// + /// Represents a filter operator enumeration with predefined values. + /// + public class FilterOperator : Enumeration + { + /// + /// Represents the "eq" filter operator. + /// + public static FilterOperator Equal { get; } = new FilterOperator(1, "eq"); + + /// + /// Represents the "ne" filter operator. + /// + public static FilterOperator NotEqual { get; } = new FilterOperator(2, "ne"); + + /// + /// Represents the "contains" filter operator. + /// + public static FilterOperator Contains { get; } = new FilterOperator(3, "contains"); + + /// + /// Represents the "isnull" filter operator. + /// + public static FilterOperator IsNull { get; } = new FilterOperator(4, "isnull"); + + /// + /// Represents the "notnull" filter operator. + /// + public static FilterOperator NotNull { get; } = new FilterOperator(5, "notnull"); + + /// + /// Represents the "gt" filter operator. + /// + public static FilterOperator GreaterThan { get; } = new FilterOperator(6, "gt"); + + /// + /// Represents the "lt" filter operator. + /// + public static FilterOperator LessThan { get; } = new FilterOperator(7, "lt"); + + /// + /// Represents the "and" filter operator. + /// + public static FilterOperator And { get; } = new FilterOperator(8, "and"); + + /// + /// Represents the "or" filter operator. + /// + public static FilterOperator Or { get; } = new FilterOperator(9, "or"); + + /// + /// Represents the "not" filter operator. + /// + public static FilterOperator Not { get; } = new FilterOperator(10, "not"); + + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier of the filter operator. + /// The name of the filter operator. + private FilterOperator(int id, string name) : base(id, name) + { + } + } + +} \ No newline at end of file diff --git a/Onspring.API.SDK/IOnspringClient.cs b/Onspring.API.SDK/IOnspringClient.cs index f519361..1f93f4e 100644 --- a/Onspring.API.SDK/IOnspringClient.cs +++ b/Onspring.API.SDK/IOnspringClient.cs @@ -1,4 +1,5 @@ using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; using Onspring.API.SDK.Models; using System; using System.Collections.Generic; @@ -11,6 +12,12 @@ namespace Onspring.API.SDK /// public interface IOnspringClient { + /// + /// Creates a new Onspring Request which exposes a fluent interface for making a request to the Onspring API. + /// + /// An instance that implements the interface. + IOnspringRequestBuilder CreateRequest(); + /// /// Determines if the API is reachable. /// @@ -55,6 +62,13 @@ public interface IOnspringClient /// Task> GetAppAsync(int appId); + /// + /// Gets all accessible apps. + /// + /// The number of apps to return per page. + /// An async enumerable of where T is . + IAsyncEnumerable> GetAllAppsAsync(int pageSize = 50); + /// /// Gets all accessible apps. /// @@ -69,6 +83,7 @@ public interface IOnspringClient /// Task> GetAppsAsync(IEnumerable appIds); + /// /// Gets the requested field. /// @@ -83,6 +98,15 @@ public interface IOnspringClient /// Task> GetFieldsAsync(IEnumerable fieldIds); + /// + /// Gets all accessible fields. + /// + /// The identifier of the app to get fields for. + /// The number of fields to return per page. + /// An async enumerable of where T is . + IAsyncEnumerable> GetAllFieldsForAppAsync(int appId, int pageSize = 50); + + /// /// Gets the fields associated to the . /// @@ -123,6 +147,21 @@ public interface IOnspringClient /// Task> GetRecordsAsync(GetRecordsRequest request); + /// + /// Gets all records associated to an app. + /// + /// An instance of . + /// An async enumerable of where T is . + IAsyncEnumerable> GetAllRecordsForAppAsync(GetRecordsByAppRequest request); + + /// + /// Gets all records by query. + /// + /// An instance of . + /// The number of records to return per page. + /// An async enumerable of where T is . + IAsyncEnumerable> GetAllRecordsByQueryAsync(QueryRecordsRequest request, int pageSize = 50); + /// /// Gets the records associated to an app. /// @@ -139,6 +178,14 @@ public interface IOnspringClient /// Task> GetReportAsync(int reportId, ReportDataType dataType = ReportDataType.ReportData, DataFormat dataFormat = DataFormat.Raw); + /// + /// Gets all reports associated to the . + /// + /// The identifier of the app to get reports for. + /// The number of reports to return per page. + /// An async enumerable of where T is . + IAsyncEnumerable> GetAllReportsForAppAsync(int appId, int pageSize = 50); + /// /// Gets the reports associated to the . /// @@ -175,5 +222,6 @@ public interface IOnspringClient /// /// Task> SaveRecordAsync(ResultRecord request); + } } \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAllAppsPagesRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAllAppsPagesRequestBuilder.cs new file mode 100644 index 0000000..20e9fe5 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAllAppsPagesRequestBuilder.cs @@ -0,0 +1,36 @@ +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a request builder for getting all pages of apps. + /// + public interface IGetAllAppsPagesRequestBuilder + { + /// + /// Gets the page size to retrieve. + /// + int PageSize { get; } + + /// + /// Sets the page size to retrieve. + /// + IGetAllAppsPagesRequestBuilder WithPageSize(int pageSize); + + /// + /// Sends the request to retrieve all pages of apps. + /// + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(); + + /// + /// Sends the request to retrieve all pages of apps with the specified options. + /// + /// The options to use for the request. + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppByIdRequestBuilder.cs new file mode 100644 index 0000000..75a3159 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppByIdRequestBuilder.cs @@ -0,0 +1,22 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve an app by ID. + /// + public interface IGetAppByIdRequestBuilder + { + /// + /// Gets the ID of the app to retrieve. + /// + int AppId { get; } + + /// + /// Asynchronously sends the request to retrieve the app. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppsByIdsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppsByIdsRequestBuilder.cs new file mode 100644 index 0000000..ef8e93f --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppsByIdsRequestBuilder.cs @@ -0,0 +1,23 @@ +using Onspring.API.SDK.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve apps by IDs + /// + public interface IGetAppsByIdsRequestBuilder + { + /// + /// Gets the IDs of the apps to retrieve. + /// + IEnumerable AppIds { get; } + + /// + /// Asynchronously sends the request to retrieve the apps. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppsRequestBuilder.cs new file mode 100644 index 0000000..c69d89d --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetAppsRequestBuilder.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve apps. + /// + public interface IGetAppsRequestBuilder + { + /// + /// Specifies the page number to retrieve. + /// + /// The page number to retrieve. + /// A for further configuration of the request. + IGetPagedAppsRequestBuilder ForPage(int pageNumber); + + /// + /// Specifies the IDs of the apps to retrieve. + /// + /// The IDs of the apps to retrieve. + /// A for further configuration of the request. + IGetAppsByIdsRequestBuilder WithIds(IEnumerable appIds); + + /// + /// Specifies the ID of the app to retrieve. + /// + /// The ID of the app to retrieve. + /// A for further configuration of the request. + IGetAppByIdRequestBuilder WithId(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetPagedAppsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetPagedAppsRequestBuilder.cs new file mode 100644 index 0000000..af5ee52 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Apps/IGetPagedAppsRequestBuilder.cs @@ -0,0 +1,34 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a request builder for getting paged apps. + /// + public interface IGetPagedAppsRequestBuilder + { + /// + /// Gets the page number of the apps to retrieve. + /// + int PageNumber { get; } + + /// + /// Gets the page size of the apps to retrieve. The default is 50. + /// + int PageSize { get; } + + /// + /// Specifies the page size of the apps to retrieve. + /// + /// The page size of the apps to retrieve. + /// A for further configuration of the request. + IGetPagedAppsRequestBuilder WithPageSize(int pageSize); + + /// + /// Asynchronously sends the request to retrieve the apps. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetAllFieldsPagesByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetAllFieldsPagesByAppRequestBuilder.cs new file mode 100644 index 0000000..4ef0b57 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetAllFieldsPagesByAppRequestBuilder.cs @@ -0,0 +1,43 @@ +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a request builder to retrieve all pages of fields. + /// + public interface IGetAllFieldsPagesByAppRequestBuilder + { + /// + /// Gets the app ID to retrieve fields for. + /// + int AppId { get; } + + /// + /// Gets the page size to retrieve. The default is 50. + /// + int PageSize { get; } + + /// + /// Sets the page size to retrieve. + /// + /// The page size to retrieve. + /// The current instance of the . + IGetAllFieldsPagesByAppRequestBuilder WithPageSize(int pageSize); + + /// + /// Sends the request to retrieve all pages of fields for an app. + /// + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(); + + /// + /// Sends the request to retrieve all pages of fields for an app with the specified options. + /// + /// The options to use for the request. + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetAllFieldsPagesRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetAllFieldsPagesRequestBuilder.cs new file mode 100644 index 0000000..3f4297c --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetAllFieldsPagesRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a request builder for getting all pages of fields. + /// + public interface IGetAllFieldsPagesRequestBuilder + { + /// + /// Specifies the ID of the app to retrieve fields for. + /// + /// The ID of the app to retrieve fields for. + /// A for further configuration of the request. + IGetAllFieldsPagesByAppRequestBuilder FromApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldByIdRequestBuilder.cs new file mode 100644 index 0000000..1656573 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldByIdRequestBuilder.cs @@ -0,0 +1,22 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields by id. + /// + public interface IGetFieldByIdRequestBuilder + { + /// + /// Gets the ID of the field to retrieve. + /// + int FieldId { get; } + + /// + /// Asynchronously sends the request to retrieve the field. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsByAppRequestBuilder.cs new file mode 100644 index 0000000..eb429c3 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsByAppRequestBuilder.cs @@ -0,0 +1,55 @@ +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields by app. + /// + public interface IGetFieldsByAppRequestBuilder + { + /// + /// Gets the ID of the app to retrieve fields for. + /// + int AppId { get; } + + /// + /// Gets the page number to retrieve. + /// + int PageNumber { get; } + + /// + /// Gets the page size to retrieve. + /// + int PageSize { get; } + + /// + /// Specifies the page number to retrieve. + /// + /// The page number to retrieve. + /// A for further configuration of the request. + IGetFieldsByAppRequestBuilder ForPage(int pageNumber); + + /// + /// Specifies the page size to retrieve. + /// + /// The page size to retrieve. + /// A for further configuration of the request. + IGetFieldsByAppRequestBuilder WithPageSize(int pageSize); + + /// + /// Asynchronously sends the request to retrieve the fields. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Asynchronously sends the request to retrieve the fields. + /// + /// An action constructs the options for the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsByIdsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsByIdsRequestBuilder.cs new file mode 100644 index 0000000..771be5a --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsByIdsRequestBuilder.cs @@ -0,0 +1,23 @@ +using Onspring.API.SDK.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields by IDs. + /// + public interface IGetFieldsByIdsRequestBuilder + { + /// + /// Gets the IDs of the fields to retrieve. + /// + IEnumerable FieldIds { get; } + + /// + /// Asynchronously sends the request to retrieve the fields. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsRequestBuilder.cs new file mode 100644 index 0000000..492691f --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Fields/IGetFieldsRequestBuilder.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields. + /// + public interface IGetFieldsRequestBuilder + { + /// + /// Specifies the ID of the field to retrieve. + /// + /// The ID of the field to retrieve. + /// A for further configuration of the request. + IGetFieldByIdRequestBuilder WithId(int fieldId); + + /// + /// Specifies the ID of the app to retrieve fields for. + /// + /// The ID of the app to retrieve fields for. + /// A for further configuration of the request. + IGetFieldsByAppRequestBuilder FromApp(int appId); + + /// + /// Specifies the IDs of the fields to retrieve. + /// + /// The IDs of the fields to retrieve. + /// A for further configuration of the request. + IGetFieldsByIdsRequestBuilder WithIds(IEnumerable fieldIds); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileInFieldRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileInFieldRequestBuilder.cs new file mode 100644 index 0000000..d06f56c --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileInFieldRequestBuilder.cs @@ -0,0 +1,25 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file to a field. + /// + public interface IAddFileInFieldRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to add the file to. + /// + int FieldId { get; } + + /// + /// Specifies the name of the file to add. + /// + /// The name of the file to add. + /// A for further configuration of the request. + IAddFileWithNameRequestBuilder WithName(string name); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileRequestBuilder.cs new file mode 100644 index 0000000..bf81054 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file. + /// + public interface IAddFileRequestBuilder + { + /// + /// Specifies the ID of the record to add the file to. + /// + /// The ID of the record to add the file to. + /// A for further configuration of the request. + IAddFileToRecordRequestBuilder ToRecord(int recordId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileToRecordRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileToRecordRequestBuilder.cs new file mode 100644 index 0000000..8c52be0 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileToRecordRequestBuilder.cs @@ -0,0 +1,20 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file to a record. + /// + public interface IAddFileToRecordRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Specifies the ID of the field to add the file to. + /// + /// The ID of the field to add the file to. + /// A for further configuration of the request. + IAddFileInFieldRequestBuilder InField(int fieldId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithModifiedDateRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithModifiedDateRequestBuilder.cs new file mode 100644 index 0000000..f0d2ca6 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithModifiedDateRequestBuilder.cs @@ -0,0 +1,51 @@ +using Onspring.API.SDK.Models; +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + public interface IAddFileWithModifiedDateRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to add the file to. + /// + int FieldId { get; } + + /// + /// Gets the name of the file to add. + /// + string Name { get; } + + /// + /// Gets the stream of the file to add. + /// + Stream FileStream { get; } + + /// + /// Gets the MIME type of the file to add. + /// + string Type { get; } + + /// + /// Gets the notes of the file to add. + /// + string Notes { get; } + + /// + /// Gets the modified date of the file to add. + /// + DateTime? ModifiedDate { get; } + + /// + /// Asynchronously sends the request to add the file. + /// + /// An awaitable task that returns an when completed + Task>> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithNameRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithNameRequestBuilder.cs new file mode 100644 index 0000000..a972bcb --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithNameRequestBuilder.cs @@ -0,0 +1,32 @@ +using System.IO; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file with a name. + /// + public interface IAddFileWithNameRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to add the file to. + /// + int FieldId { get; } + + /// + /// Gets the name of the file to add. + /// + string Name { get; } + + /// + /// Specifies the Stream of the file to add. + /// + /// The Stream of the file to add. + /// A for further configuration of the request. + IAddFileWithStreamRequestBuilder WithStream(Stream stream); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithNotesRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithNotesRequestBuilder.cs new file mode 100644 index 0000000..73a3514 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithNotesRequestBuilder.cs @@ -0,0 +1,48 @@ +using System; +using System.IO; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file with notes. + /// + public interface IAddFileWithNotesRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to add the file to. + /// + int FieldId { get; } + + /// + /// Gets the name of the file to add. + /// + string Name { get; } + + /// + /// Gets the stream of the file to add. + /// + Stream FileStream { get; } + + /// + /// Gets the MIME type of the file to add. + /// + string Type { get; } + + /// + /// Gets the notes of the file to add. + /// + string Notes { get; } + + /// + /// Specifies the modified date of the file to add. + /// + /// The modified date of the file to add. + /// A for further configuration of the request. + IAddFileWithModifiedDateRequestBuilder WithModifiedDate(DateTime? modifiedDate); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithStreamRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithStreamRequestBuilder.cs new file mode 100644 index 0000000..b0318b7 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithStreamRequestBuilder.cs @@ -0,0 +1,37 @@ +using System.IO; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file with a stream. + /// + public interface IAddFileWithStreamRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to add the file to. + /// + int FieldId { get; } + + /// + /// Gets the name of the file to add. + /// + string Name { get; } + + /// + /// Gets the stream of the file to add. + /// + Stream FileStream { get; } + + /// + /// Specifies the MIME type of the file to add. + /// + /// The MIME type of the file to add. + /// A for further configuration of the request. + IAddFileWithTypeRequestBuilder WithType(string type); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithTypeRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithTypeRequestBuilder.cs new file mode 100644 index 0000000..9013074 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Add/IAddFileWithTypeRequestBuilder.cs @@ -0,0 +1,42 @@ +using System.IO; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file with a type. + /// + public interface IAddFileWithTypeRequestBuilder + { + /// + /// Gets the ID of the record to add the file to. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to add the file to. + /// + int FieldId { get; } + + /// + /// Gets the name of the file to add. + /// + string Name { get; } + + /// + /// Gets the stream of the file to add. + /// + Stream FileStream { get; } + + /// + /// Gets the MIME type of the file to add. + /// + string Type { get; } + + /// + /// Specifies the notes of the file to add. + /// + /// The notes of the file to add. + /// A for further configuration of the request. + IAddFileWithNotesRequestBuilder WithNotes(string notes); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileByIdRequestBuilder.cs new file mode 100644 index 0000000..6aeb8dc --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileByIdRequestBuilder.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a file. + /// + public interface IDeleteFileByIdRequestBuilder + { + /// + /// Gets the ID of the record to delete the file from. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to delete the file from. + /// + int FieldId { get; } + + /// + /// Gets the ID of the file to delete. + /// + int FileId { get; } + + /// + /// Asynchronously sends the request to delete the file. + /// + /// An awaitable task that returns an when complete. + Task SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileFromRecordRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileFromRecordRequestBuilder.cs new file mode 100644 index 0000000..c1fd261 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileFromRecordRequestBuilder.cs @@ -0,0 +1,20 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a file from a record. + /// + public interface IDeleteFileFromRecordRequestBuilder + { + /// + /// Gets the ID of the record to delete the file from. + /// + int RecordId { get; } + + /// + /// Specifies the ID of the field to delete the file from. + /// + /// The ID of the field to delete the file from. + /// A for further configuration of the request. + IDeleteFileInFieldRequestBuilder InField(int fieldId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileInFieldRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileInFieldRequestBuilder.cs new file mode 100644 index 0000000..a4f02ba --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileInFieldRequestBuilder.cs @@ -0,0 +1,25 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a file from a field. + /// + public interface IDeleteFileInFieldRequestBuilder + { + /// + /// Gets the ID of the record to delete the file from. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to delete the file from. + /// + int FieldId { get; } + + /// + /// Specifies the ID of the file to delete. + /// + /// The ID of the file to delete. + /// A for further configuration of the request. + IDeleteFileByIdRequestBuilder WithId(int fileId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileRequestBuilder.cs new file mode 100644 index 0000000..32db69d --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Delete/IDeleteFileRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a file. + /// + public interface IDeleteFileRequestBuilder + { + /// + /// Specifies the ID of the record to delete the file from. + /// + /// The ID of the record to delete the file from. + /// A for further configuration of the request. + IDeleteFileFromRecordRequestBuilder FromRecord(int recordId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileByIdRequestBuilder.cs new file mode 100644 index 0000000..fd58fe2 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileByIdRequestBuilder.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve files by id. + /// + public interface IGetFileByIdRequestBuilder + { + /// + /// Gets the ID of the record to retrieve the file from. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to retrieve the file from. + /// + int FieldId { get; } + + /// + /// Gets the ID of the file to retrieve. + /// + int FileId { get; } + + /// + /// Asynchronously sends the request to retrieve the file. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileFromRecordRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileFromRecordRequestBuilder.cs new file mode 100644 index 0000000..95ec64a --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileFromRecordRequestBuilder.cs @@ -0,0 +1,20 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve a file from a record. + /// + public interface IGetFileFromRecordRequestBuilder + { + /// + /// Gets the ID of the record to retrieve the file from. + /// + int RecordId { get; } + + /// + /// Specifies the ID of the field to retrieve the file from. + /// + /// The ID of the field to retrieve the file from. + /// A for further configuration of the request. + IGetFileInFieldRequestBuilder InField(int fieldId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInFieldRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInFieldRequestBuilder.cs new file mode 100644 index 0000000..e6b68f2 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInFieldRequestBuilder.cs @@ -0,0 +1,25 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve a file from a field. + /// + public interface IGetFileInFieldRequestBuilder + { + /// + /// Gets the ID of the record to retrieve the file from. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to retrieve the file from. + /// + int FieldId { get; } + + /// + /// Specifies the ID of the file to retrieve. + /// + /// The ID of the file to retrieve. + /// A for further configuration of the request. + IGetFileByIdRequestBuilder WithId(int fileId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoByIdRequestBuilder.cs new file mode 100644 index 0000000..0c7a286 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoByIdRequestBuilder.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve information about a file by its ID. + /// + public interface IGetFileInfoByIdRequestBuilder + { + /// + /// Gets the ID of the record to retrieve the file information from. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to retrieve the file information from. + /// + int FieldId { get; } + + /// + /// Gets the ID of the file to retrieve information about. + /// + int FileId { get; } + + /// + /// Asynchronously sends the request to retrieve the file information. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoFromRecordRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoFromRecordRequestBuilder.cs new file mode 100644 index 0000000..fa752ba --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoFromRecordRequestBuilder.cs @@ -0,0 +1,20 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve information about a file from a record. + /// + public interface IGetFileInfoFromRecordRequestBuilder + { + /// + /// Gets the ID of the record to retrieve the file information from. + /// + int RecordId { get; } + + /// + /// Specifies the ID of the field to retrieve the file information from. + /// + /// The ID of the field to retrieve the file information from. + /// A for further configuration of the request. + IGetFileInfoInFieldRequestBuilder InField(int fieldId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoInFieldRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoInFieldRequestBuilder.cs new file mode 100644 index 0000000..5b03669 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoInFieldRequestBuilder.cs @@ -0,0 +1,25 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve information about a file in a field. + /// + public interface IGetFileInfoInFieldRequestBuilder + { + /// + /// Gets the ID of the record to retrieve the file information from. + /// + int RecordId { get; } + + /// + /// Gets the ID of the field to retrieve the file information from. + /// + int FieldId { get; } + + /// + /// Specifies the ID of the file to retrieve information about. + /// + /// The ID of the file to retrieve information about. + /// A for further configuration of the request. + IGetFileInfoByIdRequestBuilder WithId(int fileId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoRequestBuilder.cs new file mode 100644 index 0000000..2d38027 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileInfoRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve information about a file. + /// + public interface IGetFileInfoRequestBuilder + { + /// + /// Specifies the ID of the record to retrieve the file information from. + /// + /// The ID of the record to retrieve the file information from. + /// A for further configuration of the request. + IGetFileInfoFromRecordRequestBuilder FromRecord(int recordId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileRequestBuilder.cs new file mode 100644 index 0000000..bfb1f4b --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Files/Get/IGetFileRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve a file. + /// + public interface IGetFileRequestBuilder + { + /// + /// Specifies the ID of the file to retrieve. + /// + /// The ID of the record to retrieve the file from. + /// A for further configuration of the request. + IGetFileFromRecordRequestBuilder FromRecord(int recordId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/IOnspringRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/IOnspringRequestBuilder.cs new file mode 100644 index 0000000..6b9a69f --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/IOnspringRequestBuilder.cs @@ -0,0 +1,98 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder interface for creating various types of Onspring API requests. + /// + public interface IOnspringRequestBuilder + { + /// + /// Creates a builder for checking the connection to the Onspring API. + /// + /// A builder instance for checking the connection that implements the interface. + IConnectionRequestBuilder ToCheckConnection(); + + /// + /// Creates a builder for retrieving records from Onspring. + /// + /// A builder instance for retrieving records that implements the interface. + IGetRecordsRequestBuilder ToGetRecords(); + + /// + /// Creates a builder for deleting records in Onspring. + /// + /// A builder instance for deleting records that implements the interface. + IDeleteRecordsRequestBuilder ToDeleteRecords(); + + /// + /// Creates a builder for saving a record in Onspring. + /// + /// A builder instance for saving records that implements the interface. + ISaveRecordRequestBuilder ToSaveRecord(); + + /// + /// Creates a builder for retrieving reports from Onspring. + /// + /// A builder instance for retrieving reports that implements the interface. + IGetReportsRequestBuilder ToGetReports(); + + /// + /// Creates a builder for retrieving report data from Onspring. + /// + /// A builder instance for retrieving report data that implements the interface. + IGetReportRequestBuilder ToGetReportData(); + + /// + /// Creates a builder for saving a list value in Onspring. + /// + /// A builder instance for saving list values that implements the interface. + ISaveListValueRequestBuilder ToSaveListValue(); + + /// + /// Creates a builder for deleting a list value in Onspring. + /// + /// A builder instance for deleting list values that implements the interface. + IDeleteListValueRequestBuilder ToDeleteListValue(); + + /// + /// Creates a builder for retrieving files from Onspring. + /// + /// A builder instance for retrieving files that implements the interface. + IGetFileRequestBuilder ToGetFile(); + + /// + /// Creates a builder for retrieving file information from Onspring. + /// + /// A builder instance for retrieving file information that implements the interface. + IGetFileInfoRequestBuilder ToGetFileInfo(); + + /// + /// Creates a builder for deleting a file in Onspring. + /// + /// A builder instance for deleting files that implements the interface. + IDeleteFileRequestBuilder ToDeleteFile(); + + /// + /// Creates a builder for adding a file in Onspring. + /// + /// A builder instance for adding files that implements the interface. + IAddFileRequestBuilder ToAddFile(); + + /// + /// Creates a builder for retrieving fields from Onspring. + /// + /// A builder instance for retrieving fields that implements the interface. + IGetFieldsRequestBuilder ToGetFields(); + + /// + /// Creates a builder for retrieving apps from Onspring. + /// + /// A builder instance for retrieving apps that implements the interface. + IGetAppsRequestBuilder ToGetApps(); + + /// + /// Creates a builder for retrieving all pages of an entity that supports pagination. + /// + /// A builder instance for retrieving all pages that implements the interface. + IPagedRequestBuilder ToGetAllPages(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueInListRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueInListRequestBuilder.cs new file mode 100644 index 0000000..58ced72 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueInListRequestBuilder.cs @@ -0,0 +1,22 @@ +using System; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a list value in a list. + /// + public interface IDeleteListValueInListRequestBuilder + { + /// + /// Gets the ID of the list to delete the value in. + /// + int ListId { get; } + + /// + /// Specifies the ID of the list value to delete. + /// + /// The ID of the list value to delete. + /// A for further configuration of the request. + IDeleteListValueWithIdRequestBuilder WithId(Guid id); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueRequestBuilder.cs new file mode 100644 index 0000000..c2266e4 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a list value. + /// + public interface IDeleteListValueRequestBuilder + { + /// + /// Specifies the ID of the list where the list value to delete is located. + /// + /// The ID of the list where the list value to delete is located. + /// A for further configuration of the request. + IDeleteListValueInListRequestBuilder InList(int listId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueWithIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueWithIdRequestBuilder.cs new file mode 100644 index 0000000..0fdfa7b --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Delete/IDeleteListValueWithIdRequestBuilder.cs @@ -0,0 +1,28 @@ +using Onspring.API.SDK.Models; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a list value in a list. + /// + public interface IDeleteListValueWithIdRequestBuilder + { + /// + /// Gets the ID of the list to delete the value in. + /// + int ListId { get; } + + /// + /// Gets the ID of the list value to delete. + /// + Guid Id { get; } + + /// + /// Asynchronously sends the request to delete the list value. + /// + /// An awaitable task that returns an when complete. + Task SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueInListRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueInListRequestBuilder.cs new file mode 100644 index 0000000..a7eb832 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueInListRequestBuilder.cs @@ -0,0 +1,17 @@ +using System; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a list value in a list. + /// + public interface ISaveListValueInListRequestBuilder + { + /// + /// Specifies the ID of the list to save the value in. If id is null, a new list value will be created. + /// + /// The ID of the list value to save. + /// A for further configuration of the request. + ISaveListValueWithIdRequestBuilder WithId(Guid? id); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueRequestBuilder.cs new file mode 100644 index 0000000..83f3a3e --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a list value. + /// + public interface ISaveListValueRequestBuilder + { + /// + /// Specifies the ID of the list to save the value in. + /// + /// The ID of the list to save the value in. + /// A for further configuration of the request. + ISaveListValueInListRequestBuilder InList(int listId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueWithIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueWithIdRequestBuilder.cs new file mode 100644 index 0000000..93d9c40 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueWithIdRequestBuilder.cs @@ -0,0 +1,27 @@ +using System; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a list value with id in a list. + /// + public interface ISaveListValueWithIdRequestBuilder + { + /// + /// Gets the ID of the list to save the value in. + /// + int ListId { get; } + + /// + /// Gets the ID of the list value to save. + /// + Guid? Id { get; } + + /// + /// Specifies the name of the list value to save. + /// + /// The name of the list value to save. + /// A for further configuration of the request. + ISaveListValueWithNameRequestBuilder WithName(string name); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueWithNameRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueWithNameRequestBuilder.cs new file mode 100644 index 0000000..eedd29d --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Lists/Save/ISaveListValueWithNameRequestBuilder.cs @@ -0,0 +1,47 @@ +using Onspring.API.SDK.Models; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a list value with name in a list. + /// + public interface ISaveListValueWithNameRequestBuilder + { + /// + /// Gets the ID of the list to save the value in. + /// + int ListId { get; } + + /// + /// Gets the ID of the list value to save. + /// + Guid? Id { get; } + + /// + /// Gets the name of the list value to save. + /// + string Name { get; } + + /// + /// Specifies the color of the list value to save. + /// + /// The color of the list value to save. + /// A for further configuration of the request. + ISaveListValueWithNameRequestBuilder WithColor(string color); + + /// + /// Specifies the numeric value of the list value to save. + /// + /// The numeric value of the list value to save. + /// A for further configuration of the request. + ISaveListValueWithNameRequestBuilder WithNumericValue(decimal value); + + /// + /// Asynchronously sends the request to save the list value. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Pagination/IPagedRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Pagination/IPagedRequestBuilder.cs new file mode 100644 index 0000000..7ded694 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Pagination/IPagedRequestBuilder.cs @@ -0,0 +1,32 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Interface for building paged requests. + /// + public interface IPagedRequestBuilder + { + /// + /// Creates a builder to get all pages of apps. + /// + /// A for further configuration of the request. + IGetAllAppsPagesRequestBuilder OfApps(); + + /// + /// Creates a builder to get all pages of fields for a specific app. + /// + /// A for further configuration of the request. + IGetAllFieldsPagesRequestBuilder OfFields(); + + /// + /// Creates a builder to get all pages of records for a specific app. + /// + /// A for further configuration of the request. + IGetAllRecordsPagesRequestBuilder OfRecords(); + + /// + /// Creates a builder to get all pages of reports for a specific app. + /// + /// A for further configuration of the request. + IGetAllReportsPagesRequestBuilder OfReports(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Ping/IConnectionRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Ping/IConnectionRequestBuilder.cs new file mode 100644 index 0000000..d1475b3 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Ping/IConnectionRequestBuilder.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder interface for sending a connection request to the Onspring API. + /// + public interface IConnectionRequestBuilder + { + /// + /// Asynchronously sends the connection request to the Onspring API. + /// + /// A representing the asynchronous operation. The result is a boolean indicating the success of the connection. + Task SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordByIdRequestBuilder.cs new file mode 100644 index 0000000..77278eb --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordByIdRequestBuilder.cs @@ -0,0 +1,27 @@ +using Onspring.API.SDK.Models; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a record from an app by ID. + /// + public interface IDeleteRecordByIdRequestBuilder + { + /// + /// Gets the ID of the app from which to delete the record. + /// + int AppId { get; } + + /// + /// Gets the ID of the record to delete. + /// + int RecordId { get; } + + /// + /// Asynchronously sends the request to delete the record. + /// + /// An awaitable task that returns an when complete. + Task SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsByAppRequestBuilder.cs new file mode 100644 index 0000000..3dc2115 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsByAppRequestBuilder.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete records from an app. + /// + public interface IDeleteRecordsByAppRequestBuilder + { + /// + /// Gets the ID of the app from which to delete records. + /// + int AppId { get; } + + /// + /// Specifies the ID of the record to delete. + /// + /// The ID of the record to delete. + /// A for further configuration of the request. + IDeleteRecordByIdRequestBuilder WithId(int recordId); + + /// + /// Specifies the IDs of the records to delete. + /// + /// The IDs of the records to delete. + /// A for further configuration of the request. + IDeleteRecordsByIdsRequestBuilder WithIds(IEnumerable recordIds); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsByIdsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsByIdsRequestBuilder.cs new file mode 100644 index 0000000..b33bb48 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsByIdsRequestBuilder.cs @@ -0,0 +1,28 @@ +using Onspring.API.SDK.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete records from an app by IDs. + /// + public interface IDeleteRecordsByIdsRequestBuilder + { + /// + /// Gets the ID of the app from which to delete records. + /// + int AppId { get; } + + /// + /// Gets the IDs of the records to delete. + /// + IEnumerable RecordIds { get; } + + /// + /// Asynchronously sends the request to delete the records. + /// + /// An awaitable task that returns an when complete. + Task SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsRequestBuilder.cs new file mode 100644 index 0000000..204c0b7 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Delete/IDeleteRecordsRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to delete records. + /// + public interface IDeleteRecordsRequestBuilder + { + /// + /// Specifies the app from which to delete records. + /// + /// The ID of the app from which to delete records. + /// A for further configuration of the request. + IDeleteRecordsByAppRequestBuilder FromApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesByAppRequestBuilder.cs new file mode 100644 index 0000000..804c944 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesByAppRequestBuilder.cs @@ -0,0 +1,82 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a request builder for getting all pages of records from an app. + /// + public interface IGetAllRecordsPagesByAppRequestBuilder + { + /// + /// Gets the ID of the app to retrieve records from. + /// + int AppId { get; } + + /// + /// Gets the page size to use when retrieving records. The default is 50. + /// + int PageSize { get; } + + /// + /// Gets the data format to use when retrieving records. The default is . + /// + DataFormat DataFormat { get; } + + /// + /// Gets the IDs of the fields to retrieve with the records. + /// + IEnumerable FieldIds { get; } + + /// + /// Specifies the fields to retrieve with the records. + /// + /// The IDs of the fields to retrieve with the records. + /// A for further configuration of the request. + IGetAllRecordsPagesByAppRequestBuilder WithFields(IEnumerable fieldIds); + + /// + /// Specifies the data format to use when retrieving records. + /// + /// The data format to use when retrieving records. + /// A for further configuration of the request. + IGetAllRecordsPagesByAppRequestBuilder WithDataFormat(DataFormat dataFormat); + + /// + /// Specifies the page size to use when retrieving records. + /// + /// The page size to use when retrieving records. Must be greater than zero. + /// A for further configuration of the request. + IGetAllRecordsPagesByAppRequestBuilder WithPageSize(int pageSize); + + /// + /// Specifies the filter to be used to query records. + /// + /// The filter to be used to query records. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithFilter(string filter); + + /// + /// Specifies the filter to be used to query records. + /// + /// An action that constructs the filter to be used to query records. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithFilter(Action filter); + + /// + /// Sends the request to get all pages of records from the app. + /// + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(); + + /// + /// Sends the request to get all pages of records from the app. + /// + /// An action that configures the request options. + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(Action options); + } +} diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesByQueryRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesByQueryRequestBuilder.cs new file mode 100644 index 0000000..015c805 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesByQueryRequestBuilder.cs @@ -0,0 +1,87 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get all pages of records from an app by query. + /// + public interface IGetAllRecordsPagesByQueryRequestBuilder + { + /// + /// Gets the ID of the app from which to retrieve records. + /// + int AppId { get; } + + /// + /// Gets the page size to use when retrieving records. The default is 50. + /// + int PageSize { get; } + + /// + /// Gets the IDs of the fields to retrieve with the records. + /// + IEnumerable FieldIds { get; } + + /// + /// Gets the data format to use when retrieving records. The default is . + /// + DataFormat DataFormat { get; } + + /// + /// Gets the filter to be used to query records. + /// + string Filter { get; } + + /// + /// Specifies the fields to retrieve with the records. + /// + /// The IDs of the fields to retrieve with the records. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithFields(IEnumerable fieldIds); + + /// + /// Specifies the data format to use when retrieving records. + /// + /// The data format to use when retrieving records. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithDataFormat(DataFormat dataFormat); + + /// + /// Specifies the page size to use when retrieving records. + /// + /// The page size to use when retrieving records. Must be greater than zero. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithPageSize(int pageSize); + + /// + /// Specifies the filter to be used to query records. + /// + /// The filter to be used to query records. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithFilter(string filter); + + /// + /// Specifies the filter to be used to query records. + /// + /// An action that constructs the filter to be used to query records. + /// A for further configuration of the request. + IGetAllRecordsPagesByQueryRequestBuilder WithFilter(Action filter); + + /// + /// Sends the request to get all pages of records from the app. + /// + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(); + + /// + /// Sends the request to get all pages of records from the app. + /// + /// The options to use when sending the request. + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesRequestBuilder.cs new file mode 100644 index 0000000..af6fbc1 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetAllRecordsPagesRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a request builder for getting all pages of records. + /// + public interface IGetAllRecordsPagesRequestBuilder + { + /// + /// Specifies the app to retrieve records from. + /// + /// The ID of the app to retrieve records from. + /// A for further configuration of the request. + IGetAllRecordsPagesByAppRequestBuilder FromApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordByIdRequestBuilder.cs new file mode 100644 index 0000000..93341e3 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordByIdRequestBuilder.cs @@ -0,0 +1,62 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get a record by ID. + /// + public interface IGetRecordByIdRequestBuilder + { + /// + /// Gets the app from which to retrieve records. + /// + int AppId { get; } + + /// + /// Gets the ID of the record to retrieve. + /// + int RecordId { get; } + + /// + /// Gets the IDs of the fields to retrieve. + /// + IEnumerable FieldIds { get; } + + /// + /// Gets the data format for the response. + /// + DataFormat Format { get; } + + /// + /// Sends the request asynchronously. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Sends the request asynchronously with the specified options. + /// + /// An action that constructs the options to use when sending the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + + /// + /// Specifies the IDs of the fields to retrieve. + /// + /// The IDs of the fields to retrieve. + /// A builder for further configuration of the request. + IGetRecordByIdRequestBuilder WithFieldIds(IEnumerable fieldIds); + + /// + /// Specifies the data format for the response. + /// + /// The data format for the response. + /// A builder for further configuration of the request. + IGetRecordByIdRequestBuilder WithFormat(DataFormat dataFormat); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByAppPagedRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByAppPagedRequestBuilder.cs new file mode 100644 index 0000000..1fcc645 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByAppPagedRequestBuilder.cs @@ -0,0 +1,74 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get records by an app. + /// + public interface IGetRecordsByAppPagedRequestBuilder + { + /// + /// Gets the app from which to retrieve records. + /// + int AppId { get; } + + /// + /// Gets the page number to retrieve. + /// + int PageNumber { get; } + + /// + /// Gets the IDs of the fields to retrieve. + /// + IEnumerable FieldIds { get; } + + /// + /// Gets the data format for the response. + /// + DataFormat Format { get; } + + /// + /// Gets the page size. + /// + int PageSize { get; } + + /// + /// Sends the request asynchronously. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Sends the request asynchronously with the specified options. + /// + /// An action that constructs the options to use when sending the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + + /// + /// Specifies the page size to retrieve. + /// + /// The size of page to retrieve + /// A for further configuration of the request. + IGetRecordsByAppPagedRequestBuilder WithPageSize(int pageSize); + + /// + /// Specifies the IDs of the fields to retrieve. + /// + /// The IDs of the fields to retrieve. + /// A for further configuration of the request. + IGetRecordsByAppPagedRequestBuilder WithFieldIds(IEnumerable fieldIds); + + /// + /// Specifies the data format for the response. + /// + /// The data format for the response. + /// A for further configuration of the request. + IGetRecordsByAppPagedRequestBuilder WithFormat(DataFormat dataFormat); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByAppRequestBuilder.cs new file mode 100644 index 0000000..2180881 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByAppRequestBuilder.cs @@ -0,0 +1,52 @@ +using Onspring.API.SDK.Models; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get records by app. + /// + public interface IGetRecordsByAppRequestBuilder + { + /// + /// Gets the app from which to retrieve records. + /// + int AppId { get; } + + /// + /// Specifies the page number to retrieve. + /// + /// The page number to retrieve. Must be greater than zero. + /// A for further configuration of the request. + IGetRecordsByAppPagedRequestBuilder ForPage(int pageNumber); + + /// + /// Specifies the record ID to retrieve. + /// + /// The ID of the record to retrieve. + /// A for further configuration of the request. + IGetRecordByIdRequestBuilder WithId(int recordId); + + /// + /// Specifies the IDs of the records to retrieve. + /// + /// The IDs of the records to retrieve. + /// A for further configuration of the request. + IGetRecordsByIdsRequestBuilder WithIds(IEnumerable recordIds); + + /// + /// Specifies the filter to be used to query records. + /// + /// The filter to be used to query record + /// A for further configuration of the request. + IQueryRecordsByAppPagedRequestBuilder WithFilter(string filter); + + /// + /// Specifies the filter to be used to query records. + /// + /// An action that constructs the filter to be used to query record + /// A for further configuration of the request. + IQueryRecordsByAppPagedRequestBuilder WithFilter(Action filter); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByIdsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByIdsRequestBuilder.cs new file mode 100644 index 0000000..0e7b718 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsByIdsRequestBuilder.cs @@ -0,0 +1,62 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get records by IDs. + /// + public interface IGetRecordsByIdsRequestBuilder + { + /// + /// Gets the app from which to retrieve records. + /// + int AppId { get; } + + /// + /// Gets the IDs of the records to retrieve. + /// + IEnumerable RecordIds { get; } + + /// + /// Gets the IDs of the fields to retrieve. + /// + IEnumerable FieldIds { get; } + + /// + /// Gets the data format of the response. + /// + DataFormat Format { get; } + + /// + /// Sends the request asynchronously. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Sends the request asynchronously with the specified options. + /// + /// The options to use when sending the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + + /// + /// Specifies the IDs of the fields to retrieve. + /// + /// The IDs of the fields to retrieve. + /// A builder for further configuration of the request. + IGetRecordsByIdsRequestBuilder WithFieldIds(IEnumerable fieldIds); + + /// + /// Specifies the data format of the response. + /// + /// The data format of the response. + /// A builder for further configuration of the request. + IGetRecordsByIdsRequestBuilder WithFormat(DataFormat dataFormat); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsRequestBuilder.cs new file mode 100644 index 0000000..c0be59b --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IGetRecordsRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve records. + /// + public interface IGetRecordsRequestBuilder + { + /// + /// Specifies the app from which to retrieve records. + /// + /// The unique identifier of the app. + /// A for further configuration of the request. + IGetRecordsByAppRequestBuilder FromApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IQueryRecordsByAppPagedRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IQueryRecordsByAppPagedRequestBuilder.cs new file mode 100644 index 0000000..4d5689a --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Get/IQueryRecordsByAppPagedRequestBuilder.cs @@ -0,0 +1,86 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to query records from an app. + /// + public interface IQueryRecordsByAppPagedRequestBuilder + { + /// + /// Gets the application ID. + /// + int AppId { get; } + + /// + /// Gets the filter. + /// + string Filter { get; } + + /// + /// Gets the page number. + /// + int PageNumber { get; } + + /// + /// Gets the page size. + /// + int PageSize { get; } + + /// + /// Gets the field IDs. + /// + IEnumerable FieldIds { get; } + + /// + /// Gets the data format. + /// + DataFormat Format { get; } + + /// + /// Sends the request asynchronously. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Sends the request asynchronously with the specified options. + /// + /// An action that constructs the options to use when sending the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + + /// + /// Sets the page number to retrieve. + /// + /// The page number to retrieve + /// A builder for further configuration of the request. + IQueryRecordsByAppPagedRequestBuilder ForPage(int pageNumber); + + /// + /// Sets the page size to retrieve. + /// + /// The size of page to retrieve + /// A builder for further configuration of the request. + IQueryRecordsByAppPagedRequestBuilder WithPageSize(int pageSize); + + /// + /// Sets the field IDs to retrieve. + /// + /// The field IDs to retrieve + /// A builder for further configuration of the request. + IQueryRecordsByAppPagedRequestBuilder WithFieldIds(IEnumerable fieldIds); + + /// + /// Sets the format of the data to retrieve. + /// + /// The format of the data to retrieve + /// A builder for further configuration of the request. + IQueryRecordsByAppPagedRequestBuilder WithFormat(DataFormat dataFormat); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordByIdRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordByIdRequestBuilder.cs new file mode 100644 index 0000000..0b3ea65 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordByIdRequestBuilder.cs @@ -0,0 +1,28 @@ +using Onspring.API.SDK.Models; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a record by ID. + /// + public interface ISaveRecordByIdRequestBuilder + { + /// + /// Gets the ID of the app in which to save the record. + /// + int AppId { get; } + + /// + /// Gets the ID of the record to save. + /// + int? RecordId { get; } + + /// + /// Specifies the field values to save. + /// + /// The field values to save. + /// A for further configuration of the request. + ISaveRecordByIdWithValuesRequestBuilder WithValues(IEnumerable values); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordByIdWithValuesRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordByIdWithValuesRequestBuilder.cs new file mode 100644 index 0000000..e3be363 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordByIdWithValuesRequestBuilder.cs @@ -0,0 +1,33 @@ +using Onspring.API.SDK.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a record by ID with values. + /// + public interface ISaveRecordByIdWithValuesRequestBuilder + { + /// + /// Gets the ID of the app in which to save the record. + /// + int AppId { get; } + + /// + /// Gets the ID of the record to save. + /// + int? RecordId { get; } + + /// + /// Gets the field values to save. + /// + IEnumerable Values { get; } + + /// + /// Asynchronously sends the request. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordInAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordInAppRequestBuilder.cs new file mode 100644 index 0000000..80f2340 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordInAppRequestBuilder.cs @@ -0,0 +1,20 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a record in an app. + /// + public interface ISaveRecordInAppRequestBuilder + { + /// + /// Gets the ID of the app in which to save the record. + /// + int AppId { get; } + + /// + /// Specifies the record to save. If the record ID is null, a new record will be created. + /// + /// The ID of the record to save. + /// A for further configuration of the request. + ISaveRecordByIdRequestBuilder WithId(int? recordId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordRequestBuilder.cs new file mode 100644 index 0000000..0ab7c22 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Records/Save/ISaveRecordRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to save a record. + /// + public interface ISaveRecordRequestBuilder + { + /// + /// Specifies the app in which to save the record. + /// + /// The ID of the app in which to save the record. + /// A for further configuration of the request. + ISaveRecordInAppRequestBuilder InApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetAllReportsPagesByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetAllReportsPagesByAppRequestBuilder.cs new file mode 100644 index 0000000..9c75a33 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetAllReportsPagesByAppRequestBuilder.cs @@ -0,0 +1,43 @@ +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Interface for building requests to get all pages of reports for a specific app. + /// + public interface IGetAllReportsPagesByAppRequestBuilder + { + /// + /// Gets the app ID for the request. + /// + int AppId { get; } + + /// + /// Gets the page size for the request. Default is 50. + /// + int PageSize { get; } + + /// + /// Sets the page size for the request. + /// + /// The page size. + /// A for further configuration of the request. + IGetAllReportsPagesByAppRequestBuilder WithPageSize(int pageSize); + + /// + /// Sends the request to retrieve all pages of reports for the app. + /// + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(); + + /// + /// Sends the request to retrieve all pages of reports for the app with the specified options. + /// + /// The options to use for the request. + /// An async enumerable of where T is . + IAsyncEnumerable> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetAllReportsPagesRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetAllReportsPagesRequestBuilder.cs new file mode 100644 index 0000000..e475baa --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetAllReportsPagesRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Interface for building requests to get all pages of reports. + /// + public interface IGetAllReportsPagesRequestBuilder + { + /// + /// Sets the app ID for the request. + /// + /// The app ID. + /// A for further configuration of the request. + IGetAllReportsPagesByAppRequestBuilder FromApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportDataRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportDataRequestBuilder.cs new file mode 100644 index 0000000..300966f --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportDataRequestBuilder.cs @@ -0,0 +1,56 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get a report's data. + /// + public interface IGetReportDataRequestBuilder + { + /// + /// Gets the ID of the report to get. + /// + int ReportId { get; } + + /// + /// Gets the format of the report data. + /// + DataFormat Format { get; } + + /// + /// Gets the type of report data to return. + /// + ReportDataType DataType { get; } + + /// + /// Specifies the format of the report data. + /// + /// The format of the report data. + /// A for further configuration of the request. + IGetReportDataRequestBuilder WithFormat(DataFormat format); + + /// + /// Specifies the type of report data to return. + /// + /// The type of report data to return. + /// A for further configuration of the request. + IGetReportDataRequestBuilder WithDataType(ReportDataType dataType); + + /// + /// Asynchronously sends the request. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Asynchronously sends the request with the specified options. + /// + /// An action that constructs the options to use for the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportRequestBuilder.cs new file mode 100644 index 0000000..4db1c15 --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get a report. + /// + public interface IGetReportRequestBuilder + { + /// + /// Specifies the ID of the report to get. + /// + /// The ID of the report to get. + /// A for further configuration of the request. + IGetReportDataRequestBuilder FromReport(int reportId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportsByAppRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportsByAppRequestBuilder.cs new file mode 100644 index 0000000..5c771ec --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportsByAppRequestBuilder.cs @@ -0,0 +1,55 @@ +using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get reports from an app. + /// + public interface IGetReportsByAppRequestBuilder + { + /// + /// Gets the ID of the app from which to get reports. + /// + int AppId { get; } + + /// + /// Gets the page number of the reports to get. + /// + int PageNumber { get; } + + /// + /// Gets the page size of the page of reports to get. + /// + int PageSize { get; } + + /// + /// Specifies the page number of the reports to get. + /// + /// The page number of the reports to get. + /// A for further configuration of the request. + IGetReportsByAppRequestBuilder ForPage(int pageNumber); + + /// + /// Specifies the page size of the page of reports to get. + /// + /// The page size of the page of reports to get. + /// A for further configuration of the request. + IGetReportsByAppRequestBuilder WithPageSize(int pageNumber); + + /// + /// Asynchronously sends the request. + /// + /// An awaitable task that returns an when complete. + Task> SendAsync(); + + /// + /// Asynchronously sends the request with the specified options. + /// + /// An action that constructs the options to use for the request. + /// An awaitable task that returns an when complete. + Task> SendAsync(Action options); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportsRequestBuilder.cs b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportsRequestBuilder.cs new file mode 100644 index 0000000..100050e --- /dev/null +++ b/Onspring.API.SDK/Interfaces/Fluent/Reports/IGetReportsRequestBuilder.cs @@ -0,0 +1,15 @@ +namespace Onspring.API.SDK.Interfaces.Fluent +{ + /// + /// Represents a builder for constructing requests to get reports. + /// + public interface IGetReportsRequestBuilder + { + /// + /// Specifies the ID of the app from which to get reports. + /// + /// The ID of the app from which to get reports. + /// A for further configuration of the request. + IGetReportsByAppRequestBuilder FromApp(int appId); + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Filter.cs b/Onspring.API.SDK/Models/Filter.cs new file mode 100644 index 0000000..a4f83cf --- /dev/null +++ b/Onspring.API.SDK/Models/Filter.cs @@ -0,0 +1,82 @@ +using System; +using Onspring.API.SDK.Enums; + +namespace Onspring.API.SDK.Models +{ + /// + /// Represents a filter used for querying data. + /// + public class Filter + { + /// + /// Gets or sets the identifier of the field to filter on. + /// + public int FieldId { get; set; } + + /// + /// Gets or sets the filter operator to apply to the field. + /// + public FilterOperator Operator { get; set; } + + private object filterValue; + + /// + /// Gets or sets the value to filter against. + /// + public object Value + { + get { return filterValue; } + set + { + if (value == null && Operator != null && Operator != FilterOperator.IsNull && Operator != FilterOperator.NotNull) + { + throw new ArgumentException("Value cannot be null for this operator"); + } + + filterValue = value; + } + } + + /// + /// Initializes a new instance of the class. + /// + internal Filter() { } + + /// + /// Initializes a new instance of the class with specified values. + /// + /// The identifier of the field to filter on. + /// The filter operator to apply to the field. + /// The value to filter against. + public Filter(int fieldId, FilterOperator filterOperator, object value) + { + FieldId = fieldId; + Operator = filterOperator; + Value = value; + } + + /// + /// Returns a string representation of the filter. + /// + /// A string representing the filter. + public override string ToString() + { + if (Value == null) + { + return $"{FieldId} {Operator}"; + } + + if (Value is DateTime dateTime) + { + return $"{FieldId} {Operator} datetime'{dateTime:O}'"; + } + + if (Value is string stringValue) + { + return $"{FieldId} {Operator} '{stringValue}'"; + } + + return $"{FieldId} {Operator} {Value}"; + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Apps/GetAllAppsPagesRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Apps/GetAllAppsPagesRequestBuilder.cs new file mode 100644 index 0000000..cfd1a81 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Apps/GetAllAppsPagesRequestBuilder.cs @@ -0,0 +1,46 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a request builder for getting all pages of apps. + /// + /// + public class GetAllAppsPagesRequestBuilder : IGetAllAppsPagesRequestBuilder + { + private readonly IOnspringClient _client; + public int PageSize { get; private set; } = 50; + + internal GetAllAppsPagesRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetAllAppsPagesRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public async IAsyncEnumerable> SendAsync() + { + await foreach (var response in _client.GetAllAppsAsync(PageSize)) + { + yield return response; + } + } + + public async IAsyncEnumerable> SendAsync(Action options) + { + var opts = new GetAllAppsPagesRequestBuilderOptions(); + options.Invoke(opts); + + await foreach (var response in _client.GetAllAppsAsync(opts.PageSize)) + { + yield return response; + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Apps/GetAllAppsPagesRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Apps/GetAllAppsPagesRequestBuilderOptions.cs new file mode 100644 index 0000000..196a794 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Apps/GetAllAppsPagesRequestBuilderOptions.cs @@ -0,0 +1,13 @@ +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to retrieve all pages of apps. + /// + public class GetAllAppsPagesRequestBuilderOptions + { + /// + /// Gets or sets the page size to retrieve. The default is 50. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Apps/GetAppByIdRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Apps/GetAppByIdRequestBuilder.cs new file mode 100644 index 0000000..17d52d6 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Apps/GetAppByIdRequestBuilder.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve an app by ID. + /// + /// + public class GetAppByIdRequestBuilder : IGetAppByIdRequestBuilder + { + private readonly IOnspringClient _client; + + public int AppId { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The client used to send the request. + /// The ID of the app to retrieve. + internal GetAppByIdRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public async Task> SendAsync() + { + return await _client.GetAppAsync(AppId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Apps/GetAppsByIdsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Apps/GetAppsByIdsRequestBuilder.cs new file mode 100644 index 0000000..953b600 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Apps/GetAppsByIdsRequestBuilder.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve apps by IDs + /// + /// + public class GetAppsByIdsRequestBuilder : IGetAppsByIdsRequestBuilder + { + private readonly IOnspringClient _client; + public IEnumerable AppIds { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + /// The IDs of the apps to retrieve. + internal GetAppsByIdsRequestBuilder(IOnspringClient client, IEnumerable appIds) + { + _client = client; + AppIds = appIds; + } + + public async Task> SendAsync() + { + return await _client.GetAppsAsync(AppIds); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Apps/GetAppsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Apps/GetAppsRequestBuilder.cs new file mode 100644 index 0000000..b8c8d51 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Apps/GetAppsRequestBuilder.cs @@ -0,0 +1,38 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve apps. + /// + /// + public class GetAppsRequestBuilder : IGetAppsRequestBuilder + { + private readonly IOnspringClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal GetAppsRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetPagedAppsRequestBuilder ForPage(int pageNumber) + { + return new GetPagedAppsRequestBuilder(_client, pageNumber); + } + + public IGetAppsByIdsRequestBuilder WithIds(IEnumerable appIds) + { + return new GetAppsByIdsRequestBuilder(_client, appIds); + } + + public IGetAppByIdRequestBuilder WithId(int appId) + { + return new GetAppByIdRequestBuilder(_client, appId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Apps/GetPagedAppsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Apps/GetPagedAppsRequestBuilder.cs new file mode 100644 index 0000000..10683a6 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Apps/GetPagedAppsRequestBuilder.cs @@ -0,0 +1,38 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve apps that are paginated. + /// + /// + public class GetPagedAppsRequestBuilder : IGetPagedAppsRequestBuilder + { + private readonly IOnspringClient _client; + public int PageNumber { get; private set; } + public int PageSize { get; private set; } = 50; + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + /// The page number of the apps to retrieve. + internal GetPagedAppsRequestBuilder(IOnspringClient client, int pageNumber) + { + _client = client; + PageNumber = pageNumber; + } + + public IGetPagedAppsRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public async Task> SendAsync() + { + return await _client.GetAppsAsync(new PagingRequest(PageNumber, PageSize)); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilder.cs new file mode 100644 index 0000000..674b0e6 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilder.cs @@ -0,0 +1,48 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a request builder for getting all pages of fields. + /// + /// + public class GetAllFieldsPagesByAppRequestBuilder : IGetAllFieldsPagesByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int PageSize { get; private set; } = 50; + + internal GetAllFieldsPagesByAppRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public IGetAllFieldsPagesByAppRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public async IAsyncEnumerable> SendAsync() + { + await foreach (var response in _client.GetAllFieldsForAppAsync(AppId, PageSize)) + { + yield return response; + } + } + + public async IAsyncEnumerable> SendAsync(Action options) + { + var opts = new GetAllFieldsPagesByAppRequestBuilderOptions(); + options.Invoke(opts); + + await foreach (var response in _client.GetAllFieldsForAppAsync(AppId, opts.PageSize)) + { + yield return response; + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilderOptions.cs new file mode 100644 index 0000000..4e27ac0 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesByAppRequestBuilderOptions.cs @@ -0,0 +1,13 @@ +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to retrieve all pages of fields for an app. + /// + public class GetAllFieldsPagesByAppRequestBuilderOptions + { + /// + /// Gets or sets the page size to retrieve. The default is 50. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesRequestBuilder.cs new file mode 100644 index 0000000..3f18284 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetAllFieldsPagesRequestBuilder.cs @@ -0,0 +1,23 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a request builder for getting all pages of fields. + /// + /// + public class GetAllFieldsPagesRequestBuilder : IGetAllFieldsPagesRequestBuilder + { + private readonly IOnspringClient _client; + + internal GetAllFieldsPagesRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetAllFieldsPagesByAppRequestBuilder FromApp(int appId) + { + return new GetAllFieldsPagesByAppRequestBuilder(_client, appId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetFieldByIdRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldByIdRequestBuilder.cs new file mode 100644 index 0000000..3eafc2f --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldByIdRequestBuilder.cs @@ -0,0 +1,29 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields by id. + /// + /// + public class GetFieldByIdRequestBuilder : IGetFieldByIdRequestBuilder + { + private readonly IOnspringClient _client; + public int FieldId { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + internal GetFieldByIdRequestBuilder(IOnspringClient client, int fieldId) + { + _client = client; + FieldId = fieldId; + } + + public async Task> SendAsync() + { + return await _client.GetFieldAsync(FieldId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByAppRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByAppRequestBuilder.cs new file mode 100644 index 0000000..2a4ecec --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByAppRequestBuilder.cs @@ -0,0 +1,53 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields by app. + /// + /// + public class GetFieldsByAppRequestBuilder : IGetFieldsByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int PageNumber { get; private set; } = 1; + public int PageSize { get; private set; } = 50; + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + /// The ID of the app to retrieve fields for. + internal GetFieldsByAppRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public IGetFieldsByAppRequestBuilder ForPage(int pageNumber) + { + PageNumber = pageNumber; + return this; + } + + public IGetFieldsByAppRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public async Task> SendAsync() + { + return await _client.GetFieldsForAppAsync(AppId, new PagingRequest(PageNumber, PageSize)); + } + + public async Task> SendAsync(Action options) + { + var opts = new GetFieldsByAppRequestBuilderOptions(); + options.Invoke(opts); + return await _client.GetFieldsForAppAsync(AppId, new PagingRequest(opts.PageNumber, opts.PageSize)); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByAppRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByAppRequestBuilderOptions.cs new file mode 100644 index 0000000..34deec2 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByAppRequestBuilderOptions.cs @@ -0,0 +1,18 @@ +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to retrieve fields by app. + /// + public class GetFieldsByAppRequestBuilderOptions + { + /// + /// Gets or sets the page number to retrieve. The default is 1. + /// + public int PageNumber { get; set; } = 1; + + /// + /// Gets or sets the page size to retrieve. The default is 50. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByIdsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByIdsRequestBuilder.cs new file mode 100644 index 0000000..cf1a8c4 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsByIdsRequestBuilder.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields by IDs. + /// + /// + public class GetFieldsByIdsRequestBuilder : IGetFieldsByIdsRequestBuilder + { + private readonly IOnspringClient _client; + public IEnumerable FieldIds { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + /// The IDs of the fields to retrieve. + internal GetFieldsByIdsRequestBuilder(IOnspringClient client, IEnumerable fieldIds) + { + _client = client; + FieldIds = fieldIds; + } + + public async Task> SendAsync() + { + return await _client.GetFieldsAsync(FieldIds); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsRequestBuilder.cs new file mode 100644 index 0000000..9cff157 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Fields/GetFieldsRequestBuilder.cs @@ -0,0 +1,38 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve fields. + /// + /// + public class GetFieldsRequestBuilder : IGetFieldsRequestBuilder + { + private readonly IOnspringClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal GetFieldsRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetFieldsByAppRequestBuilder FromApp(int appId) + { + return new GetFieldsByAppRequestBuilder(_client, appId); + } + + public IGetFieldByIdRequestBuilder WithId(int fieldId) + { + return new GetFieldByIdRequestBuilder(_client, fieldId); + } + + public IGetFieldsByIdsRequestBuilder WithIds(IEnumerable fieldIds) + { + return new GetFieldsByIdsRequestBuilder(_client, fieldIds); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Files/Add/AddFileRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Files/Add/AddFileRequestBuilder.cs new file mode 100644 index 0000000..cd00706 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Files/Add/AddFileRequestBuilder.cs @@ -0,0 +1,100 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to add a file. + /// + /// + public class AddFileRequestBuilder : + IAddFileRequestBuilder, + IAddFileToRecordRequestBuilder, + IAddFileInFieldRequestBuilder, + IAddFileWithNameRequestBuilder, + IAddFileWithStreamRequestBuilder, + IAddFileWithTypeRequestBuilder, + IAddFileWithNotesRequestBuilder, + IAddFileWithModifiedDateRequestBuilder + { + private readonly IOnspringClient _client; + public int RecordId { get; private set; } + public int FieldId { get; private set; } + public string Name { get; private set; } + public Stream FileStream { get; private set; } + public string Type { get; private set; } + public string Notes { get; private set; } + public DateTime? ModifiedDate { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal AddFileRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IAddFileToRecordRequestBuilder ToRecord(int recordId) + { + RecordId = recordId; + return this; + } + + public IAddFileInFieldRequestBuilder InField(int fieldId) + { + FieldId = fieldId; + return this; + } + + public IAddFileWithNameRequestBuilder WithName(string name) + { + Name = name; + return this; + } + + public IAddFileWithStreamRequestBuilder WithStream(Stream stream) + { + FileStream = stream; + return this; + } + + public IAddFileWithTypeRequestBuilder WithType(string type) + { + Type = type; + return this; + } + + public IAddFileWithNotesRequestBuilder WithNotes(string notes) + { + Notes = notes; + return this; + } + + public IAddFileWithModifiedDateRequestBuilder WithModifiedDate(DateTime? modifiedDate) + { + ModifiedDate = modifiedDate; + return this; + } + + + + public async Task>> SendAsync() + { + return await _client.SaveFileAsync( + new SaveFileRequest + { + RecordId = RecordId, + FieldId = FieldId, + Notes = Notes, + ModifiedDate = ModifiedDate, + ContentType = Type, + FileName = Name, + FileStream = FileStream, + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Files/Delete/DeleteFileRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Files/Delete/DeleteFileRequestBuilder.cs new file mode 100644 index 0000000..f9ce069 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Files/Delete/DeleteFileRequestBuilder.cs @@ -0,0 +1,53 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a file. + /// + /// + public class DeleteFileRequestBuilder : + IDeleteFileRequestBuilder, + IDeleteFileFromRecordRequestBuilder, + IDeleteFileInFieldRequestBuilder, + IDeleteFileByIdRequestBuilder + { + private readonly IOnspringClient _client; + public int RecordId { get; private set; } + public int FieldId { get; private set; } + public int FileId { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal DeleteFileRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IDeleteFileFromRecordRequestBuilder FromRecord(int recordId) + { + RecordId = recordId; + return this; + } + + public IDeleteFileInFieldRequestBuilder InField(int fieldId) + { + FieldId = fieldId; + return this; + } + + public IDeleteFileByIdRequestBuilder WithId(int fileId) + { + FileId = fileId; + return this; + } + + public async Task SendAsync() + { + return await _client.DeleteFileAsync(RecordId, FieldId, FileId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Files/Get/GetFileInfoRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Files/Get/GetFileInfoRequestBuilder.cs new file mode 100644 index 0000000..0828b49 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Files/Get/GetFileInfoRequestBuilder.cs @@ -0,0 +1,52 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve information about a file. + /// + public class GetFileInfoRequestBuilder : + IGetFileInfoRequestBuilder, + IGetFileInfoFromRecordRequestBuilder, + IGetFileInfoInFieldRequestBuilder, + IGetFileInfoByIdRequestBuilder + { + private readonly IOnspringClient _client; + public int RecordId { get; private set; } + public int FieldId { get; private set; } + public int FileId { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal GetFileInfoRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetFileInfoFromRecordRequestBuilder FromRecord(int recordId) + { + RecordId = recordId; + return this; + } + + public IGetFileInfoInFieldRequestBuilder InField(int fieldId) + { + FieldId = fieldId; + return this; + } + + public IGetFileInfoByIdRequestBuilder WithId(int fileId) + { + FileId = fileId; + return this; + } + + public async Task> SendAsync() + { + return await _client.GetFileInfoAsync(RecordId, FieldId, FileId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Files/Get/GetFileRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Files/Get/GetFileRequestBuilder.cs new file mode 100644 index 0000000..424bcc3 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Files/Get/GetFileRequestBuilder.cs @@ -0,0 +1,53 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve a file. + /// + /// + public class GetFileRequestBuilder : + IGetFileRequestBuilder, + IGetFileFromRecordRequestBuilder, + IGetFileInFieldRequestBuilder, + IGetFileByIdRequestBuilder + { + private readonly IOnspringClient _client; + public int RecordId { get; private set; } + public int FieldId { get; private set; } + public int FileId { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal GetFileRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetFileFromRecordRequestBuilder FromRecord(int recordId) + { + RecordId = recordId; + return this; + } + + public IGetFileInFieldRequestBuilder InField(int fieldId) + { + FieldId = fieldId; + return this; + } + + public IGetFileByIdRequestBuilder WithId(int fileId) + { + FileId = fileId; + return this; + } + + public async Task> SendAsync() + { + return await _client.GetFileAsync(RecordId, FieldId, FileId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Lists/Delete/DeleteListValueRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Lists/Delete/DeleteListValueRequestBuilder.cs new file mode 100644 index 0000000..a7f179a --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Lists/Delete/DeleteListValueRequestBuilder.cs @@ -0,0 +1,46 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a list value. + /// + /// + public class DeleteListValueRequestBuilder : + IDeleteListValueRequestBuilder, + IDeleteListValueInListRequestBuilder, + IDeleteListValueWithIdRequestBuilder + { + private readonly IOnspringClient _client; + public int ListId { get; private set; } + public Guid Id { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal DeleteListValueRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IDeleteListValueInListRequestBuilder InList(int listId) + { + ListId = listId; + return this; + } + + public IDeleteListValueWithIdRequestBuilder WithId(Guid id) + { + Id = id; + return this; + } + + public async Task SendAsync() + { + return await _client.DeleteListItemAsync(ListId, Id); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Lists/Save/SaveListValueRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Lists/Save/SaveListValueRequestBuilder.cs new file mode 100644 index 0000000..fa9ca6a --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Lists/Save/SaveListValueRequestBuilder.cs @@ -0,0 +1,77 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to save a list value. + /// + /// + public class SaveListValueRequestBuilder : + ISaveListValueRequestBuilder, + ISaveListValueInListRequestBuilder, + ISaveListValueWithIdRequestBuilder, + ISaveListValueWithNameRequestBuilder + { + private readonly IOnspringClient _client; + public int ListId { get; private set; } + public Guid? Id { get; private set; } + public string Name { get; private set; } + public decimal? NumericValue { get; private set; } + public string Color { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal SaveListValueRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public ISaveListValueInListRequestBuilder InList(int listId) + { + ListId = listId; + return this; + } + + public ISaveListValueWithIdRequestBuilder WithId(Guid? id) + { + Id = id; + return this; + } + + public ISaveListValueWithNameRequestBuilder WithName(string name) + { + Name = name; + return this; + } + + public ISaveListValueWithNameRequestBuilder WithColor(string color) + { + Color = color; + return this; + } + + public ISaveListValueWithNameRequestBuilder WithNumericValue(decimal value) + { + NumericValue = value; + return this; + } + + public async Task> SendAsync() + { + return await _client.SaveListItemAsync( + new SaveListItemRequest + { + ListId = ListId, + Id = Id, + Name = Name, + NumericValue = NumericValue, + Color = Color, + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/OnspringRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/OnspringRequestBuilder.cs new file mode 100644 index 0000000..d2f03be --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/OnspringRequestBuilder.cs @@ -0,0 +1,97 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing Onspring API requests. + /// + /// + public class OnspringRequestBuilder : IOnspringRequestBuilder + { + private readonly IOnspringClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The Onspring client to use for making API requests. + internal OnspringRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IConnectionRequestBuilder ToCheckConnection() + { + return new ConnectionRequestBuilder(_client); + } + + public IGetRecordsRequestBuilder ToGetRecords() + { + return new GetRecordsRequestBuilder(_client); + } + + public ISaveRecordRequestBuilder ToSaveRecord() + { + return new SaveRecordRequestBuilder(_client); + } + + public IDeleteRecordsRequestBuilder ToDeleteRecords() + { + return new DeleteRecordsRequestBuilder(_client); + } + + public IGetReportsRequestBuilder ToGetReports() + { + return new GetReportsRequestBuilder(_client); + } + + public IGetReportRequestBuilder ToGetReportData() + { + return new GetReportRequestBuilder(_client); + } + + public ISaveListValueRequestBuilder ToSaveListValue() + { + return new SaveListValueRequestBuilder(_client); + } + + public IDeleteListValueRequestBuilder ToDeleteListValue() + { + return new DeleteListValueRequestBuilder(_client); + } + + public IGetFileRequestBuilder ToGetFile() + { + return new GetFileRequestBuilder(_client); + } + + public IGetFileInfoRequestBuilder ToGetFileInfo() + { + return new GetFileInfoRequestBuilder(_client); + } + + public IDeleteFileRequestBuilder ToDeleteFile() + { + return new DeleteFileRequestBuilder(_client); + } + + public IAddFileRequestBuilder ToAddFile() + { + return new AddFileRequestBuilder(_client); + } + + public IGetFieldsRequestBuilder ToGetFields() + { + return new GetFieldsRequestBuilder(_client); + } + + public IGetAppsRequestBuilder ToGetApps() + { + return new GetAppsRequestBuilder(_client); + } + + public IPagedRequestBuilder ToGetAllPages() + { + return new PagedRequestBuilder(_client); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Pagination/PagedRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Pagination/PagedRequestBuilder.cs new file mode 100644 index 0000000..d0832a3 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Pagination/PagedRequestBuilder.cs @@ -0,0 +1,38 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for paged requests. + /// + /// + public class PagedRequestBuilder : IPagedRequestBuilder + { + private readonly IOnspringClient _client; + + internal PagedRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetAllAppsPagesRequestBuilder OfApps() + { + return new GetAllAppsPagesRequestBuilder(_client); + } + + public IGetAllFieldsPagesRequestBuilder OfFields() + { + return new GetAllFieldsPagesRequestBuilder(_client); + } + + public IGetAllRecordsPagesRequestBuilder OfRecords() + { + return new GetAllRecordsPagesRequestBuilder(_client); + } + + public IGetAllReportsPagesRequestBuilder OfReports() + { + return new GetAllReportsPagesRequestBuilder(_client); + } + } +} diff --git a/Onspring.API.SDK/Models/Fluent/Ping/ConnectionRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Ping/ConnectionRequestBuilder.cs new file mode 100644 index 0000000..b1dbe2a --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Ping/ConnectionRequestBuilder.cs @@ -0,0 +1,21 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + public class ConnectionRequestBuilder : IConnectionRequestBuilder + { + private readonly IOnspringClient _client; + + internal ConnectionRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public async Task SendAsync() + { + return await _client.CanConnectAsync(); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordByIdRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordByIdRequestBuilder.cs new file mode 100644 index 0000000..a30b847 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordByIdRequestBuilder.cs @@ -0,0 +1,33 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to delete a record from an app by ID. + /// + public class DeleteRecordByIdRequestBuilder : IDeleteRecordByIdRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int RecordId { get; private set; } + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The ID of the app from which to delete the record. + /// The ID of the record to delete. + internal DeleteRecordByIdRequestBuilder(IOnspringClient client, int appId, int recordId) + { + _client = client; + AppId = appId; + RecordId = recordId; + } + + public async Task SendAsync() + { + return await _client.DeleteRecordAsync(AppId, RecordId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsByAppRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsByAppRequestBuilder.cs new file mode 100644 index 0000000..d4df61a --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsByAppRequestBuilder.cs @@ -0,0 +1,36 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to delete records from an app. + /// + /// + public class DeleteRecordsByAppRequestBuilder : IDeleteRecordsByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The ID of the app from which to delete records. + internal DeleteRecordsByAppRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public IDeleteRecordByIdRequestBuilder WithId(int recordId) + { + return new DeleteRecordByIdRequestBuilder(_client, AppId, recordId); + } + + public IDeleteRecordsByIdsRequestBuilder WithIds(IEnumerable recordIds) + { + return new DeleteRecordsByIdsRequestBuilder(_client, AppId, recordIds); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsByIdsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsByIdsRequestBuilder.cs new file mode 100644 index 0000000..d808bc5 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsByIdsRequestBuilder.cs @@ -0,0 +1,41 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to delete records from an app by IDs. + /// + public class DeleteRecordsByIdsRequestBuilder : IDeleteRecordsByIdsRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public IEnumerable RecordIds { get; private set; } + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The ID of the app from which to delete records. + /// The IDs of the records to delete. + internal DeleteRecordsByIdsRequestBuilder(IOnspringClient client, int appId, IEnumerable recordIds) + { + _client = client; + AppId = appId; + RecordIds = recordIds; + } + + public async Task SendAsync() + { + return await _client.DeleteRecordsAsync( + new DeleteRecordsRequest + { + AppId = AppId, + RecordIds = RecordIds.ToList(), + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsRequestBuilder.cs new file mode 100644 index 0000000..724eaa7 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Delete/DeleteRecordsRequestBuilder.cs @@ -0,0 +1,27 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to delete records. + /// + /// + public class DeleteRecordsRequestBuilder : IDeleteRecordsRequestBuilder + { + private readonly IOnspringClient _client; + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + internal DeleteRecordsRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IDeleteRecordsByAppRequestBuilder FromApp(int appId) + { + return new DeleteRecordsByAppRequestBuilder(_client, appId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilder.cs new file mode 100644 index 0000000..16cfc52 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilder.cs @@ -0,0 +1,107 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a request builder for getting all pages of records from an app. + /// + /// + public class GetAllRecordsPagesByAppRequestBuilder : IGetAllRecordsPagesByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; } + public int PageSize { get; private set; } = 50; + public DataFormat DataFormat { get; private set; } = DataFormat.Raw; + public IEnumerable FieldIds { get; private set; } = Enumerable.Empty(); + + internal GetAllRecordsPagesByAppRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public IGetAllRecordsPagesByAppRequestBuilder WithDataFormat(DataFormat dataFormat) + { + DataFormat = dataFormat; + return this; + } + + public IGetAllRecordsPagesByAppRequestBuilder WithFields(IEnumerable fieldIds) + { + FieldIds = fieldIds; + return this; + } + + public IGetAllRecordsPagesByAppRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithFilter(string filter) + { + return new GetAllRecordsPagesByQueryRequestBuilder( + _client, + AppId, + PageSize, + FieldIds, + DataFormat, + filter + ); + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithFilter(Action filter) + { + var newFilter = new Filter(); + filter.Invoke(newFilter); + + return new GetAllRecordsPagesByQueryRequestBuilder( + _client, + AppId, + PageSize, + FieldIds, + DataFormat, + newFilter.ToString() + ); + } + + public async IAsyncEnumerable> SendAsync() + { + var request = new GetRecordsByAppRequest + { + AppId = AppId, + PagingRequest = new PagingRequest { PageSize = PageSize }, + DataFormat = DataFormat, + FieldIds = FieldIds.ToList(), + }; + + await foreach (var response in _client.GetAllRecordsForAppAsync(request)) + { + yield return response; + } + } + + public async IAsyncEnumerable> SendAsync(Action options) + { + var opts = new GetAllRecordsPagesByAppRequestBuilderOptions(); + options.Invoke(opts); + + var request = new GetRecordsByAppRequest + { + AppId = AppId, + PagingRequest = new PagingRequest { PageSize = opts.PageSize }, + DataFormat = opts.DataFormat, + FieldIds = opts.FieldIds.ToList(), + }; + + await foreach (var response in _client.GetAllRecordsForAppAsync(request)) + { + yield return response; + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilderOptions.cs new file mode 100644 index 0000000..a65d4bb --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByAppRequestBuilderOptions.cs @@ -0,0 +1,27 @@ +using Onspring.API.SDK.Enums; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to retrieve all pages of records for an app. + /// + public class GetAllRecordsPagesByAppRequestBuilderOptions + { + /// + /// Gets or sets the IDs of the fields to retrieve. + /// + public IEnumerable FieldIds { get; set; } = Enumerable.Empty(); + + /// + /// Gets or sets the data format to retrieve. The default is . + /// + public DataFormat DataFormat { get; set; } = DataFormat.Raw; + + /// + /// Gets or sets the page size to retrieve. The default is 50. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByQueryRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByQueryRequestBuilder.cs new file mode 100644 index 0000000..26edc61 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesByQueryRequestBuilder.cs @@ -0,0 +1,106 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to get all pages of records from an app by query. + /// + /// + public class GetAllRecordsPagesByQueryRequestBuilder : IGetAllRecordsPagesByQueryRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; } + public int PageSize { get; private set; } = 50; + public DataFormat DataFormat { get; private set; } = DataFormat.Raw; + public IEnumerable FieldIds { get; private set; } = Enumerable.Empty(); + public string Filter { get; private set; } + + internal GetAllRecordsPagesByQueryRequestBuilder( + IOnspringClient client, + int appId, + int pageSize, + IEnumerable fieldIds, + DataFormat dataFormat, + string filter + ) + { + _client = client; + AppId = appId; + PageSize = pageSize; + FieldIds = fieldIds; + DataFormat = dataFormat; + Filter = filter; + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithDataFormat(DataFormat dataFormat) + { + DataFormat = dataFormat; + return this; + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithFields(IEnumerable fieldIds) + { + FieldIds = fieldIds; + return this; + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithFilter(string filter) + { + Filter = filter; + return this; + } + + public IGetAllRecordsPagesByQueryRequestBuilder WithFilter(Action filter) + { + var newFilter = new Filter(); + filter.Invoke(newFilter); + Filter = newFilter.ToString(); + return this; + } + + public async IAsyncEnumerable> SendAsync() + { + var request = new QueryRecordsRequest + { + AppId = AppId, + DataFormat = DataFormat, + FieldIds = FieldIds.ToList(), + Filter = Filter + }; + + await foreach (var response in _client.GetAllRecordsByQueryAsync(request, PageSize)) + { + yield return response; + } + } + + public async IAsyncEnumerable> SendAsync(Action options) + { + var opts = new GetAllRecordsPagesByAppRequestBuilderOptions(); + options.Invoke(opts); + + var request = new QueryRecordsRequest + { + AppId = AppId, + DataFormat = opts.DataFormat, + FieldIds = opts.FieldIds.ToList(), + Filter = Filter + }; + + await foreach (var response in _client.GetAllRecordsByQueryAsync(request, opts.PageSize)) + { + yield return response; + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesRequestBuilder.cs new file mode 100644 index 0000000..269bbe3 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetAllRecordsPagesRequestBuilder.cs @@ -0,0 +1,19 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + public class GetAllRecordsPagesRequestBuilder : IGetAllRecordsPagesRequestBuilder + { + private readonly IOnspringClient _client; + + internal GetAllRecordsPagesRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetAllRecordsPagesByAppRequestBuilder FromApp(int appId) + { + return new GetAllRecordsPagesByAppRequestBuilder(_client, appId); + } + } +} diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordByIdRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordByIdRequestBuilder.cs new file mode 100644 index 0000000..18e3642 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordByIdRequestBuilder.cs @@ -0,0 +1,75 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to get a record by ID. + /// + /// + public class GetRecordByIdRequestBuilder : IGetRecordByIdRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int RecordId { get; private set; } + public IEnumerable FieldIds { get; private set; } = Enumerable.Empty(); + public DataFormat Format { get; private set; } = DataFormat.Raw; + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The unique identifier of the app from which to retrieve records. + /// The ID of the record to retrieve. + internal GetRecordByIdRequestBuilder(IOnspringClient client, int appId, int recordId) + { + _client = client; + AppId = appId; + RecordId = recordId; + } + + public IGetRecordByIdRequestBuilder WithFieldIds(IEnumerable fieldIds) + { + FieldIds = fieldIds; + return this; + } + + public IGetRecordByIdRequestBuilder WithFormat(DataFormat dataFormat) + { + Format = dataFormat; + return this; + } + + async public Task> SendAsync() + { + return await _client.GetRecordAsync( + new GetRecordRequest + { + AppId = AppId, + RecordId = RecordId, + FieldIds = FieldIds.ToList(), + DataFormat = Format, + } + ); + } + + async public Task> SendAsync(Action options) + { + var opts = new GetRecordByIdRequestBuilderOptions(); + options.Invoke(opts); + return await _client.GetRecordAsync( + new GetRecordRequest + { + AppId = AppId, + RecordId = RecordId, + FieldIds = opts.FieldIds.ToList(), + DataFormat = opts.Format, + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordByIdRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordByIdRequestBuilderOptions.cs new file mode 100644 index 0000000..175c0dc --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordByIdRequestBuilderOptions.cs @@ -0,0 +1,22 @@ +using Onspring.API.SDK.Enums; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to get a record by ID. + /// + public class GetRecordByIdRequestBuilderOptions + { + /// + /// Gets or sets the IDs of the fields to retrieve. + /// + public IEnumerable FieldIds { get; set; } = Enumerable.Empty(); + + /// + /// Gets or sets the data format for the response. + /// + public DataFormat Format { get; set; } = DataFormat.Raw; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilder.cs new file mode 100644 index 0000000..29fae71 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilder.cs @@ -0,0 +1,90 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to get records by an app. + /// + /// + public class GetRecordsByAppPagedRequestBuilder : IGetRecordsByAppPagedRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int PageNumber { get; private set; } + public IEnumerable FieldIds { get; private set; } = Enumerable.Empty(); + public DataFormat Format { get; private set; } = DataFormat.Raw; + public int PageSize { get; private set; } = 50; + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The unique identifier of the app from which to retrieve records. + /// The page number to retrieve. + internal GetRecordsByAppPagedRequestBuilder(IOnspringClient client, int appId, int pageNumber) + { + _client = client; + AppId = appId; + PageNumber = pageNumber; + } + + public IGetRecordsByAppPagedRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public IGetRecordsByAppPagedRequestBuilder WithFieldIds(IEnumerable fieldIds) + { + FieldIds = fieldIds; + return this; + } + + public IGetRecordsByAppPagedRequestBuilder WithFormat(DataFormat dataFormat) + { + Format = dataFormat; + return this; + } + + async public Task> SendAsync() + { + return await _client.GetRecordsForAppAsync( + new GetRecordsByAppRequest + { + AppId = AppId, + FieldIds = FieldIds.ToList(), + DataFormat = Format, + PagingRequest = new PagingRequest + { + PageNumber = PageNumber, + PageSize = PageSize + } + } + ); + } + + async public Task> SendAsync(Action options) + { + var opts = new GetRecordsByAppPagedRequestBuilderOptions(); + options.Invoke(opts); + return await _client.GetRecordsForAppAsync( + new GetRecordsByAppRequest + { + AppId = AppId, + FieldIds = opts.FieldIds.ToList(), + DataFormat = opts.Format, + PagingRequest = new PagingRequest + { + PageNumber = PageNumber, + PageSize = opts.PageSize, + } + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilderOptions.cs new file mode 100644 index 0000000..509c5fb --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppPagedRequestBuilderOptions.cs @@ -0,0 +1,27 @@ +using Onspring.API.SDK.Enums; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to get records by an app. + /// + public class GetRecordsByAppPagedRequestBuilderOptions + { + /// + /// Gets or sets the IDs of the fields to retrieve. + /// + public IEnumerable FieldIds { get; set; } = Enumerable.Empty(); + + /// + /// Gets or sets the data format for the response. + /// + public DataFormat Format { get; set; } = DataFormat.Raw; + + /// + /// Gets or sets the page size for the paged request. Default is 50. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppRequestBuilder.cs new file mode 100644 index 0000000..cbb668d --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByAppRequestBuilder.cs @@ -0,0 +1,54 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to get records by app. + /// + /// + public class GetRecordsByAppRequestBuilder : IGetRecordsByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The unique identifier of the app from which to retrieve records. + internal GetRecordsByAppRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public IGetRecordsByAppPagedRequestBuilder ForPage(int pageNumber) + { + return new GetRecordsByAppPagedRequestBuilder(_client, AppId, pageNumber); + } + + public IGetRecordByIdRequestBuilder WithId(int recordId) + { + return new GetRecordByIdRequestBuilder(_client, AppId, recordId); + } + + public IGetRecordsByIdsRequestBuilder WithIds(IEnumerable recordIds) + { + return new GetRecordsByIdsRequestBuilder(_client, AppId, recordIds); + } + + public IQueryRecordsByAppPagedRequestBuilder WithFilter(string filter) + { + return new QueryRecordsByAppPagedRequestBuilder(_client, AppId, filter); + } + + public IQueryRecordsByAppPagedRequestBuilder WithFilter(Action filter) + { + var queryFilter = new Filter(); + filter.Invoke(queryFilter); + return new QueryRecordsByAppPagedRequestBuilder(_client, AppId, queryFilter.ToString()); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByIdsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByIdsRequestBuilder.cs new file mode 100644 index 0000000..3fb79c1 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByIdsRequestBuilder.cs @@ -0,0 +1,75 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// A builder for constructing requests to get records by IDs. + /// + /// + public class GetRecordsByIdsRequestBuilder : IGetRecordsByIdsRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public IEnumerable RecordIds { get; private set; } + public IEnumerable FieldIds { get; private set; } = Enumerable.Empty(); + public DataFormat Format { get; private set; } = DataFormat.Raw; + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The unique identifier of the app from which to retrieve records. + /// The unique identifiers of the records to retrieve. + internal GetRecordsByIdsRequestBuilder(IOnspringClient client, int appId, IEnumerable recordIds) + { + _client = client; + AppId = appId; + RecordIds = recordIds; + } + + public IGetRecordsByIdsRequestBuilder WithFieldIds(IEnumerable fieldIds) + { + FieldIds = fieldIds; + return this; + } + + public IGetRecordsByIdsRequestBuilder WithFormat(DataFormat dataFormat) + { + Format = dataFormat; + return this; + } + + async public Task> SendAsync() + { + return await _client.GetRecordsAsync( + new GetRecordsRequest + { + AppId = AppId, + RecordIds = RecordIds.ToList(), + FieldIds = FieldIds.ToList(), + DataFormat = Format, + } + ); + } + + async public Task> SendAsync(Action options) + { + var opts = new GetRecordsByIdsRequestBuilderOptions(); + options.Invoke(opts); + return await _client.GetRecordsAsync( + new GetRecordsRequest + { + AppId = AppId, + RecordIds = RecordIds.ToList(), + FieldIds = opts.FieldIds.ToList(), + DataFormat = opts.Format, + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByIdsRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByIdsRequestBuilderOptions.cs new file mode 100644 index 0000000..f53241b --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsByIdsRequestBuilderOptions.cs @@ -0,0 +1,22 @@ +using Onspring.API.SDK.Enums; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents options for building requests to get records by IDs. + /// + public class GetRecordsByIdsRequestBuilderOptions + { + /// + /// Gets or sets the IDs of the fields to retrieve. Default is an empty collection. + /// + public IEnumerable FieldIds { get; set; } = Enumerable.Empty(); + + /// + /// Gets or sets the data format for the query results. Default is . + /// + public DataFormat Format { get; set; } = DataFormat.Raw; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsRequestBuilder.cs new file mode 100644 index 0000000..12aaef4 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/GetRecordsRequestBuilder.cs @@ -0,0 +1,27 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to retrieve records. + /// + /// + public class GetRecordsRequestBuilder : IGetRecordsRequestBuilder + { + private readonly IOnspringClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The Onspring client to use for making API requests. + internal GetRecordsRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetRecordsByAppRequestBuilder FromApp(int appId) + { + return new GetRecordsByAppRequestBuilder(_client, appId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilder.cs new file mode 100644 index 0000000..6df2f3b --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilder.cs @@ -0,0 +1,97 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// A builder for constructing requests to query records from an app. + /// + /// + public class QueryRecordsByAppPagedRequestBuilder : IQueryRecordsByAppPagedRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public string Filter { get; private set; } + public int PageNumber { get; private set; } = 1; + public int PageSize { get; private set; } = 50; + public IEnumerable FieldIds { get; private set; } = Enumerable.Empty(); + public DataFormat Format { get; private set; } = DataFormat.Raw; + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + /// The unique identifier of the app from which to retrieve records. + /// The filter to apply to the request. + internal QueryRecordsByAppPagedRequestBuilder(IOnspringClient client, int appId, string filter) + { + _client = client; + AppId = appId; + Filter = filter; + } + + public IQueryRecordsByAppPagedRequestBuilder ForPage(int pageNumber) + { + PageNumber = pageNumber; + return this; + } + + public IQueryRecordsByAppPagedRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public IQueryRecordsByAppPagedRequestBuilder WithFieldIds(IEnumerable fieldIds) + { + FieldIds = fieldIds; + return this; + } + + public IQueryRecordsByAppPagedRequestBuilder WithFormat(DataFormat dataFormat) + { + Format = dataFormat; + return this; + } + + public async Task> SendAsync() + { + return await _client.QueryRecordsAsync( + new QueryRecordsRequest() + { + Filter = Filter, + FieldIds = FieldIds.ToList(), + DataFormat = Format, + }, + new PagingRequest() + { + PageNumber = PageNumber, + PageSize = PageSize + } + ); + } + + public async Task> SendAsync(Action options) + { + var opts = new QueryRecordsByAppPagedRequestBuilderOptions(); + options.Invoke(opts); + return await _client.QueryRecordsAsync( + new QueryRecordsRequest() + { + Filter = Filter, + FieldIds = opts.FieldIds.ToList(), + DataFormat = opts.Format, + }, + new PagingRequest() + { + PageNumber = opts.PageNumber, + PageSize = opts.PageSize + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilderOptions.cs new file mode 100644 index 0000000..aaebade --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Get/QueryRecordsByAppPagedRequestBuilderOptions.cs @@ -0,0 +1,32 @@ +using Onspring.API.SDK.Enums; +using System.Collections.Generic; +using System.Linq; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents options for building paged requests to query records by application. + /// + public class QueryRecordsByAppPagedRequestBuilderOptions + { + /// + /// Gets or sets the page number for the paged request. Default is 1. + /// + public int PageNumber { get; set; } = 1; + + /// + /// Gets or sets the page size for the paged request. Default is 50. + /// + public int PageSize { get; set; } = 50; + + /// + /// Gets or sets the field IDs to include in the query. Default is an empty collection. + /// + public IEnumerable FieldIds { get; set; } = Enumerable.Empty(); + + /// + /// Gets or sets the data format for the query results. Default is . + /// + public DataFormat Format { get; set; } = DataFormat.Raw; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Records/Save/SaveRecordRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Records/Save/SaveRecordRequestBuilder.cs new file mode 100644 index 0000000..3cf3b3b --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Records/Save/SaveRecordRequestBuilder.cs @@ -0,0 +1,63 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to save a record. + /// + /// + public class SaveRecordRequestBuilder : + ISaveRecordRequestBuilder, + ISaveRecordInAppRequestBuilder, + ISaveRecordByIdRequestBuilder, + ISaveRecordByIdWithValuesRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int? RecordId { get; private set; } + + /// + /// Creates a new instance of the class. + /// + /// The used to send the request. + internal SaveRecordRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IEnumerable Values { get; private set; } + + public ISaveRecordInAppRequestBuilder InApp(int appId) + { + AppId = appId; + return this; + } + + public ISaveRecordByIdRequestBuilder WithId(int? recordId) + { + RecordId = recordId; + return this; + } + + public ISaveRecordByIdWithValuesRequestBuilder WithValues(IEnumerable values) + { + Values = values; + return this; + } + + public async Task> SendAsync() + { + return await _client.SaveRecordAsync( + new ResultRecord + { + AppId = AppId, + RecordId = RecordId ?? 0, + FieldData = Values.ToList(), + } + ); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesByAppRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesByAppRequestBuilder.cs new file mode 100644 index 0000000..7ee9c26 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesByAppRequestBuilder.cs @@ -0,0 +1,48 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Collections.Generic; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for requests to get all pages of reports. + /// + /// + public class GetAllReportsPagesByAppRequestBuilder : IGetAllReportsPagesByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; } + public int PageSize { get; private set; } = 50; + + internal GetAllReportsPagesByAppRequestBuilder(IOnspringClient client, int appId) + { + _client = client; + AppId = appId; + } + + public IGetAllReportsPagesByAppRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public async IAsyncEnumerable> SendAsync() + { + await foreach (var response in _client.GetAllReportsForAppAsync(AppId, PageSize)) + { + yield return response; + } + } + + public async IAsyncEnumerable> SendAsync(Action options) + { + var opts = new GetAllReportsPagesByAppRequestBuilderOptions(); + options.Invoke(opts); + + await foreach (var response in _client.GetAllReportsForAppAsync(AppId, opts.PageSize)) + { + yield return response; + } + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesByAppRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesByAppRequestBuilderOptions.cs new file mode 100644 index 0000000..2ebdffe --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesByAppRequestBuilderOptions.cs @@ -0,0 +1,13 @@ +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents options for building requests to get all pages of reports for a specific app. + /// + public class GetAllReportsPagesByAppRequestBuilderOptions + { + /// + /// Gets or sets the page size for the request. Default is 50. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesRequestBuilder.cs new file mode 100644 index 0000000..24f8e99 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetAllReportsPagesRequestBuilder.cs @@ -0,0 +1,23 @@ +using Onspring.API.SDK.Interfaces.Fluent; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for requests to get all pages of reports. + /// + /// + public class GetAllReportsPagesRequestBuilder : IGetAllReportsPagesRequestBuilder + { + private readonly IOnspringClient _client; + + internal GetAllReportsPagesRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetAllReportsPagesByAppRequestBuilder FromApp(int appId) + { + return new GetAllReportsPagesByAppRequestBuilder(_client, appId); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetReportBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetReportBuilderOptions.cs new file mode 100644 index 0000000..dd97de1 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetReportBuilderOptions.cs @@ -0,0 +1,20 @@ +using Onspring.API.SDK.Enums; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents options for a request to get a report. + /// + public class GetReportBuilderOptions + { + /// + /// Gets or sets the format of the report data. + /// + public DataFormat Format { get; set; } = DataFormat.Raw; + + /// + /// Gets or sets the type of report data to return. + /// + public ReportDataType DataType { get; set; } = ReportDataType.ReportData; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetReportRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetReportRequestBuilder.cs new file mode 100644 index 0000000..00f4202 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetReportRequestBuilder.cs @@ -0,0 +1,58 @@ +using Onspring.API.SDK.Enums; +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to get a report. + /// + /// + public class GetReportRequestBuilder : IGetReportRequestBuilder, IGetReportDataRequestBuilder + { + private readonly IOnspringClient _client; + public int ReportId { get; private set; } + public DataFormat Format { get; private set; } + public ReportDataType DataType { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal GetReportRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetReportDataRequestBuilder FromReport(int reportId) + { + ReportId = reportId; + return this; + } + + public IGetReportDataRequestBuilder WithDataType(ReportDataType dataType) + { + DataType = dataType; + return this; + } + + public IGetReportDataRequestBuilder WithFormat(DataFormat format) + { + Format = format; + return this; + } + + public async Task> SendAsync() + { + return await _client.GetReportAsync(ReportId, DataType, Format); + } + + public async Task> SendAsync(Action options) + { + var opts = new GetReportBuilderOptions(); + options.Invoke(opts); + return await _client.GetReportAsync(ReportId, opts.DataType, opts.Format); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetReportsRequestBuilder.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetReportsRequestBuilder.cs new file mode 100644 index 0000000..cebde05 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetReportsRequestBuilder.cs @@ -0,0 +1,57 @@ +using Onspring.API.SDK.Interfaces.Fluent; +using System; +using System.Threading.Tasks; + +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents a builder for constructing requests to get reports. + /// + /// + public class GetReportsRequestBuilder : IGetReportsRequestBuilder, IGetReportsByAppRequestBuilder + { + private readonly IOnspringClient _client; + public int AppId { get; private set; } + public int PageNumber { get; private set; } + public int PageSize { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The to use for the request. + internal GetReportsRequestBuilder(IOnspringClient client) + { + _client = client; + } + + public IGetReportsByAppRequestBuilder FromApp(int appId) + { + AppId = appId; + return this; + } + + public IGetReportsByAppRequestBuilder ForPage(int pageNumber) + { + PageNumber = pageNumber; + return this; + } + + public IGetReportsByAppRequestBuilder WithPageSize(int pageSize) + { + PageSize = pageSize; + return this; + } + + public async Task> SendAsync() + { + return await _client.GetReportsForAppAsync(AppId, new PagingRequest(PageNumber, PageSize)); + } + + public async Task> SendAsync(Action options) + { + var opts = new GetReportsRequestBuilderOptions(); + options.Invoke(opts); + return await _client.GetReportsForAppAsync(AppId, new PagingRequest(opts.PageNumber, opts.PageSize)); + } + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/Fluent/Reports/GetReportsRequestBuilderOptions.cs b/Onspring.API.SDK/Models/Fluent/Reports/GetReportsRequestBuilderOptions.cs new file mode 100644 index 0000000..93496b2 --- /dev/null +++ b/Onspring.API.SDK/Models/Fluent/Reports/GetReportsRequestBuilderOptions.cs @@ -0,0 +1,18 @@ +namespace Onspring.API.SDK.Models.Fluent +{ + /// + /// Represents the options for a request to get reports. + /// + public class GetReportsRequestBuilderOptions + { + /// + /// Gets or sets the page number to retrieve. + /// + public int PageNumber { get; set; } = 1; + + /// + /// Gets or sets the page size to retrieve. + /// + public int PageSize { get; set; } = 50; + } +} \ No newline at end of file diff --git a/Onspring.API.SDK/Models/PagedResponse.cs b/Onspring.API.SDK/Models/PagedResponse.cs index 709d9b6..460c715 100644 --- a/Onspring.API.SDK/Models/PagedResponse.cs +++ b/Onspring.API.SDK/Models/PagedResponse.cs @@ -13,18 +13,13 @@ namespace Onspring.API.SDK.Models /// /// Represents a response to request that has paged items. /// - public class PagedResponse + public class PagedResponse { /// /// Gets the page number of the response. /// public int PageNumber { get; set; } - /// - /// Gets the size of the page. - /// - public int PageSize => Items?.Count ?? 0; - /// /// Gets the total amount of pages. /// @@ -34,10 +29,19 @@ public class PagedResponse /// Gets the total amount of records. /// public int TotalRecords { get; set; } + } + /// + public class PagedResponse : PagedResponse + { /// /// Gets the collection of items in the response. /// public List Items { get; set; } = new List(); + + /// + /// Gets the size of the page. + /// + public int PageSize => Items?.Count ?? 0; } } diff --git a/Onspring.API.SDK/Models/RecordFieldValue.cs b/Onspring.API.SDK/Models/RecordFieldValue.cs index 011a512..4e74bda 100644 --- a/Onspring.API.SDK/Models/RecordFieldValue.cs +++ b/Onspring.API.SDK/Models/RecordFieldValue.cs @@ -28,7 +28,7 @@ public class RecordFieldValue public int FieldId { get; set; } } - /// + /// public class RecordFieldValue : RecordFieldValue { /// diff --git a/Onspring.API.SDK/Onspring.API.SDK.csproj b/Onspring.API.SDK/Onspring.API.SDK.csproj index 426f4d2..bbe0a00 100644 --- a/Onspring.API.SDK/Onspring.API.SDK.csproj +++ b/Onspring.API.SDK/Onspring.API.SDK.csproj @@ -1,6 +1,7 @@ - + netstandard2.0;netstandard2.1 + 8.0 Onspring.API.SDK Onspring Technologies Onspring.API.SDK @@ -14,9 +15,17 @@ true Onspring; Onspring Technologies; Onspring SDK; Onspring API + + + + <_Parameter1>$(AssemblyName).Tests + + + + - + diff --git a/Onspring.API.SDK/OnspringClient.cs b/Onspring.API.SDK/OnspringClient.cs index e9c3a8f..ac61947 100644 --- a/Onspring.API.SDK/OnspringClient.cs +++ b/Onspring.API.SDK/OnspringClient.cs @@ -2,7 +2,9 @@ using Onspring.API.SDK.Extensions; using Onspring.API.SDK.Helpers; using Onspring.API.SDK.Http; +using Onspring.API.SDK.Interfaces.Fluent; using Onspring.API.SDK.Models; +using Onspring.API.SDK.Models.Fluent; using Onspring.API.SDK.Validation; using System; using System.Collections.Generic; @@ -71,6 +73,14 @@ public OnspringClient(OnspringClientConfiguration clientConfig) HttpClient = HttpClientFactory.GetHttpClient(clientConfig.BaseAddress); } + // ------------------------------------ Fluent Interface ------------------------------------ + + /// + public IOnspringRequestBuilder CreateRequest() + { + return new OnspringRequestBuilder(this); + } + // ------------------------------------ Diagnostic ------------------------------------ #region Diagnostic @@ -93,6 +103,15 @@ public async Task CanConnectAsync() #region Apps + /// + public async IAsyncEnumerable> GetAllAppsAsync(int pageSize = 50) + { + await foreach (var response in GetAllPagesAsync(page => GetAppsAsync(new PagingRequest(page, pageSize)))) + { + yield return response; + } + } + /// /// Gets all accessible apps. /// @@ -135,6 +154,15 @@ public async Task> GetAppsAsync(IEnumerable ap #region Fields + /// + public async IAsyncEnumerable> GetAllFieldsForAppAsync(int appId, int pageSize = 50) + { + await foreach (var response in GetAllPagesAsync(page => GetFieldsForAppAsync(appId, new PagingRequest(page, pageSize)))) + { + yield return response; + } + } + /// /// Gets the requested field. Returns null if field could not be found. /// @@ -333,6 +361,30 @@ public async Task> GetRecordsForAppAsync(Ge return apiResponse; } + /// + public async IAsyncEnumerable> GetAllRecordsForAppAsync(GetRecordsByAppRequest request) + { + var callback = new Func>>(page => + { + request.PagingRequest = new PagingRequest(page, request.PagingRequest?.PageSize ?? 50); + return GetRecordsForAppAsync(request); + }); + + await foreach (var response in GetAllPagesAsync(callback)) + { + yield return response; + } + } + + /// + public async IAsyncEnumerable> GetAllRecordsByQueryAsync(QueryRecordsRequest request, int pageSize = 50) + { + await foreach (var response in GetAllPagesAsync(page => QueryRecordsAsync(request, new PagingRequest(page, pageSize)))) + { + yield return response; + } + } + /// /// Gets a record by its identifier. /// @@ -451,10 +503,43 @@ public async Task> GetReportsForAppAsync(i return getReportsResponse; } + /// + public async IAsyncEnumerable> GetAllReportsForAppAsync(int appId, int pageSize = 50) + { + await foreach (var response in GetAllPagesAsync(page => GetReportsForAppAsync(appId, new PagingRequest(page, pageSize)))) + { + yield return response; + } + } + #endregion // ------------------------------------ Client internals ------------------------------------ + /// + /// Gets all pages of a paged response. + /// + /// Where T is a paged response. + /// The callback to get a page of the response. + /// An async enumerable of the paged response. + private async IAsyncEnumerable> GetAllPagesAsync(Func>> callback) where T : PagedResponse + { + var initialResponse = await callback(1); + + yield return initialResponse; + + var totalPages = initialResponse.Value.TotalPages; + var nextPage = initialResponse.Value.PageNumber + 1; + + while (nextPage <= totalPages) + { + var response = await callback(nextPage); + nextPage++; + + yield return response; + } + } + /// /// Performs an HTTP DELETE request to the and adds an API Key header. /// diff --git a/README.md b/README.md index 17885d7..99a209f 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,16 @@ Install the SDK using Nuget ## API Key -In order to successfully interact with the Onspring API, you must use an API key. API keys may be obtained by an Onspring user with permissions to read API Keys for your instance, using the following instructions: +In order to successfully interact with the Onspring API, you must use an API key. API keys may be obtained by an Onspring user with permissions to read API Keys for your instance, using the following instructions: -1. Within Onspring, navigate to Administration | Security | API Keys. -2. On the list page, add a new API Key (requires Create permissions) or click an existing API Key to view its details. -3. On the details page for an API Key, expand the **Developer Information** section. Copy the **X-ApiKey Header** value from this section. +1. Within Onspring, navigate to Administration | Security | API Keys. +2. On the list page, add a new API Key (requires Create permissions) or click an existing API Key to view its details. +3. On the details page for an API Key, expand the **Developer Information** section. Copy the **X-ApiKey Header** value from this section. -#### Important +### Important -- An API Key must have a **Status** of *Enabled* (available on the details page) in order to be used. -- Each API Key has an associated **Role** that controls the permissions for requests made using that API Key. An Onspring administrator may configure those permissions as they would any other Role in Onspring. If the API Key does not have sufficient permissions to perform the requested action, an error will be returned. +- An API Key must have a **Status** of _Enabled_ (available on the details page) in order to be used. +- Each API Key has an associated **Role** that controls the permissions for requests made using that API Key. An Onspring administrator may configure those permissions as they would any other Role in Onspring. If the API Key does not have sufficient permissions to perform the requested action, an error will be returned. ## Sample Projects @@ -28,7 +28,7 @@ In order to successfully interact with the Onspring API, you must use an API key ## Start Coding -The most common way to use the SDK is to create an `OnspringClient` instance and call its methods. Its constructor requires two parameters: +The most common way to use the SDK is to create an `OnspringClient` instance and call its methods. Its constructor requires two parameters: - `baseUrl` - currently this should always be: **`https://api.onspring.com/`** - `apiKey` - the value obtained by following the steps in the **API Key** section @@ -59,7 +59,6 @@ var onspringClient = new OnspringClient(apiKey, myHttpClient); Although we strongly recommend using async for accessing the API, in the case that the calling code is synchronous, we offer a simple helper class `Onspring.API.SDK.Helpers.AsyncHelper`. This class allows C# to execute an asynchronous function in a synchronous context without deadlocking. - Example assumes that you've have an `OnspringClient` (or `IOnspringClient`) instance prior to execution. ```C# @@ -68,10 +67,9 @@ using Onspring.API.SDK.Helpers; bool canConnect = AsyncHelper.RunTask(() => onspringClient.CanConnectAsync()); ``` - ## Full API Documentation -When using the SDK, you do not need to be as concerned with the details covered in the full [Onspring API documentation](https://software.onspring.com/hubfs/Training/Admin%20Guide%20-%20v2%20API.pdf). However, you may wish to refer to it when determining which values to pass as parameters to some of the `OnspringClient` methods. +When using the SDK, you do not need to be as concerned with the details covered in the full [Onspring API documentation](https://software.onspring.com/hubfs/Training/Admin%20Guide%20-%20v2%20API.pdf). However, you may wish to refer to it when determining which values to pass as parameters to some of the `OnspringClient` methods. Each method on the `OnspringClient` aside from `CanConnectAsync` returns a wrapped response, allowing clients to decide how a response should be handled. This wrapper is the `ApiResponse` class and includes generic types to encompass the response body, if any. In the examples below, we're omitting the validation/error handling around that, however we recommend that each client adds resilience and error handling for potential unsuccessful responses. Please refer to the API documentation/swagger page to determine the possible responses. @@ -82,12 +80,30 @@ The `OnspringClient` is thread-safe and can be used as a singleton or transient. ## Upgrading SDK Already using a previous version of the SDK? Check out our migration guides below. + - [2.x to 3.0](./docs/migrations/2-to-30.md) ## Example Code The examples that follow assume you have created an `OnspringClient` as described in the **Start Coding** section. +### Fluent Interface + +The `OnspringClient` provides a method named `CreateRequest` which returns an instance that implements the `IOnspringRequestBuilder` interface. This builder exposes the same methods that are exposed by the `IOnspringClient` interface, but through a fluent API. This interface is intended to provide a more readable way to build a request and provide better discoverability of the ways in which the SDK can be used to make requests. + +```C# +var apiResponse = await _apiClient + .CreateRequest() + .ToGetRecords() + .FromApp(_appIdWithRecords) + .WithId(1) + .WithFieldIds(new[] { 1, 2, 3 }) + .WithFormat(DataFormat.Formatted) + .SendAsync(); +``` + +When using this interface you should find that each successful chained method walks you down the proper path to make a successful request as the ability to send the request is not exposed until you've provided all required information for making the request. + ### Verify connectivity ```C# @@ -98,7 +114,8 @@ bool canConnect = await onspringClient.CanConnectAsync(); Returns a paged collection of apps/surveys, which can be paged through using the `Onspring.API.SDK.Models.PagingRequest`. -##### Basic +#### Basic + ```C# var apps = await onspringClient.GetAppsAsync(); foreach (App app in apps) @@ -107,7 +124,8 @@ foreach (App app in apps) } ``` -##### Paged +#### Paged + Async and synchronous methods allow use of `Onspring.API.SDK.Models.PagingRequest`. ```C# @@ -360,4 +378,46 @@ using (var result = getFileResponse.Value) result.Stream.CopyTo(fileStream); } } -``` \ No newline at end of file +``` + +### Pagination Done For You + +There are several methods on the `IOnspringClient` that return a paged collection of items. These include: + +- `GetAppsAsync` +- `GetFieldsForAppAsync` +- `GetReportsForAppAsync` +- `QueryRecordsAsync` +- `GetRecordsForAppAsync` + +Using these methods allows the caller to page through the results, but requires the caller to handle the pagination process themselves. This can feel like a chore, given that in the vast majority of cases the caller will want to iterate through all the pages. In order to improve developer experience, the SDK provides a set of wrapper methods that handle the pagination process for you by leveraging the `IAsyncEnumerable` interface. These methods accept all the same parameters as the methods they wrap, but when it comes to paging they only allow you to control the size of each page and they internally can moving from the first page to the last for you. These methods include: + +- `GetAllAppsAsync` +- `GetAllFieldsForAppAsync` +- `GetAllReportsForAppAsync` +- `GetAllRecordsByQueryAsync` +- `GetAllRecordsForAppAsync` + +These methods return an `IAsyncEnumerable` that allows the caller to iterate through all pages. The caller can use the `await foreach` construct to iterate through the items. The value of each iteration is an `ApiResponse` where `T` is the response that was received for that page. The following example demonstrates how to use these methods: + +```C# +var appsResponses = onspringClient.GetAllAppsAsync(); + +await foreach (var response in appsResponses) +{ + if (response.IsSuccessful) + { + foreach (var app in response.Value.Items) + { + Console.WriteLine($"{app.Id}, {app.Name}"); + } + } + else + { + Console.WriteLine($"Error: {response.Message}"); + } +} +``` + +> [!NOTE] +> This same pagination API is exposed for the `IOnspringRequestBuilder` interface through the `ToGetAllPages` method. diff --git a/docs/migrations/2-to-30.md b/docs/migrations/2-to-30.md index 574c71b..1f1effb 100644 --- a/docs/migrations/2-to-30.md +++ b/docs/migrations/2-to-30.md @@ -7,44 +7,44 @@ This SDK upgrade will allow the SDK to communicate with the V2 Onspring Client A ## What's New? - Client changes: - - `HttpHelper` has been replaced with `OnspringClient` and moved to the root namespace: `Onspring.API.SDK`. - - Added ability to supply HttpClient instance. - - Added ability to customize serialization of JSON. - - Added interface `IOnspringClient` to allow for easier dependency injection/mocking. - - Errors are no longer raised on an unsuccessful API response. - - Added ability to created/update/delete list items. + - `HttpHelper` has been replaced with `OnspringClient` and moved to the root namespace: `Onspring.API.SDK`. + - Added ability to supply HttpClient instance. + - Added ability to customize serialization of JSON. + - Added interface `IOnspringClient` to allow for easier dependency injection/mocking. + - Errors are no longer raised on an unsuccessful API response. + - Added ability to created/update/delete list items. - Request changes: - - The majority of request objects have been renamed/modified/restructured. - - Paging request added to allow for paged requests. + - The majority of request objects have been renamed/modified/restructured. + - Paging request added to allow for paged requests. - Response changes: - - All client responses (other than CanConnect/Async) are wrapped in an `ApiResponse` wrapper class. - - This allows clients to determine how they want to handle any API response, as well as including a response message, if possible. - - Paged responses added for endpoints that allow retrieval of data. - - Methods that get data by their identifiers do not include paging, since a specific set of data is requested. - - Record result values have been consolidated into the `Onspring.API.SDK.Models` namespace. + - All client responses (other than CanConnect/Async) are wrapped in an `ApiResponse` wrapper class. + - This allows clients to determine how they want to handle any API response, as well as including a response message, if possible. + - Paged responses added for endpoints that allow retrieval of data. + - Methods that get data by their identifiers do not include paging, since a specific set of data is requested. + - Record result values have been consolidated into the `Onspring.API.SDK.Models` namespace. - New features: - - Apps - - Get individual app info. - - Get a batch of apps. - - Paging around getting all apps. - - Fields - - Get fields by their identifier. - - Get a batch of fields. - - Paging around getting all fields for app. - - Files - - Get a file's info without actually getting the file. - - Delete a file. - - Lists - - Add/Update list item. - - Remove list item. - - Records - - Create and update record consolidated into `SaveRecordAsync`. - - Separate method for querying records, with paging. - - Delete batch of records. - - Get batch of records. - - Paging around getting all records for app. - - Reports - - Paging around getting all reports for app. + - Apps + - Get individual app info. + - Get a batch of apps. + - Paging around getting all apps. + - Fields + - Get fields by their identifier. + - Get a batch of fields. + - Paging around getting all fields for app. + - Files + - Get a file's info without actually getting the file. + - Delete a file. + - Lists + - Add/Update list item. + - Remove list item. + - Records + - Create and update record consolidated into `SaveRecordAsync`. + - Separate method for querying records, with paging. + - Delete batch of records. + - Get batch of records. + - Paging around getting all records for app. + - Reports + - Paging around getting all reports for app. - Support for netstandard2.1 - Removed all synchronous API calls. @@ -55,6 +55,7 @@ Version 3.x of the SDK will not work with the V1 API, due to request/response ob ## API address Change With the V2 Client API, we've approached versioning using header values, which means we're going to need to change the legacy path, as it includes version as part of the path. Specifically, we just need to remove the `v1` portion of the original URL. + - `https://api.onspring.com/v1` should be changed to `https://api.onspring.com/` ## Breaking changes @@ -64,11 +65,13 @@ Due to the amount of breaking changes within the SDK itself, this section will b ### App breaking changes `GetAppsAsync` response object has changed from `IReadOnlyList` to `ApiResponse` + - Additionally, we've added an optional parameter to the request for paging. ### Field breaking changes `GetAppFieldsAsync` has been replaced with `GetFieldsForAppAsync`. + - Response type changed from `IReadOnlyList` to `ApiResponse` - Additionally, the request/response has changed to allow for paging. @@ -84,6 +87,7 @@ var fields = getFieldsResponse.Value.Items; ``` `GetAppFieldAsync` has been replaced with `GetFieldAsync` + - Response type changed from `Field` to `ApiResponse` ```C# @@ -100,6 +104,7 @@ var field = getFieldsResponse.Value; ### File breaking changes `GetFileFromRecordAsync` has been replaced with `GetFileAsync`. + - AppId is no longer needed in order to get a file. - Response type changed from `FileResult` to `ApiResponse`. @@ -118,6 +123,7 @@ var fileResult = getFileResponse.Value; ``` `AddFileToRecordAsync` has been replaced with `SaveFileAsync`. + - Overload to load from file has been removed. - AppId is no longer needed in order to save a file. - Response type changed from `FileResult` to `ApiResponse`. @@ -146,6 +152,7 @@ var newFileId = saveResponse.Value.Id; ### Record breaking changes `CreateAppRecordAsync` and `UpdateAppRecordAsync` have been replaced with `SaveRecordAsync`. + - Response type changed from `AddEditResult` to `ApiResponse` ```C# @@ -162,9 +169,10 @@ var saveRequest = new SaveRecordRequest // ... }; var saveResponse = await onspringClient.SaveRecordAsync(saveRequest); -```` +``` `GetAppRecordsAsync` has been replaced with `GetRecordsForAppAsync`. + - Response type changed from `IReadOnlyList` to `ApiResponse`. - Additionally, the request/response has changed to allow for paging. @@ -190,6 +198,7 @@ var newFileId = saveResponse.Value.Id; ``` `GetAppRecordAsync` has been replaced with `GetRecordAsync`. + - Request parameters changed to use an object instead of multiple parameters. - Response type changed from `ResultRecord` to `ApiResponse`. @@ -207,6 +216,7 @@ var record = getResponse.Value; ``` `DeleteAppRecordAsync` has been replaced with `DeleteRecordAsync`. + - Response type changed from `DeleteResult` to `ApiResponse`. ```C# @@ -227,8 +237,9 @@ Lastly, the `As` methods for record field values no longer work as properties. I ### Report breaking changes `GetAppReportsAsync` has been replaced with `GetReportsForAppAsync`. + - Response changed from `IReadOnlyList` to `ApiResponse` -- Additionally, the request/response has changed to allow for paging. +- Additionally, the request/response has changed to allow for paging. ```C# const int appId = 1; @@ -242,6 +253,7 @@ var reports = getFieldsResponse.Value.Items; ``` `GetReportDataAsync` has been replaced with `GetReportAsync`. + - Response type changed from `ReportData` to `ApiResponse` ```C# @@ -255,4 +267,4 @@ var reportData = await httpHelper.GetReportDataAsync(reportId, dataType, dataFor // New var getReportResponse = await onspringClient.GetReportAsync(reportId, dataType, dataFormat); var reportData = getReportResponse.Value; -``` \ No newline at end of file +```