aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-08-31 22:22:57 +0800
committercrupest <crupest@outlook.com>2020-08-31 22:22:57 +0800
commitc73388256aad039239cf3977d7b079e3f9323258 (patch)
treec8f4b17ebb6623a6bafc03a2417d18b8615f94a0
parent12410a51fb2e5f55e8d83415bc3c4053a146ce3b (diff)
downloadtimeline-c73388256aad039239cf3977d7b079e3f9323258.tar.gz
timeline-c73388256aad039239cf3977d7b079e3f9323258.tar.bz2
timeline-c73388256aad039239cf3977d7b079e3f9323258.zip
Now uesr avatar put api returns etag.
-rw-r--r--Timeline.Tests/Helpers/HttpResponseExtensions.cs35
-rw-r--r--Timeline.Tests/IntegratedTests/UserAvatarTest.cs25
-rw-r--r--Timeline/Controllers/UserAvatarController.cs6
-rw-r--r--Timeline/Services/UserAvatarService.cs14
4 files changed, 72 insertions, 8 deletions
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<T> ReadBodyAsJsonAsync<T>(this HttpResponseMessage response)
+ {
+ var stream = await response.Content.ReadAsStreamAsync();
+ return await JsonSerializer.DeserializeAsync<T>(stream, JsonSerializerOptions);
+ }
+
+ public static Task<CommonResponse> ReadBodyAsCommonResponseAsync(this HttpResponseMessage response)
+ {
+ return response.ReadBodyAsJsonAsync<CommonResponse>();
+ }
+ }
+}
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
/// </summary>
/// <param name="id">The id of the user to set avatar for.</param>
/// <param name="avatar">The avatar. Can be null to delete the saved avatar.</param>
+ /// <returns>The etag of the avatar.</returns>
/// <exception cref="ArgumentException">Thrown if any field in <paramref name="avatar"/> is null when <paramref name="avatar"/> is not null.</exception>
/// <exception cref="ImageException">Thrown if avatar is of bad format.</exception>
- Task SetAvatar(long id, Avatar? avatar);
+ Task<string> 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<string> 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;
}
}
}