From 9fbea653f2b1c886158164ba92f194b2afeeb67f Mon Sep 17 00:00:00 2001 From: Max Inno <40697586+innomaxx@users.noreply.github.com> Date: Fri, 17 Jan 2025 12:58:15 +0200 Subject: [PATCH] feat(string-translations): add endpoint "Remove String Approvals" (#291) --- .../IStringTranslationsApiExecutor.cs | 4 +- .../StringTranslationsApiExecutor.cs | 29 ++++++- .../StringTranslations/ApprovalsApiTests.cs | 69 ++++++++++++++++ .../StringTranslationsApiTests.cs | 81 ++++++++++++------- 4 files changed, 150 insertions(+), 33 deletions(-) create mode 100644 tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/ApprovalsApiTests.cs diff --git a/src/Crowdin.Api/StringTranslations/IStringTranslationsApiExecutor.cs b/src/Crowdin.Api/StringTranslations/IStringTranslationsApiExecutor.cs index ecdacec8..d154cefe 100644 --- a/src/Crowdin.Api/StringTranslations/IStringTranslationsApiExecutor.cs +++ b/src/Crowdin.Api/StringTranslations/IStringTranslationsApiExecutor.cs @@ -54,6 +54,8 @@ Task> ListTranslationApprovals( Task RemoveApproval(int projectId, int approvalId); + Task RemoveStringApprovals(int projectId, int stringId); + #endregion #region Translations @@ -75,7 +77,7 @@ Task> ListStringTranslations( Task AddTranslation(int projectId, AddTranslationRequest request); - Task DeleteStringTranslations(int projectId, int stringId, string languageId); + Task DeleteStringTranslations(int projectId, int stringId, string? languageId = null); Task GetTranslation(int projectId, int translationId, bool? denormalizePlaceholders = null); diff --git a/src/Crowdin.Api/StringTranslations/StringTranslationsApiExecutor.cs b/src/Crowdin.Api/StringTranslations/StringTranslationsApiExecutor.cs index f2205841..7b4d2878 100644 --- a/src/Crowdin.Api/StringTranslations/StringTranslationsApiExecutor.cs +++ b/src/Crowdin.Api/StringTranslations/StringTranslationsApiExecutor.cs @@ -107,6 +107,25 @@ public async Task RemoveApproval(int projectId, int approvalId) Utils.ThrowIfStatusNot204(statusCode, $"Approval {approvalId} removal failed"); } + /// + /// Remove string approvals. Documentation: + /// Crowdin API + /// Crowdin Enterprise API + /// + [PublicAPI] + public async Task RemoveStringApprovals(int projectId, int stringId) + { + string url = FormUrl_Approvals(projectId); + + var queryParams = new Dictionary(1) + { + ["stringId"] = stringId.ToString() + }; + + HttpStatusCode statusCode = await _apiClient.SendDeleteRequest(url, queryParams); + Utils.ThrowIfStatusNot204(statusCode, $"Approvals for string {stringId} removal failed"); + } + #region Helper methods private static string FormUrl_Approvals(int projectId) @@ -231,16 +250,20 @@ public async Task AddTranslation(int projectId, AddTranslatio /// Crowdin Enterprise API /// [PublicAPI] - public async Task DeleteStringTranslations(int projectId, int stringId, string languageId) + public async Task DeleteStringTranslations(int projectId, int stringId, string? languageId = null) { string url = FormUrl_Translations(projectId); var queryParams = new Dictionary { - { "stringId", stringId.ToString() }, - { "languageId", languageId } + ["stringId"] = stringId.ToString(), }; + if (!string.IsNullOrWhiteSpace(languageId)) + { + queryParams.Add("languageId", languageId!); + } + HttpStatusCode statusCode = await _apiClient.SendDeleteRequest(url, queryParams); Utils.ThrowIfStatusNot204(statusCode, "String translation removal failed"); } diff --git a/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/ApprovalsApiTests.cs b/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/ApprovalsApiTests.cs new file mode 100644 index 00000000..5eff5e37 --- /dev/null +++ b/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/ApprovalsApiTests.cs @@ -0,0 +1,69 @@ + +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; + +using Moq; +using Newtonsoft.Json.Linq; +using Xunit; + +using Crowdin.Api.Core; +using Crowdin.Api.StringTranslations; + +namespace Crowdin.Api.UnitTesting.Tests.StringTranslations +{ + public class ApprovalsApiTests + { + [Fact] + public async Task ListTranslationApprovals() + { + const int ProjectId = 1; + var url = $"/projects/{ProjectId}/approvals"; + + Mock mockClient = TestUtils.CreateMockClientWithDefaultParser(); + + IDictionary queryParams = TestUtils.CreateQueryParamsFromPaging(); + + mockClient + .Setup(client => client.SendGetRequest(url, queryParams)) + .ReturnsAsync(new CrowdinApiResult + { + StatusCode = HttpStatusCode.OK, + JsonObject = JObject.Parse(Resources.StringTranslations.ListTranslationsApproval_Response) + }); + + var executor = new StringTranslationsApiExecutor(mockClient.Object); + ResponseList response = await executor.ListTranslationApprovals(ProjectId); + + Assert.NotNull(response); + + TranslationApproval data = response.Data[1]; + Assert.Equal(200695, data.TranslationId); + Assert.Equal(1234, data.StringId); + Assert.IsType(data.User); + } + + [Fact] + public async Task RemoveStringApprovals() + { + const int ProjectId = 1; + const int StringId = 2; + + Mock mockClient = TestUtils.CreateMockClientWithDefaultParser(); + + var url = $"/projects/{ProjectId}/approvals"; + + var queryParams = new Dictionary + { + ["stringId"] = StringId.ToString() + }; + + mockClient + .Setup(client => client.SendDeleteRequest(url, queryParams)) + .ReturnsAsync(HttpStatusCode.NoContent); + + var executor = new StringTranslationsApiExecutor(mockClient.Object); + await executor.RemoveStringApprovals(ProjectId, StringId); + } + } +} \ No newline at end of file diff --git a/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/StringTranslationsApiTests.cs b/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/StringTranslationsApiTests.cs index 8d7473ee..a68f65a5 100644 --- a/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/StringTranslationsApiTests.cs +++ b/tests/Crowdin.Api.UnitTesting/Tests/StringTranslations/StringTranslationsApiTests.cs @@ -3,13 +3,15 @@ using System.Linq; using System.Net; using System.Threading.Tasks; -using Crowdin.Api.Core; -using Crowdin.Api.StringTranslations; + using Moq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Xunit; +using Crowdin.Api.Core; +using Crowdin.Api.StringTranslations; + namespace Crowdin.Api.UnitTesting.Tests.StringTranslations { public class StringTranslationsApiTests @@ -108,6 +110,54 @@ public async Task RestoreTranslation() Assert.Equal(PluralCategoryName.Few, response.PluralCategoryName); } + [Fact] + public async Task DeleteStringTranslations() + { + const int ProjectId = 1; + const int StringId = 2; + + Mock mockClient = TestUtils.CreateMockClientWithDefaultParser(); + + var url = $"/projects/{ProjectId}/translations"; + + var queryParams = new Dictionary + { + ["stringId"] = StringId.ToString() + }; + + mockClient + .Setup(client => client.SendDeleteRequest(url, queryParams)) + .ReturnsAsync(HttpStatusCode.NoContent); + + var executor = new StringTranslationsApiExecutor(mockClient.Object); + await executor.DeleteStringTranslations(ProjectId, StringId); + } + + [Fact] + public async Task DeleteStringTranslations_WithLanguageId() + { + const int ProjectId = 1; + const int StringId = 2; + const string LanguageId = "uk"; + + Mock mockClient = TestUtils.CreateMockClientWithDefaultParser(); + + var url = $"/projects/{ProjectId}/translations"; + + var queryParams = new Dictionary + { + ["stringId"] = StringId.ToString(), + ["languageId"] = LanguageId + }; + + mockClient + .Setup(client => client.SendDeleteRequest(url, queryParams)) + .ReturnsAsync(HttpStatusCode.NoContent); + + var executor = new StringTranslationsApiExecutor(mockClient.Object); + await executor.DeleteStringTranslations(ProjectId, StringId, LanguageId); + } + [Fact] public async Task TranslationAlignment() { @@ -155,33 +205,6 @@ public async Task TranslationAlignment() Assert.Equal(2, alignment.Probability); } - [Fact] - public async Task ListTranslationApprovals() - { - const int projectId = 1; - var url = $"/projects/{projectId}/approvals"; - - Mock mockClient = TestUtils.CreateMockClientWithDefaultParser(); - - var queryParams = TestUtils.CreateQueryParamsFromPaging(); - - mockClient - .Setup(client => client.SendGetRequest(url, queryParams)) - .ReturnsAsync(new CrowdinApiResult - { - StatusCode = HttpStatusCode.OK, - JsonObject = JObject.Parse(Resources.StringTranslations.ListTranslationsApproval_Response) - }); - - var executor = new StringTranslationsApiExecutor(mockClient.Object); - ResponseList response = await executor.ListTranslationApprovals(projectId); - Assert.NotNull(response); - var data = response.Data[1]; - Assert.Equal(200695, data.TranslationId); - Assert.Equal(1234, data.StringId); - Assert.IsType(data.User); - } - [Fact] public async Task ListTranslationVotes() {