diff --git a/src/Piwigo.Client.Tests/Piwigo.Client.Tests.csproj b/src/Piwigo.Client.Tests/Piwigo.Client.Tests.csproj index 50e7262..389510b 100644 --- a/src/Piwigo.Client.Tests/Piwigo.Client.Tests.csproj +++ b/src/Piwigo.Client.Tests/Piwigo.Client.Tests.csproj @@ -41,6 +41,21 @@ ImageApiTests.cs + + Always + + + TagApiTests.cs + + + Always + + + TagApiTests.cs + + + TagApiTests.cs + diff --git a/src/Piwigo.Client.Tests/TagApi.GetAdminList.json b/src/Piwigo.Client.Tests/TagApi.GetAdminList.json new file mode 100644 index 0000000..8988376 --- /dev/null +++ b/src/Piwigo.Client.Tests/TagApi.GetAdminList.json @@ -0,0 +1,19 @@ +{ + "stat": "ok", + "result": { + "tags": [ + { + "id": "1", + "name": "tag1", + "url_name": "tag1", + "lastmodified": "2022-10-27 21:17:59" + }, + { + "id": "2", + "name": "tag2", + "url_name": "tag2", + "lastmodified": "2022-10-27 21:23:34" + } + ] + } +} \ No newline at end of file diff --git a/src/Piwigo.Client.Tests/TagApi.GetList.json b/src/Piwigo.Client.Tests/TagApi.GetList.json new file mode 100644 index 0000000..37a068a --- /dev/null +++ b/src/Piwigo.Client.Tests/TagApi.GetList.json @@ -0,0 +1,15 @@ +{ + "stat": "ok", + "result": { + "tags": [ + { + "id": 1, + "name": "tag1", + "url_name": "tag1", + "lastmodified": "2022-10-27 21:17:59", + "counter": 1, + "url": "http://localhost:8080/index.php?/tags/1-tag1" + } + ] + } +} \ No newline at end of file diff --git a/src/Piwigo.Client.Tests/TagApiTests.AddAsync_should_add_tag_and_return_correct_result.verified.txt b/src/Piwigo.Client.Tests/TagApiTests.AddAsync_should_add_tag_and_return_correct_result.verified.txt new file mode 100644 index 0000000..dd8a748 --- /dev/null +++ b/src/Piwigo.Client.Tests/TagApiTests.AddAsync_should_add_tag_and_return_correct_result.verified.txt @@ -0,0 +1,6 @@ +{ + info: Keyword "test3" has been added, + id: 3, + name: test3, + url_name: test3 +} \ No newline at end of file diff --git a/src/Piwigo.Client.Tests/TagApiTests.GetAdminListAsync_should_return_all_tags.verified.txt b/src/Piwigo.Client.Tests/TagApiTests.GetAdminListAsync_should_return_all_tags.verified.txt new file mode 100644 index 0000000..8ecc262 --- /dev/null +++ b/src/Piwigo.Client.Tests/TagApiTests.GetAdminListAsync_should_return_all_tags.verified.txt @@ -0,0 +1,14 @@ +[ + { + id: 1, + name: tag1, + url_name: tag1, + lastmodified: DateTime_1 + }, + { + id: 2, + name: tag2, + url_name: tag2, + lastmodified: DateTime_2 + } +] \ No newline at end of file diff --git a/src/Piwigo.Client.Tests/TagApiTests.GetListAsync_should_return_all_tags.verified.txt b/src/Piwigo.Client.Tests/TagApiTests.GetListAsync_should_return_all_tags.verified.txt new file mode 100644 index 0000000..5e6ae85 --- /dev/null +++ b/src/Piwigo.Client.Tests/TagApiTests.GetListAsync_should_return_all_tags.verified.txt @@ -0,0 +1,10 @@ +[ + { + counter: 1, + url: http://localhost:8080/index.php?/tags/1-tag1, + id: 1, + name: tag1, + url_name: tag1, + lastmodified: DateTime_1 + } +] \ No newline at end of file diff --git a/src/Piwigo.Client.Tests/TagApiTests.cs b/src/Piwigo.Client.Tests/TagApiTests.cs new file mode 100644 index 0000000..a054d90 --- /dev/null +++ b/src/Piwigo.Client.Tests/TagApiTests.cs @@ -0,0 +1,54 @@ +using Microsoft.Extensions.Logging.Abstractions; +using Piwigo.Client.Tags; + +namespace Piwigo.Client.Tests; + +[TestFixture] +public class TagApiTests : ApiTestsBase +{ + private ITagApi _tagApi = null!; + private const string ApiToken = "37ff55f201cf54eadf11f734a74f1d0e"; + + protected override void OnSetUp() + { + base.OnSetUp(); + _tagApi = new TagApi(Context, new NullLogger()); + } + + [Test] + public async Task AddAsync_should_add_tag_and_return_correct_result() + { + SetJsonResult(@"{""stat"":""ok"",""result"":{""info"":""Keyword \""test3\"" has been added"",""id"":3,""name"":""test3"",""url_name"":""test3""}}"); + + var response = await _tagApi.AddAsync("test3"); + + CorrectMethodShouldGetCalled("pwg.tags.add"); + CorrectParamShouldGetSent("name", "test3"); + + await Verify(response); + } + + [Test] + public async Task GetAdminListAsync_should_return_all_tags() + { + await SetJsonResultFromFileAsync("TagApi.GetAdminList.json"); + + var response = await _tagApi.GetAdminListAsync(); + + CorrectMethodShouldGetCalled("pwg.tags.getAdminList"); + + await Verify(response); + } + + [Test] + public async Task GetListAsync_should_return_all_tags() + { + await SetJsonResultFromFileAsync("TagApi.GetList.json"); + + var response = await _tagApi.GetListAsync(); + + CorrectMethodShouldGetCalled("pwg.tags.getList"); + + await Verify(response); + } +} \ No newline at end of file diff --git a/src/Piwigo.Client/Tags/AssignedTag.cs b/src/Piwigo.Client/Tags/AssignedTag.cs new file mode 100644 index 0000000..b80a0d8 --- /dev/null +++ b/src/Piwigo.Client/Tags/AssignedTag.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Tags; + +public record AssignedTag : Tag +{ + [JsonProperty("counter")] + public int Counter { get; init; } + + [JsonProperty("url")] + public string Url { get; init; } +} \ No newline at end of file diff --git a/src/Piwigo.Client/Tags/ITagApi.cs b/src/Piwigo.Client/Tags/ITagApi.cs index 9eeb9e2..2aa1ca6 100644 --- a/src/Piwigo.Client/Tags/ITagApi.cs +++ b/src/Piwigo.Client/Tags/ITagApi.cs @@ -2,4 +2,32 @@ namespace Piwigo.Client.Tags; public interface ITagApi { + /// + /// Adds a new tag to the gallery + /// + /// the name of the tag + /// + /// + /// + /// Information about the uploaded tag + Task AddAsync(string name, CancellationToken cancellationToken = default); + + /// + /// Gets a list of all known tags. This call is only available for admins + /// + /// + /// + /// + /// all available tags + Task> GetAdminListAsync(CancellationToken cancellationToken = default); + + /// + /// Gits a list of known tags that are at least assigned to one image + /// + /// sorts the result by the number of assigned images of a tag + /// + /// + /// + /// all tags with at least one image assigned + Task> GetListAsync(bool? sortByCounter = null, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/Piwigo.Client/Tags/Tag.cs b/src/Piwigo.Client/Tags/Tag.cs new file mode 100644 index 0000000..b4ed8b4 --- /dev/null +++ b/src/Piwigo.Client/Tags/Tag.cs @@ -0,0 +1,20 @@ +using System.Diagnostics.CodeAnalysis; +using Newtonsoft.Json; + +namespace Piwigo.Client.Tags; + +[SuppressMessage("ReSharper", "StringLiteralTypo")] +public record Tag +{ + [JsonProperty("id")] + public int Id { get; init; } + + [JsonProperty("name")] + public string? Name { get; init; } + + [JsonProperty("url_name")] + public string? UrlName { get; init; } + + [JsonProperty("lastmodified")] + public DateTime? LastModified { get; init; } +} \ No newline at end of file diff --git a/src/Piwigo.Client/Tags/TagAdded.cs b/src/Piwigo.Client/Tags/TagAdded.cs new file mode 100644 index 0000000..27cf591 --- /dev/null +++ b/src/Piwigo.Client/Tags/TagAdded.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Tags; + +public record TagAdded +{ + [JsonProperty("info")] + public string? Info { get; init; } + + [JsonProperty("id")] + public int Id { get; init; } + + [JsonProperty("name")] + public string? Name { get; init; } + + [JsonProperty("url_name")] + public string? UrlName { get; init; } +} \ No newline at end of file diff --git a/src/Piwigo.Client/Tags/TagApi.cs b/src/Piwigo.Client/Tags/TagApi.cs index dae0886..1b8385b 100644 --- a/src/Piwigo.Client/Tags/TagApi.cs +++ b/src/Piwigo.Client/Tags/TagApi.cs @@ -1,5 +1,40 @@ +using Microsoft.Extensions.Logging; + namespace Piwigo.Client.Tags; public class TagApi : ITagApi { + private readonly IPiwigoContext _context; + private readonly ILogger _logger; + + public TagApi(IPiwigoContext context, ILogger logger) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public async Task AddAsync(string name, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary + { + { "name", name } + }; + var response = await _context.PostAsync>(_logger, "pwg.tags.add", formParams, cancellationToken); + return response.Result; + } + + public async Task> GetAdminListAsync(CancellationToken cancellationToken = default) + { + var response = await _context.PostAsync>>(_logger, "pwg.tags.getAdminList", new Dictionary(), cancellationToken); + return response.Result.Tags; + } + + public async Task> GetListAsync(bool? sortByCounter = null, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary(); + formParams.AddIfValueNotNull("sort_by_counter", sortByCounter?.ToString()); + + var response = await _context.PostAsync>>(_logger, "pwg.tags.getList", formParams, cancellationToken); + return response.Result.Tags; + } } \ No newline at end of file diff --git a/src/Piwigo.Client/Tags/TagList.cs b/src/Piwigo.Client/Tags/TagList.cs new file mode 100644 index 0000000..c8bfab2 --- /dev/null +++ b/src/Piwigo.Client/Tags/TagList.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Tags; + +internal record TagList +{ + [JsonProperty("tags")] + public IReadOnlyCollection Tags { get; init; } = null!; +} \ No newline at end of file