using System.Text; using Microsoft.Extensions.Logging.Abstractions; using Piwigo.Client.Contract; namespace Piwigo.Client.Tests; [TestFixture] public class ImageApiTests : ApiTestsBase { private IImageApi _imageApi = null!; private const string ApiToken = "37ff55f201cf54eadf11f734a74f1d0e"; protected override void OnSetUp() { base.OnSetUp(); _imageApi = new ImageApi(Context, new NullLogger()); } [Test] public async Task SetInfoAsync_should_pass_correct_mapped_values_to_piwigo() { SetOkResult(); var albums = new List<(int AlbumId, int? Rank)> { new ValueTuple(3, 10), new ValueTuple(5, null), new ValueTuple(7, 11) }; var imageInfo = new ImageInfo { Author = "unit test", Comment = "perfect image", Level = 42, Name = "Image001.jpg", CreatedAt = new DateTime(2022, 10, 22, 21, 50, 42), FileName = "RAW-Image001.jpg", Albums = albums, TagIds = new List { 2, 4, 8 } }; await _imageApi.SetInfoAsync(4, imageInfo); CorrectMethodShouldGetCalled("pwg.images.setInfo"); CorrectParamShouldGetSent("image_id", "4"); CorrectParamShouldGetSent("file", imageInfo.FileName); CorrectParamShouldGetSent("name", imageInfo.Name); CorrectParamShouldGetSent("author", imageInfo.Author); CorrectParamShouldGetSent("date_creation", "2022-10-22 21:50:42"); CorrectParamShouldGetSent("comment", imageInfo.Comment); CorrectParamShouldGetSent("level", imageInfo.Level.ToString()!); CorrectParamShouldGetSent("categories", "3,10;5;7,11"); CorrectParamShouldGetSent("tag_ids", "2,4,8"); CorrectParamShouldGetSent("single_value_mode", "fill_if_empty"); CorrectParamShouldGetSent("multiple_value_mode", "append"); } [Test] public async Task RateAsync_should_pass_correct_values_to_server_and_return_correctly_mapped_result() { SetJsonResult(@"{""stat"":""ok"",""result"":{""score"":5,""average"":4.5,""count"":""2""}}"); var rating = await _imageApi.RateAsync(4, 5); rating.Score.Should().Be(5); rating.Average.Should().Be(4.5f); rating.Count.Should().Be(2); CorrectMethodShouldGetCalled("pwg.images.rate"); CorrectParamShouldGetSent("image_id", "4"); CorrectParamShouldGetSent("rate", "5"); } [Test] public async Task ExistsByMd5SumsAsync_should_pass_correct_values_to_server_and_return_correctly_mapped_result() { SetJsonResult(@"{""stat"":""ok"",""result"":{""2c6d9eab0c567d5f96c53825ae53f3d4"":""4"",""ee45c441b8ea4bcb3ab9b7a51370b242"":null}}"); var existsResult = await _imageApi.ExistsByMd5SumsAsync(new[] { "2c6d9eab0c567d5f96c53825ae53f3d4", "ee45c441b8ea4bcb3ab9b7a51370b242" }); existsResult.Should().HaveCount(2); existsResult["2c6d9eab0c567d5f96c53825ae53f3d4"].Should().Be(4); existsResult["ee45c441b8ea4bcb3ab9b7a51370b242"].Should().BeNull(); CorrectMethodShouldGetCalled("pwg.images.exist"); CorrectParamShouldGetSent("md5sum_list", "2c6d9eab0c567d5f96c53825ae53f3d4,ee45c441b8ea4bcb3ab9b7a51370b242"); } [Test] public async Task DeleteOrphansAsync_should_pass_request_toPiwigo_and_return_performed_results() { SetJsonResult(@"{""stat"":""ok"",""result"":{""nb_deleted"":10,""nb_orphans"":154}}"); var (deleted, orphans) = await _imageApi.DeleteOrphansAsync(ApiToken, 10); deleted.Should().Be(10); orphans.Should().Be(154); CorrectMethodShouldGetCalled("pwg.images.deleteOrphans"); CorrectParamShouldGetSent("block_size", "10"); CorrectParamShouldGetSent("pwg_token", ApiToken); } [Test] public async Task DeleteAsync_should_pass_request_toPiwigo_and_return_success() { SetJsonResult(@"{""stat"":""ok"",""result"":1}"); var result = await _imageApi.DeleteAsync(1, ApiToken); result.Should().Be(true); CorrectMethodShouldGetCalled("pwg.images.delete"); CorrectParamShouldGetSent("image_id", "1"); CorrectParamShouldGetSent("pwg_token", ApiToken); } [Test] public async Task CheckImageAsync_should_pass_data_to_piwigo_and_return_status() { SetJsonResult(@"{""stat"":""ok"",""result"":{""file"":""differs""}}"); const string md5Sum = "ee45c441b8ea4bcb3ab9b7a51370b242"; var result = await _imageApi.CheckImageAsync(1, md5Sum); result.Should().Be(ImageCheckStatus.Differs); CorrectMethodShouldGetCalled("pwg.images.checkFiles"); CorrectParamShouldGetSent("image_id", "1"); CorrectParamShouldGetSent("file_sum", md5Sum); } [Test] public async Task AddComment_should_pass_data_to_piwigo_and_return_new_comment() { SetJsonResult(@"{""stat"":""ok"",""result"":{""comment"":{""id"":2,""validation"":true}}}"); var commentId = await _imageApi.AddCommentAsync(4, "admin", "test comment", "testKey"); CorrectMethodShouldGetCalled("pwg.images.addComment"); CorrectParamShouldGetSent("image_id", "4"); CorrectParamShouldGetSent("author", "admin"); CorrectParamShouldGetSent("content", "test comment"); CorrectParamShouldGetSent("key", "testKey"); commentId.Should().Be(2); } [Test] public async Task GetInfo_should_pass_request_and_return_data() { await SetJsonResultFromFileAsync("ImageApi.getInfo.json"); var response = await _imageApi.GetInfoAsync(3, 2, 100); CorrectMethodShouldGetCalled("pwg.images.getInfo"); CorrectParamShouldGetSent("image_id", "3"); CorrectParamShouldGetSent("comments_page", "2"); CorrectParamShouldGetSent("comments_per_page", "100"); await Verify(response); } [Test] public async Task Update_should_pass_data_to_piwigo() { SetJsonResult(@"{stat: ""ok"", result: { image_id: 1042, url: ""https://localhost/image.jpg"" }}"); var imageUpload = GetImageUpload(); var uploaded = await _imageApi.UpdateAsync(1234, imageUpload); uploaded.ImageId.Should().Be(1042); uploaded.Url.Should().Be("https://localhost/image.jpg"); CorrectMethodShouldGetCalled("pwg.images.add"); CorrectParamShouldGetSent("original_filename", imageUpload.FileName!); CorrectParamShouldGetSent("name", imageUpload.Name!); CorrectParamShouldGetSent("author", imageUpload.Author!); CorrectParamShouldGetSent("date_creation", "2022-10-22 21:50:42"); CorrectParamShouldGetSent("comment", imageUpload.Comment!); CorrectParamShouldGetSent("level", imageUpload.Level.ToString()!); CorrectParamShouldGetSent("categories", "3,10;5;7,11"); CorrectParamShouldGetSent("tag_ids", "2,4,8"); CorrectParamShouldGetSent("image_id", "1234"); } [Test] public async Task Add_should_pass_data_to_piwigo() { SetJsonResult(@"{stat: ""ok"", result: { image_id: 1042, url: ""https://localhost/image.jpg"" }}"); var imageUpload = GetImageUpload(); var uploaded = await _imageApi.AddAsync(imageUpload); uploaded.ImageId.Should().Be(1042); uploaded.Url.Should().Be("https://localhost/image.jpg"); CorrectMethodShouldGetCalled("pwg.images.add"); // must not be sent or it will be used as an update. // Piwigo uses the same request for add or update depending on this parameter ParamShouldNotGetSent("image_id"); CorrectParamShouldGetSent("original_filename", imageUpload.FileName!); CorrectParamShouldGetSent("name", imageUpload.Name!); CorrectParamShouldGetSent("author", imageUpload.Author!); CorrectParamShouldGetSent("date_creation", "2022-10-22 21:50:42"); CorrectParamShouldGetSent("comment", imageUpload.Comment!); CorrectParamShouldGetSent("level", imageUpload.Level.ToString()!); CorrectParamShouldGetSent("categories", "3,10;5;7,11"); CorrectParamShouldGetSent("tag_ids", "2,4,8"); } [Test] public async Task ReadyForUpload_should_return_correct_value() { SetJsonResult(@"{stat: ""ok"", result: { message: null, ready_for_upload: true }}"); var isReady = await _imageApi.ReadyForUploadAsync(); CorrectMethodShouldGetCalled("pwg.images.checkUpload"); isReady.Should().BeTrue(); } [Test] public async Task AddChunk_should_post_base64_encoded_data() { SetOkResult(); var bytes = Encoding.UTF8.GetBytes("PiwigoTestString"); var expectedBase64 = Convert.ToBase64String(bytes); await _imageApi.AddChunkAsync(bytes, "origSum", 0); CorrectMethodShouldGetCalled("pwg.images.addChunk"); CorrectParamShouldGetSent("data", expectedBase64); CorrectParamShouldGetSent("original_sum", "origSum"); CorrectParamShouldGetSent("type", "file"); CorrectParamShouldGetSent("position", "0"); } [Test] public async Task GetImages_should_return_expected_images() { await SetJsonResultFromFileAsync("ImageApi.getImages.json"); var result = await _imageApi.GetImagesAsync(7, true, new ImagePagingInfo(0, 100, 0), ImageFilter.Empty); CorrectMethodShouldGetCalled("pwg.categories.getImages"); CorrectParamShouldGetSent("cat_id", "7"); CorrectParamShouldGetSent("recursive", "true"); CorrectParamShouldGetSent("per_page", "100"); CorrectParamShouldGetSent("page", "0"); await Verify(result); } private static ImageUpload GetImageUpload() { var albums = new List<(int AlbumId, int? Rank)> { new ValueTuple(3, 10), new ValueTuple(5, null), new ValueTuple(7, 11) }; var imageUpload = new ImageUpload("md5Sum") { Author = "unit test", Comment = "perfect image", Level = 42, Name = "Image001.jpg", CreatedAt = new DateTime(2022, 10, 22, 21, 50, 42), FileName = "RAW-Image001.jpg", Albums = albums, TagIds = new List { 2, 4, 8 } }; return imageUpload; } }