aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-02-11 22:21:12 +0800
committercrupest <crupest@outlook.com>2021-02-11 22:21:12 +0800
commitb5376f71157f68f06aa04bde79389f9ab291d84a (patch)
tree369d3a89588e752983a26baff9c225ce43ad3ef8
parentd1317bd9fe08a933a13df88ba692343cde549123 (diff)
downloadtimeline-b5376f71157f68f06aa04bde79389f9ab291d84a.tar.gz
timeline-b5376f71157f68f06aa04bde79389f9ab291d84a.tar.bz2
timeline-b5376f71157f68f06aa04bde79389f9ab291d84a.zip
...
-rw-r--r--BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs338
-rw-r--r--BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs17
-rw-r--r--BackEnd/Timeline/Controllers/UserAvatarController.cs4
-rw-r--r--BackEnd/Timeline/Entities/TimelinePostEntity.cs2
-rw-r--r--BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs6
-rw-r--r--BackEnd/Timeline/Models/Http/HttpTimelinePost.cs5
-rw-r--r--BackEnd/Timeline/Models/Http/HttpTimelinePostCreateRequest.cs2
-rw-r--r--BackEnd/Timeline/Models/Mapper/TimelineMapper.cs2
-rw-r--r--BackEnd/Timeline/Services/TimelinePostService.cs4
9 files changed, 87 insertions, 293 deletions
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs
index 4caff416..bd79ae18 100644
--- a/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs
+++ b/BackEnd/Timeline.Tests/IntegratedTests/TimelinePostTest.cs
@@ -1,44 +1,43 @@
using FluentAssertions;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Formats.Png;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text;
using System.Threading.Tasks;
-using Timeline.Entities;
using Timeline.Models;
using Timeline.Models.Http;
-using Timeline.Tests.Helpers;
using Xunit;
+using Xunit.Abstractions;
namespace Timeline.Tests.IntegratedTests
{
- public static class TimelineHelper
+ public class TimelinePostTest : BaseTimelineTest
{
- public static HttpTimelinePostContent TextPostContent(string text)
+ private static HttpTimelinePostCreateRequest CreateTextPostRequest(string text, DateTime? time = null, string? color = null)
{
- return new HttpTimelinePostContent("text", text, null, null);
- }
-
- public static HttpTimelinePostCreateRequest TextPostCreateRequest(string text, DateTime? time = null)
- {
- return new HttpTimelinePostCreateRequest
+ return new HttpTimelinePostCreateRequest()
{
- Content = new HttpTimelinePostCreateRequestContent
+ Time = time,
+ Color = color,
+ DataList = new List<HttpTimelinePostCreateRequestData>()
{
- Type = "text",
- Text = text
- },
- Time = time
+ new HttpTimelinePostCreateRequestData()
+ {
+ ContentType = MimeTypes.TextPlain,
+ Data = Convert.ToBase64String(Encoding.UTF8.GetBytes(text))
+ }
+ }
};
}
- }
- public class TimelinePostTest : BaseTimelineTest
- {
+ private readonly ITestOutputHelper _outputHelper;
+
+ public TimelinePostTest(ITestOutputHelper outputHelper)
+ {
+ _outputHelper = outputHelper;
+ }
+
[Theory]
[MemberData(nameof(TimelineNameGeneratorTestData))]
public async Task GetPostsAndVisibility_Should_Work(TimelineNameGenerator generator)
@@ -102,15 +101,13 @@ namespace Timeline.Tests.IntegratedTests
{
using var client = await CreateClientAsUser();
- var postContentList = new List<string> { "a", "b", "c", "d" };
var posts = new List<HttpTimelinePost>();
- foreach (var content in postContentList)
+ for (int i = 0; i < 4; i++)
{
- var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts",
- new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Text = content, Type = TimelinePostDataKind.Text } });
+ var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", CreateTextPostRequest("a"));
posts.Add(post);
- await Task.Delay(1000);
+ await Task.Delay(TimeSpan.FromSeconds(1));
}
await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{posts[2].Id}");
@@ -118,64 +115,57 @@ namespace Timeline.Tests.IntegratedTests
{
var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts?modifiedSince={posts[1].LastUpdated.ToString("s", CultureInfo.InvariantCulture) }");
body.Should().HaveCount(2)
- .And.Subject.Select(p => p.Content!.Text).Should().Equal("b", "d");
+ .And.Subject.Select(p => p.Id).Should().Equal(posts[1].Id, posts[3].Id);
}
}
[Theory]
[MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task Post_ModifiedSince_And_IncludeDeleted(TimelineNameGenerator generator)
+ public async Task PostList_IncludeDeleted(TimelineNameGenerator generator)
{
using var client = await CreateClientAsUser();
- var postContentList = new List<string> { "a", "b", "c", "d" };
var posts = new List<HttpTimelinePost>();
- foreach (var (content, index) in postContentList.Select((v, i) => (v, i)))
+ for (int i = 0; i < 4; i++)
{
- var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts",
- new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Text = content, Type = TimelinePostDataKind.Text } });
- posts.Add(post);
- await Task.Delay(1000);
+ var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", CreateTextPostRequest("a"));
+ posts.Add(body);
}
- await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{posts[2].Id}");
-
+ foreach (var id in new long[] { posts[0].Id, posts[2].Id })
{
+ await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{id}");
+ }
- posts = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts?modifiedSince={posts[1].LastUpdated.ToString("s", CultureInfo.InvariantCulture)}&includeDeleted=true");
- posts.Should().HaveCount(3);
- posts.Select(p => p.Deleted).Should().Equal(false, true, false);
- posts.Select(p => p.Content == null).Should().Equal(false, true, false);
+ {
+ posts = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts?includeDeleted=true");
+ posts.Should().HaveCount(4);
+ posts.Select(p => p.Deleted).Should().Equal(true, false, true, false);
}
}
[Theory]
[MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task PostList_IncludeDeleted(TimelineNameGenerator generator)
+ public async Task Post_ModifiedSince_And_IncludeDeleted(TimelineNameGenerator generator)
{
using var client = await CreateClientAsUser();
- var postContentList = new List<string> { "a", "b", "c", "d" };
var posts = new List<HttpTimelinePost>();
- foreach (var content in postContentList)
+ for (int i = 0; i < 4; i++)
{
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts",
- new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Text = content, Type = TimelinePostDataKind.Text } });
- posts.Add(body);
+ var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", CreateTextPostRequest("a"));
+ posts.Add(post);
+ await Task.Delay(TimeSpan.FromSeconds(1));
}
- foreach (var id in new long[] { posts[0].Id, posts[2].Id })
- {
- await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{id}");
- }
+ await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{posts[2].Id}");
{
- posts = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts?includeDeleted=true");
- posts.Should().HaveCount(4);
- posts.Select(p => p.Deleted).Should().Equal(true, false, true, false);
- posts.Select(p => p.Content == null).Should().Equal(true, false, true, false);
+ posts = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts?modifiedSince={posts[1].LastUpdated.ToString("s", CultureInfo.InvariantCulture)}&includeDeleted=true");
+ posts.Should().HaveCount(3);
+ posts.Select(p => p.Deleted).Should().Equal(false, true, false);
}
}
@@ -190,25 +180,25 @@ namespace Timeline.Tests.IntegratedTests
using (var client = await CreateDefaultClient())
{ // no auth should get 401
- await client.TestPostAssertUnauthorizedAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
+ await client.TestPostAssertUnauthorizedAsync($"timelines/{generator(1)}/posts", CreateTextPostRequest("aaa"));
}
using (var client = await CreateClientAsUser())
{
// post self's
- await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
+ await client.TestPostAsync($"timelines/{generator(1)}/posts", CreateTextPostRequest("aaa"));
// post other not as a member should get 403
- await client.TestPostAssertForbiddenAsync($"timelines/{generator(0)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
+ await client.TestPostAssertForbiddenAsync($"timelines/{generator(0)}/posts", CreateTextPostRequest("aaa"));
}
using (var client = await CreateClientAsAdministrator())
{ // post as admin
- await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
+ await client.TestPostAsync($"timelines/{generator(1)}/posts", CreateTextPostRequest("aaa"));
}
using (var client = await CreateClientAs(2))
{ // post as member
- await client.TestPostAsync($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
+ await client.TestPostAsync($"timelines/{generator(1)}/posts", CreateTextPostRequest("aaa"));
}
}
@@ -219,7 +209,7 @@ namespace Timeline.Tests.IntegratedTests
async Task<long> CreatePost(int userNumber)
{
using var client = await CreateClientAs(userNumber);
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
+ var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", CreateTextPostRequest("aaa"));
return body.Id;
}
@@ -267,64 +257,13 @@ namespace Timeline.Tests.IntegratedTests
[Theory]
[MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task TextPost_Should_Work(TimelineNameGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- {
- var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts");
- body.Should().BeEmpty();
- }
-
- const string mockContent = "aaa";
- HttpTimelinePost createRes;
- {
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest(mockContent));
- body.Content.Should().BeEquivalentTo(TimelineHelper.TextPostContent(mockContent));
- body.Author.Should().BeEquivalentTo(await client.GetUserAsync("user1"));
- body.Deleted.Should().BeFalse();
- createRes = body;
- }
- {
- var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts");
- body.Should().BeEquivalentTo(createRes);
- }
- const string mockContent2 = "bbb";
- var mockTime2 = DateTime.UtcNow.AddDays(-1);
- HttpTimelinePost createRes2;
- {
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest(mockContent2, mockTime2));
- body.Should().NotBeNull();
- body.Content.Should().BeEquivalentTo(TimelineHelper.TextPostContent(mockContent2));
- body.Author.Should().BeEquivalentTo(await client.GetUserAsync("user1"));
- body.Time.Should().BeCloseTo(mockTime2, 1000);
- body.Deleted.Should().BeFalse();
- createRes2 = body;
- }
- {
- var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts");
- body.Should().BeEquivalentTo(createRes, createRes2);
- }
- {
- await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{createRes.Id}");
- await client.TestDeleteAssertErrorAsync($"timelines/{generator(1)}/posts/{createRes.Id}");
- await client.TestDeleteAssertErrorAsync($"timelines/{generator(1)}/posts/30000");
- }
- {
- var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts");
- body.Should().BeEquivalentTo(createRes2);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineNameGeneratorTestData))]
public async Task GetPost_Should_Ordered(TimelineNameGenerator generator)
{
using var client = await CreateClientAsUser();
async Task<long> CreatePost(DateTime time)
{
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa", time));
+ var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", CreateTextPostRequest("aaa", time));
return body.Id;
}
@@ -341,164 +280,17 @@ namespace Timeline.Tests.IntegratedTests
[Theory]
[MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task CreatePost_InvalidModel(TimelineNameGenerator generator)
- {
- using var client = await CreateClientAsUser();
- var postUrl = $"timelines/{generator(1)}/posts";
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = null! });
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Type = null! } });
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Type = "hahaha" } });
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Type = "text", Text = null } });
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Type = "image", Data = null } });
- // image not base64
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Type = "image", Data = "!!!" } });
- // image base64 not image
- await client.TestPostAssertInvalidModelAsync(postUrl, new HttpTimelinePostCreateRequest { Content = new HttpTimelinePostCreateRequestContent { Type = "image", Data = Convert.ToBase64String(new byte[] { 0x01, 0x02, 0x03 }) } });
- }
-
- [Theory]
- [MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task ImagePost_ShouldWork(TimelineNameGenerator generator)
- {
- var imageData = ImageHelper.CreatePngWithSize(100, 200);
-
- long postId;
- string postImageUrl;
-
- void AssertPostContent(HttpTimelinePostContent content)
- {
- content.Type.Should().Be(TimelinePostDataKind.Image);
- content.Url.Should().EndWith($"timelines/{generator(1)}/posts/{postId}/data");
- content.Text.Should().Be(null);
- }
-
- using var client = await CreateClientAsUser();
-
- {
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts",
- new HttpTimelinePostCreateRequest
- {
- Content = new HttpTimelinePostCreateRequestContent
- {
- Type = TimelinePostDataKind.Image,
- Data = Convert.ToBase64String(imageData)
- }
- });
- postId = body.Id;
- postImageUrl = body.Content!.Url!;
- AssertPostContent(body.Content);
- }
-
- {
- var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts");
- body.Should().HaveCount(1);
- var post = body[0];
- post.Id.Should().Be(postId);
- AssertPostContent(post.Content!);
- }
-
- {
- var res = await client.GetAsync($"timelines/{generator(1)}/posts/{postId}/data");
- res.Content.Headers.ContentType!.MediaType.Should().Be("image/png");
- var data = await res.Content.ReadAsByteArrayAsync();
- var image = Image.Load(data, out var format);
- image.Width.Should().Be(100);
- image.Height.Should().Be(200);
- format.Name.Should().Be(PngFormat.Instance.Name);
- }
-
- await CacheTestHelper.TestCache(client, $"timelines/{generator(1)}/posts/{postId}/data");
- await client.TestDeleteAsync($"timelines/{generator(1)}/posts/{postId}");
- await client.TestDeleteAssertErrorAsync($"timelines/{generator(1)}/posts/{postId}");
-
- {
- var body = await client.TestGetAsync<List<HttpTimelinePost>>($"timelines/{generator(1)}/posts");
- body.Should().BeEmpty();
- }
-
- {
- using var scope = TestApp.Host.Services.CreateScope();
- var database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
- var count = await database.Data.CountAsync();
- count.Should().Be(0);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task ImagePost_400(TimelineNameGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- await client.TestGetAssertNotFoundAsync($"timelines/{generator(1)}/posts/11234/data", errorCode: ErrorCodes.TimelineController.PostNotExist);
-
- long postId;
- {
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", TimelineHelper.TextPostCreateRequest("aaa"));
- postId = body.Id;
- }
-
- await client.TestGetAssertErrorAsync($"timelines/{generator(1)}/posts/{postId}/data", errorCode: ErrorCodes.TimelineController.PostNoData);
- }
-
- [Theory]
- [MemberData(nameof(TimelineNameGeneratorTestData))]
- public async Task PostDataETag(TimelineNameGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- long id;
- string etag;
-
- {
- var body = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", new HttpTimelinePostCreateRequest
- {
- Content = new HttpTimelinePostCreateRequestContent
- {
- Type = TimelinePostDataKind.Image,
- Data = Convert.ToBase64String(ImageHelper.CreatePngWithSize(100, 50))
- }
- });
- body.Content!.ETag.Should().NotBeNullOrEmpty();
-
- id = body.Id;
- etag = body.Content.ETag!;
- }
-
- {
- var res = await client.GetAsync($"timelines/{generator(1)}/posts/{id}/data");
- res.StatusCode.Should().Be(200);
- res.Headers.ETag.Should().NotBeNull();
- res.Headers.ETag!.ToString().Should().Be(etag);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineNameGeneratorTestData))]
public async Task Color(TimelineNameGenerator generator)
{
using var client = await CreateClientAsUser();
- HttpTimelinePostCreateRequestContent CreateRequestContent() => new()
- {
- Type = "text",
- Text = "aaa"
- };
-
- await client.TestPostAssertInvalidModelAsync($"timelines/{generator(1)}/posts", new HttpTimelinePostCreateRequest
- {
- Content = CreateRequestContent(),
- Color = "#1"
- });
+ await client.TestPostAssertInvalidModelAsync($"timelines/{generator(1)}/posts", CreateTextPostRequest("a", color: "aa"));
long id;
{
- var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", new HttpTimelinePostCreateRequest
- {
- Content = CreateRequestContent(),
- Color = "#aabbcc"
- });
+ var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts",
+ CreateTextPostRequest("a", color: "#aabbcc"));
post.Color.Should().Be("#aabbcc");
id = post.Id;
}
@@ -515,18 +307,10 @@ namespace Timeline.Tests.IntegratedTests
{
using var client = await CreateClientAsUser();
- HttpTimelinePostCreateRequestContent CreateRequestContent() => new()
- {
- Type = "text",
- Text = "aaa"
- };
await client.TestGetAssertNotFoundAsync($"timelines/{generator(1)}/posts/1");
- var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", new HttpTimelinePostCreateRequest
- {
- Content = CreateRequestContent(),
- });
+ var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", CreateTextPostRequest("a"));
var post2 = await client.TestGetAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts/{post.Id}");
post2.Should().BeEquivalentTo(post);
@@ -542,14 +326,8 @@ namespace Timeline.Tests.IntegratedTests
{
using var client = await CreateClientAsUser();
- var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts", new HttpTimelinePostCreateRequest
- {
- Content = new()
- {
- Type = "text",
- Text = "aaa"
- }
- });
+ var post = await client.TestPostAsync<HttpTimelinePost>($"timelines/{generator(1)}/posts",
+ CreateTextPostRequest("a"));
var date = new DateTime(2000, 10, 1);
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
index 893a5d28..708120b1 100644
--- a/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
+++ b/BackEnd/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
@@ -11,8 +11,8 @@ using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
+using Timeline.Models;
using Timeline.Models.Http;
-using Timeline.Services;
using Timeline.Tests.Helpers;
using Xunit;
@@ -23,11 +23,10 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task Test()
{
- Avatar mockAvatar = new Avatar
- {
- Data = ImageHelper.CreatePngWithSize(100, 100),
- Type = PngFormat.Instance.DefaultMimeType
- };
+ ByteData mockAvatar = new ByteData(
+ ImageHelper.CreatePngWithSize(100, 100),
+ PngFormat.Instance.DefaultMimeType
+ );
using (var client = await CreateClientAsUser())
{
@@ -106,7 +105,7 @@ namespace Timeline.Tests.IntegratedTests
}
{
- await client.TestPutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.Type);
+ await client.TestPutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.ContentType);
await TestAvatar("user1", mockAvatar.Data);
}
@@ -137,7 +136,7 @@ namespace Timeline.Tests.IntegratedTests
// Authorization check.
using (var client = await CreateClientAsAdministrator())
{
- await client.TestPutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.Type);
+ await client.TestPutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.ContentType);
await client.TestDeleteAsync("users/user1/avatar");
await client.TestPutByteArrayAssertErrorAsync("users/usernotexist/avatar", new[] { (byte)0x00 }, "image/png", errorCode: ErrorCodes.UserCommon.NotExist);
await client.TestDeleteAssertErrorAsync("users/usernotexist/avatar", errorCode: ErrorCodes.UserCommon.NotExist);
@@ -175,4 +174,4 @@ namespace Timeline.Tests.IntegratedTests
}
}
}
-} \ No newline at end of file
+}
diff --git a/BackEnd/Timeline/Controllers/UserAvatarController.cs b/BackEnd/Timeline/Controllers/UserAvatarController.cs
index 8ac2d21a..180d1f9b 100644
--- a/BackEnd/Timeline/Controllers/UserAvatarController.cs
+++ b/BackEnd/Timeline/Controllers/UserAvatarController.cs
@@ -102,12 +102,12 @@ namespace Timeline.Controllers
try
{
- var etag = await _service.SetAvatar(id, body);
+ var digest = await _service.SetAvatar(id, body);
_logger.LogInformation(Log.Format(LogPutSuccess,
("Username", username), ("Mime Type", Request.ContentType)));
- Response.Headers.Append("ETag", new EntityTagHeaderValue($"\"{etag}\"").ToString());
+ Response.Headers.Append("ETag", new EntityTagHeaderValue($"\"{digest.ETag}\"").ToString());
return Ok();
}
diff --git a/BackEnd/Timeline/Entities/TimelinePostEntity.cs b/BackEnd/Timeline/Entities/TimelinePostEntity.cs
index c65ef929..1f0270cb 100644
--- a/BackEnd/Timeline/Entities/TimelinePostEntity.cs
+++ b/BackEnd/Timeline/Entities/TimelinePostEntity.cs
@@ -37,6 +37,8 @@ namespace Timeline.Entities
[Column("last_updated")]
public DateTime LastUpdated { get; set; }
+#pragma warning disable CA2227
public List<TimelinePostDataEntity> DataList { get; set; } = default!;
+#pragma warning restore CA2227
}
}
diff --git a/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs b/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs
index 2451ead6..49f8221a 100644
--- a/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs
+++ b/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs
@@ -44,6 +44,12 @@ namespace Timeline.Formatters
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<ByteDataInputFormatter>>();
+ if (request.ContentType is null)
+ {
+ logger.LogInformation("Failed to read body as bytes. Content-Type is not set.");
+ return await InputFormatterResult.FailureAsync();
+ }
+
if (contentLength == null)
{
logger.LogInformation("Failed to read body as bytes. Content-Length is not set.");
diff --git a/BackEnd/Timeline/Models/Http/HttpTimelinePost.cs b/BackEnd/Timeline/Models/Http/HttpTimelinePost.cs
index 165c92da..26e1a92d 100644
--- a/BackEnd/Timeline/Models/Http/HttpTimelinePost.cs
+++ b/BackEnd/Timeline/Models/Http/HttpTimelinePost.cs
@@ -26,7 +26,12 @@ namespace Timeline.Models.Http
/// Post id.
/// </summary>
public long Id { get; set; }
+ /// <summary>
+ /// The data list.
+ /// </summary>
+#pragma warning disable CA2227
public List<HttpTimelinePostDataDigest> DataList { get; set; } = default!;
+#pragma warning restore CA2227
/// <summary>
/// True if post is deleted.
/// </summary>
diff --git a/BackEnd/Timeline/Models/Http/HttpTimelinePostCreateRequest.cs b/BackEnd/Timeline/Models/Http/HttpTimelinePostCreateRequest.cs
index 07d823ad..2a973c72 100644
--- a/BackEnd/Timeline/Models/Http/HttpTimelinePostCreateRequest.cs
+++ b/BackEnd/Timeline/Models/Http/HttpTimelinePostCreateRequest.cs
@@ -13,7 +13,9 @@ namespace Timeline.Models.Http
[Required]
[MinLength(1)]
[MaxLength(100)]
+#pragma warning disable CA2227
public List<HttpTimelinePostCreateRequestData> DataList { get; set; } = default!;
+#pragma warning restore CA2227
/// <summary>
/// Time of the post. If not set, current time will be used.
diff --git a/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs b/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs
index 33ee9593..1f10c123 100644
--- a/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs
+++ b/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs
@@ -66,6 +66,8 @@ namespace Timeline.Models.Mapper
public async Task<HttpTimelinePost> MapToHttp(TimelinePostEntity entity, string timelineName, IUrlHelper urlHelper)
{
+ _ = timelineName;
+
await _database.Entry(entity).Collection(p => p.DataList).LoadAsync();
await _database.Entry(entity).Reference(e => e.Author).LoadAsync();
diff --git a/BackEnd/Timeline/Services/TimelinePostService.cs b/BackEnd/Timeline/Services/TimelinePostService.cs
index 8afd0770..62bc43cc 100644
--- a/BackEnd/Timeline/Services/TimelinePostService.cs
+++ b/BackEnd/Timeline/Services/TimelinePostService.cs
@@ -1,6 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
-using SixLabors.ImageSharp;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,7 +11,6 @@ using Timeline.Helpers.Cache;
using Timeline.Models;
using Timeline.Models.Validation;
using Timeline.Services.Exceptions;
-using static Timeline.Resources.Services.TimelineService;
namespace Timeline.Services
{
@@ -37,7 +35,9 @@ namespace Timeline.Services
/// <summary>If not set, current time is used.</summary>
public DateTime? Time { get; set; }
+#pragma warning disable CA2227
public List<TimelinePostCreateRequestData> DataList { get; set; } = new List<TimelinePostCreateRequestData>();
+#pragma warning restore CA2227
}
public class TimelinePostPatchRequest