From 4dda5d088330e76844010a4f89049ea207652318 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 31 Aug 2020 22:22:57 +0800 Subject: Now uesr avatar put api returns etag. --- Timeline.Tests/Helpers/HttpResponseExtensions.cs | 35 ++++++++++++++++++++++++ Timeline.Tests/IntegratedTests/UserAvatarTest.cs | 25 +++++++++++++++++ Timeline/Controllers/UserAvatarController.cs | 6 +++- Timeline/Services/UserAvatarService.cs | 14 +++++----- 4 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 Timeline.Tests/Helpers/HttpResponseExtensions.cs diff --git a/Timeline.Tests/Helpers/HttpResponseExtensions.cs b/Timeline.Tests/Helpers/HttpResponseExtensions.cs new file mode 100644 index 00000000..2bd497f1 --- /dev/null +++ b/Timeline.Tests/Helpers/HttpResponseExtensions.cs @@ -0,0 +1,35 @@ +using System.Net.Http; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using Timeline.Models.Converters; +using Timeline.Models.Http; + +namespace Timeline.Tests.Helpers +{ + public static class HttpResponseExtensions + { + public static JsonSerializerOptions JsonSerializerOptions { get; } + + static HttpResponseExtensions() + { + JsonSerializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); + JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter()); + } + + public static async Task ReadBodyAsJsonAsync(this HttpResponseMessage response) + { + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream, JsonSerializerOptions); + } + + public static Task ReadBodyAsCommonResponseAsync(this HttpResponseMessage response) + { + return response.ReadBodyAsJsonAsync(); + } + } +} diff --git a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs index 507b05ba..f2796005 100644 --- a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs +++ b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs @@ -10,6 +10,7 @@ using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; +using System.Net.Mime; using System.Threading.Tasks; using Timeline.Models.Http; using Timeline.Services; @@ -222,5 +223,29 @@ namespace Timeline.Tests.IntegratedTests } } } + + [Fact] + public async Task AvatarPutReturnETag() + { + using var client = await CreateClientAsUser(); + + EntityTagHeaderValue etag; + + { + var image = ImageHelper.CreatePngWithSize(100, 100); + var res = await client.PutByteArrayAsync("users/user1/avatar", image, PngFormat.Instance.DefaultMimeType); + res.Should().HaveStatusCode(200); + etag = res.Headers.ETag; + etag.Should().NotBeNull(); + etag.Tag.Should().NotBeNullOrEmpty(); + } + + { + var res = await client.GetAsync("users/user1/avatar"); + res.Should().HaveStatusCode(200); + res.Headers.ETag.Should().Be(etag); + res.Headers.ETag.Tag.Should().Be(etag.Tag); + } + } } } \ No newline at end of file diff --git a/Timeline/Controllers/UserAvatarController.cs b/Timeline/Controllers/UserAvatarController.cs index 97c4bdb8..bc4afa30 100644 --- a/Timeline/Controllers/UserAvatarController.cs +++ b/Timeline/Controllers/UserAvatarController.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; using System; using System.Threading.Tasks; using Timeline.Auth; @@ -105,7 +106,7 @@ namespace Timeline.Controllers try { - await _service.SetAvatar(id, new Avatar + var etag = await _service.SetAvatar(id, new Avatar { Data = body.Data, Type = body.ContentType @@ -113,6 +114,9 @@ namespace Timeline.Controllers _logger.LogInformation(Log.Format(LogPutSuccess, ("Username", username), ("Mime Type", Request.ContentType))); + + Response.Headers.Append("ETag", new EntityTagHeaderValue($"\"{etag}\"").ToString()); + return Ok(); } catch (ImageException e) diff --git a/Timeline/Services/UserAvatarService.cs b/Timeline/Services/UserAvatarService.cs index 2bf8bddc..b41c45fd 100644 --- a/Timeline/Services/UserAvatarService.cs +++ b/Timeline/Services/UserAvatarService.cs @@ -71,9 +71,10 @@ namespace Timeline.Services /// /// The id of the user to set avatar for. /// The avatar. Can be null to delete the saved avatar. + /// The etag of the avatar. /// Thrown if any field in is null when is not null. /// Thrown if avatar is of bad format. - Task SetAvatar(long id, Avatar? avatar); + Task SetAvatar(long id, Avatar? avatar); } // TODO! : Make this configurable. @@ -199,7 +200,7 @@ namespace Timeline.Services return defaultAvatar; } - public async Task SetAvatar(long id, Avatar? avatar) + public async Task SetAvatar(long id, Avatar? avatar) { if (avatar != null) { @@ -213,11 +214,7 @@ namespace Timeline.Services if (avatar == null) { - if (avatarEntity == null || avatarEntity.DataTag == null) - { - return; - } - else + if (avatarEntity != null && avatarEntity.DataTag != null) { await _dataManager.FreeEntry(avatarEntity.DataTag); avatarEntity.DataTag = null; @@ -226,6 +223,7 @@ namespace Timeline.Services await _database.SaveChangesAsync(); _logger.LogInformation(Resources.Services.UserAvatarService.LogUpdateEntity); } + return await _defaultUserAvatarProvider.GetDefaultAvatarETag(); } else { @@ -250,6 +248,8 @@ namespace Timeline.Services { await _dataManager.FreeEntry(oldTag); } + + return avatarEntity.DataTag; } } } -- cgit v1.2.3