aboutsummaryrefslogtreecommitdiff
path: root/Timeline.Tests
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-10-27 19:21:35 +0800
committercrupest <crupest@outlook.com>2020-10-27 19:21:35 +0800
commitac769e656b122ff569c3f1534701b71e00fed586 (patch)
tree72966645ff1e25139d3995262e1c4349f2c14733 /Timeline.Tests
parent14e5848c23c643cea9b5d709770747d98c3d75e2 (diff)
downloadtimeline-ac769e656b122ff569c3f1534701b71e00fed586.tar.gz
timeline-ac769e656b122ff569c3f1534701b71e00fed586.tar.bz2
timeline-ac769e656b122ff569c3f1534701b71e00fed586.zip
Split front and back end.
Diffstat (limited to 'Timeline.Tests')
-rw-r--r--Timeline.Tests/ErrorCodeTest.cs53
-rw-r--r--Timeline.Tests/GlobalSuppressions.cs16
-rw-r--r--Timeline.Tests/Helpers/AsyncFunctionAssertionsExtensions.cs16
-rw-r--r--Timeline.Tests/Helpers/CacheTestHelper.cs64
-rw-r--r--Timeline.Tests/Helpers/HttpClientExtensions.cs51
-rw-r--r--Timeline.Tests/Helpers/HttpResponseExtensions.cs35
-rw-r--r--Timeline.Tests/Helpers/ImageHelper.cs26
-rw-r--r--Timeline.Tests/Helpers/ParameterInfoAssertions.cs60
-rw-r--r--Timeline.Tests/Helpers/ReflectionHelper.cs13
-rw-r--r--Timeline.Tests/Helpers/ResponseAssertions.cs172
-rw-r--r--Timeline.Tests/Helpers/TestApplication.cs72
-rw-r--r--Timeline.Tests/Helpers/TestClock.cs43
-rw-r--r--Timeline.Tests/Helpers/TestDatabase.cs76
-rw-r--r--Timeline.Tests/IntegratedTests/AuthorizationTest.cs52
-rw-r--r--Timeline.Tests/IntegratedTests/FrontEndTest.cs29
-rw-r--r--Timeline.Tests/IntegratedTests/IntegratedTestBase.cs164
-rw-r--r--Timeline.Tests/IntegratedTests/TimelineTest.cs1523
-rw-r--r--Timeline.Tests/IntegratedTests/TokenTest.cs165
-rw-r--r--Timeline.Tests/IntegratedTests/UnknownEndpointTest.cs21
-rw-r--r--Timeline.Tests/IntegratedTests/UserAvatarTest.cs251
-rw-r--r--Timeline.Tests/IntegratedTests/UserTest.cs447
-rw-r--r--Timeline.Tests/PasswordGenerator.cs23
-rw-r--r--Timeline.Tests/Properties/launchSettings.json2
-rw-r--r--Timeline.Tests/Services/TimelineServiceTest.cs329
-rw-r--r--Timeline.Tests/Timeline.Tests.csproj34
-rw-r--r--Timeline.Tests/UsernameValidatorUnitTest.cs78
-rw-r--r--Timeline.Tests/coverletArgs.runsettings13
-rw-r--r--Timeline.Tests/packages.lock.json2040
28 files changed, 0 insertions, 5868 deletions
diff --git a/Timeline.Tests/ErrorCodeTest.cs b/Timeline.Tests/ErrorCodeTest.cs
deleted file mode 100644
index 258ebf4e..00000000
--- a/Timeline.Tests/ErrorCodeTest.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using FluentAssertions;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using Timeline.Models.Http;
-using Xunit;
-using Xunit.Abstractions;
-
-namespace Timeline.Tests
-{
- public class ErrorCodeTest
- {
- private readonly ITestOutputHelper _output;
-
- public ErrorCodeTest(ITestOutputHelper output)
- {
- _output = output;
- }
-
- [Fact]
- public void ShouldWork()
- {
- var errorCodes = new Dictionary<int, string>();
-
- void RecursiveCheckErrorCode(Type type)
- {
- foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
- .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(int)))
- {
- var name = type.FullName + "." + field.Name;
- var value = (int)field.GetRawConstantValue();
- _output.WriteLine($"Find error code {name} , value is {value}.");
-
- value.Should().BeInRange(1000_0000, 9999_9999, "Error code should have exactly 8 digits.");
-
- errorCodes.Should().NotContainKey(value,
- "identical error codes are found and conflict paths are {0} and {1}",
- name, errorCodes.GetValueOrDefault(value));
-
- errorCodes.Add(value, name);
- }
-
- foreach (var nestedType in type.GetNestedTypes())
- {
- RecursiveCheckErrorCode(nestedType);
- }
- }
-
- RecursiveCheckErrorCode(typeof(ErrorCodes));
- }
- }
-}
diff --git a/Timeline.Tests/GlobalSuppressions.cs b/Timeline.Tests/GlobalSuppressions.cs
deleted file mode 100644
index 0f873033..00000000
--- a/Timeline.Tests/GlobalSuppressions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// This file is used by Code Analysis to maintain SuppressMessage
-// attributes that are applied to this project.
-// Project-level suppressions either have no target or are given
-// a specific target and scoped to a namespace, type, member, etc.
-
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "This is not a UI application.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Tests name have underscores.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Test may catch all exceptions.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "Test classes can be nested.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "This is redundant.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1063:Implement IDisposable Correctly", Justification = "Test classes do not need to implement it that way.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose methods should call SuppressFinalize", Justification = "Test classes do not need to implement it that way.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2234:Pass system uri objects instead of strings", Justification = "I really don't understand this rule.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "Tests do not need make strings resources.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1054:Uri parameters should not be strings", Justification = "That's unnecessary.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1056:Uri properties should not be strings", Justification = "That's unnecessary.")]
diff --git a/Timeline.Tests/Helpers/AsyncFunctionAssertionsExtensions.cs b/Timeline.Tests/Helpers/AsyncFunctionAssertionsExtensions.cs
deleted file mode 100644
index b78309c0..00000000
--- a/Timeline.Tests/Helpers/AsyncFunctionAssertionsExtensions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using FluentAssertions;
-using FluentAssertions.Primitives;
-using FluentAssertions.Specialized;
-using System;
-using System.Threading.Tasks;
-
-namespace Timeline.Tests.Helpers
-{
- public static class AsyncFunctionAssertionsExtensions
- {
- public static async Task<AndConstraint<ObjectAssertions>> ThrowAsync(this AsyncFunctionAssertions assertions, Type exceptionType, string because = "", params object[] becauseArgs)
- {
- return (await assertions.ThrowAsync<Exception>(because, becauseArgs)).Which.Should().BeAssignableTo(exceptionType);
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/CacheTestHelper.cs b/Timeline.Tests/Helpers/CacheTestHelper.cs
deleted file mode 100644
index b3709a28..00000000
--- a/Timeline.Tests/Helpers/CacheTestHelper.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using FluentAssertions;
-using System;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Threading.Tasks;
-using Timeline.Models.Http;
-
-namespace Timeline.Tests.Helpers
-{
- public static class CacheTestHelper
- {
- public static async Task TestCache(HttpClient client, string getUrl)
- {
- EntityTagHeaderValue eTag;
- {
- var res = await client.GetAsync(getUrl);
- res.Should().HaveStatusCode(200);
- var cacheControlHeader = res.Headers.CacheControl;
- cacheControlHeader.NoCache.Should().BeTrue();
- cacheControlHeader.NoStore.Should().BeFalse();
- cacheControlHeader.Private.Should().BeTrue();
- cacheControlHeader.Public.Should().BeFalse();
- cacheControlHeader.MustRevalidate.Should().BeTrue();
- cacheControlHeader.MaxAge.Should().NotBeNull().And.Be(TimeSpan.FromDays(14));
- eTag = res.Headers.ETag;
- }
-
- {
- using var request = new HttpRequestMessage()
- {
- RequestUri = new Uri(client.BaseAddress, getUrl),
- Method = HttpMethod.Get,
- };
- request.Headers.TryAddWithoutValidation("If-None-Match", "\"dsdfd");
- var res = await client.SendAsync(request);
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody(ErrorCodes.Common.Header.IfNonMatch_BadFormat);
- }
-
- {
- using var request = new HttpRequestMessage()
- {
- RequestUri = new Uri(client.BaseAddress, getUrl),
- Method = HttpMethod.Get,
- };
- request.Headers.TryAddWithoutValidation("If-None-Match", "\"aaa\"");
- var res = await client.SendAsync(request);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
-
- {
- using var request = new HttpRequestMessage()
- {
- RequestUri = new Uri(client.BaseAddress, getUrl),
- Method = HttpMethod.Get,
- };
- request.Headers.Add("If-None-Match", eTag.ToString());
- var res = await client.SendAsync(request);
- res.Should().HaveStatusCode(HttpStatusCode.NotModified);
- }
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/HttpClientExtensions.cs b/Timeline.Tests/Helpers/HttpClientExtensions.cs
deleted file mode 100644
index 6513bbe7..00000000
--- a/Timeline.Tests/Helpers/HttpClientExtensions.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Net.Mime;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Timeline.Tests.Helpers
-{
- public static class HttpClientExtensions
- {
- public static Task<HttpResponseMessage> PatchAsJsonAsync<T>(this HttpClient client, string url, T body)
- {
- return client.PatchAsJsonAsync(new Uri(url, UriKind.RelativeOrAbsolute), body);
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
- public static Task<HttpResponseMessage> PatchAsJsonAsync<T>(this HttpClient client, Uri url, T body)
- {
- return client.PatchAsync(url, new StringContent(
- JsonConvert.SerializeObject(body), Encoding.UTF8, MediaTypeNames.Application.Json));
- }
-
- public static Task<HttpResponseMessage> PutByteArrayAsync(this HttpClient client, string url, byte[] body, string mimeType)
- {
- return client.PutByteArrayAsync(new Uri(url, UriKind.RelativeOrAbsolute), body, mimeType);
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
- public static Task<HttpResponseMessage> PutByteArrayAsync(this HttpClient client, Uri url, byte[] body, string mimeType)
- {
- var content = new ByteArrayContent(body);
- content.Headers.ContentLength = body.Length;
- content.Headers.ContentType = new MediaTypeHeaderValue(mimeType);
- return client.PutAsync(url, content);
- }
-
- public static Task<HttpResponseMessage> PutStringAsync(this HttpClient client, string url, string body, string mimeType = null)
- {
- return client.PutStringAsync(new Uri(url, UriKind.RelativeOrAbsolute), body, mimeType);
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
- public static Task<HttpResponseMessage> PutStringAsync(this HttpClient client, Uri url, string body, string mimeType = null)
- {
- var content = new StringContent(body, Encoding.UTF8, mimeType ?? MediaTypeNames.Text.Plain);
- return client.PutAsync(url, content);
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/HttpResponseExtensions.cs b/Timeline.Tests/Helpers/HttpResponseExtensions.cs
deleted file mode 100644
index 2bd497f1..00000000
--- a/Timeline.Tests/Helpers/HttpResponseExtensions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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/Helpers/ImageHelper.cs b/Timeline.Tests/Helpers/ImageHelper.cs
deleted file mode 100644
index 9bed0917..00000000
--- a/Timeline.Tests/Helpers/ImageHelper.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Formats;
-using SixLabors.ImageSharp.PixelFormats;
-using System.IO;
-
-namespace Timeline.Tests.Helpers
-{
- public static class ImageHelper
- {
- public static byte[] CreatePngWithSize(int width, int height)
- {
- using var image = new Image<Rgba32>(width, height);
- using var stream = new MemoryStream();
- image.SaveAsPng(stream);
- return stream.ToArray();
- }
-
- public static byte[] CreateImageWithSize(int width, int height, IImageFormat format)
- {
- using var image = new Image<Rgba32>(width, height);
- using var stream = new MemoryStream();
- image.Save(stream, format);
- return stream.ToArray();
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/ParameterInfoAssertions.cs b/Timeline.Tests/Helpers/ParameterInfoAssertions.cs
deleted file mode 100644
index d3e5a41e..00000000
--- a/Timeline.Tests/Helpers/ParameterInfoAssertions.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using FluentAssertions;
-using FluentAssertions.Execution;
-using FluentAssertions.Formatting;
-using FluentAssertions.Primitives;
-using System;
-using System.Reflection;
-
-namespace Timeline.Tests.Helpers
-{
- public class ParameterInfoValueFormatter : IValueFormatter
- {
- public bool CanHandle(object value)
- {
- return value is ParameterInfo;
- }
-
- public string Format(object value, FormattingContext context, FormatChild formatChild)
- {
- var param = (ParameterInfo)value;
- return $"{param.Member.DeclaringType.FullName}.{param.Member.Name}#{param.Name}";
- }
- }
-
- public class ParameterInfoAssertions : ReferenceTypeAssertions<ParameterInfo, ParameterInfoAssertions>
- {
- static ParameterInfoAssertions()
- {
- Formatter.AddFormatter(new ParameterInfoValueFormatter());
- }
-
- public ParameterInfoAssertions(ParameterInfo parameterInfo)
- {
- Subject = parameterInfo;
- }
-
- protected override string Identifier => "parameter";
-
- public AndWhichConstraint<ParameterInfoAssertions, TAttribute> BeDecoratedWith<TAttribute>(string because = "", params object[] becauseArgs)
- where TAttribute : Attribute
- {
- var attribute = Subject.GetCustomAttribute<TAttribute>(false);
-
- Execute.Assertion
- .BecauseOf(because, becauseArgs)
- .ForCondition(attribute != null)
- .FailWith("Expected {0} {1} to be decorated with {2}{reason}, but that attribute was not found.",
- Identifier, Subject, typeof(TAttribute).FullName);
-
- return new AndWhichConstraint<ParameterInfoAssertions, TAttribute>(this, attribute);
- }
- }
-
- public static class ParameterInfoAssertionExtensions
- {
- public static ParameterInfoAssertions Should(this ParameterInfo parameterInfo)
- {
- return new ParameterInfoAssertions(parameterInfo);
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/ReflectionHelper.cs b/Timeline.Tests/Helpers/ReflectionHelper.cs
deleted file mode 100644
index 3f6036e3..00000000
--- a/Timeline.Tests/Helpers/ReflectionHelper.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Linq;
-using System.Reflection;
-
-namespace Timeline.Tests.Helpers
-{
- public static class ReflectionHelper
- {
- public static ParameterInfo GetParameter(this MethodInfo methodInfo, string name)
- {
- return methodInfo.GetParameters().Where(p => p.Name == name).Single();
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/ResponseAssertions.cs b/Timeline.Tests/Helpers/ResponseAssertions.cs
deleted file mode 100644
index 024732f5..00000000
--- a/Timeline.Tests/Helpers/ResponseAssertions.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-using FluentAssertions;
-using FluentAssertions.Execution;
-using FluentAssertions.Formatting;
-using FluentAssertions.Primitives;
-using System;
-using System.Globalization;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using Timeline.Models.Converters;
-using Timeline.Models.Http;
-
-namespace Timeline.Tests.Helpers
-{
- public class HttpResponseMessageValueFormatter : IValueFormatter
- {
- public bool CanHandle(object value)
- {
- return value is HttpResponseMessage;
- }
-
- public string Format(object value, FormattingContext context, FormatChild formatChild)
- {
- string newline = context.UseLineBreaks ? Environment.NewLine : "";
- string padding = new string('\t', context.Depth);
-
- var res = (HttpResponseMessage)value;
-
- var builder = new StringBuilder();
- builder.Append($"{newline}{padding} Status Code: {res.StatusCode} ; Body: ");
-
- try
- {
- var task = res.Content.ReadAsStringAsync();
- task.Wait();
- var body = task.Result;
- if (body.Length > 40)
- {
- body = body[0..40] + " ...";
- }
- builder.Append(body);
- }
- catch (AggregateException)
- {
- builder.Append("NOT A STRING.");
- }
-
- return builder.ToString();
- }
- }
-
- public class HttpResponseMessageAssertions
- : ReferenceTypeAssertions<HttpResponseMessage, HttpResponseMessageAssertions>
- {
- static HttpResponseMessageAssertions()
- {
- Formatter.AddFormatter(new HttpResponseMessageValueFormatter());
- }
-
- public HttpResponseMessageAssertions(HttpResponseMessage instance)
- {
- Subject = instance;
- }
-
- protected override string Identifier => "HttpResponseMessage";
-
- public AndConstraint<HttpResponseMessageAssertions> HaveStatusCode(int expected, string because = "", params object[] becauseArgs)
- {
- return HaveStatusCode((HttpStatusCode)expected, because, becauseArgs);
- }
-
- public AndConstraint<HttpResponseMessageAssertions> HaveStatusCode(HttpStatusCode expected, string because = "", params object[] becauseArgs)
- {
- Execute.Assertion.BecauseOf(because, becauseArgs)
- .ForCondition(Subject.StatusCode == expected)
- .FailWith("Expected status code of {context:HttpResponseMessage} to be {0}{reason}, but found {1}.", expected, Subject.StatusCode);
- return new AndConstraint<HttpResponseMessageAssertions>(this);
- }
-
- public AndWhichConstraint<HttpResponseMessageAssertions, T> HaveJsonBody<T>(string because = "", params object[] becauseArgs)
- {
- var a = Execute.Assertion.BecauseOf(because, becauseArgs);
- string body;
- try
- {
- var task = Subject.Content.ReadAsStringAsync();
- task.Wait();
- body = task.Result;
- }
- catch (AggregateException e)
- {
- a.FailWith("Expected response body of {context:HttpResponseMessage} to be json string{reason}, but failed to read it or it was not a string. Exception is {0}.", e.InnerExceptions);
- return new AndWhichConstraint<HttpResponseMessageAssertions, T>(this, null);
- }
-
-
- try
- {
- var options = new JsonSerializerOptions
- {
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase
- };
- options.Converters.Add(new JsonStringEnumConverter());
- options.Converters.Add(new JsonDateTimeConverter());
-
- var result = JsonSerializer.Deserialize<T>(body, options);
-
- return new AndWhichConstraint<HttpResponseMessageAssertions, T>(this, result);
- }
- catch (JsonException e)
- {
- a.FailWith("Expected response body of {context:HttpResponseMessage} to be json string{reason}, but failed to deserialize it. Exception is {0}.", e);
- return new AndWhichConstraint<HttpResponseMessageAssertions, T>(this, null);
- }
- }
- }
-
- public static class AssertionResponseExtensions
- {
- public static HttpResponseMessageAssertions Should(this HttpResponseMessage instance)
- {
- return new HttpResponseMessageAssertions(instance);
- }
-
- public static AndWhichConstraint<HttpResponseMessageAssertions, CommonResponse> HaveCommonBody(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs)
- {
- return assertions.HaveJsonBody<CommonResponse>(because, becauseArgs);
- }
-
- public static void HaveCommonBody(this HttpResponseMessageAssertions assertions, int code, string message = null, params object[] messageArgs)
- {
- message = string.IsNullOrEmpty(message) ? "" : ", " + string.Format(CultureInfo.CurrentCulture, message, messageArgs);
- var body = assertions.HaveCommonBody("Response body should be CommonResponse{0}", message).Which;
- body.Code.Should().Be(code, "Response body code is not the specified one{0}", message);
- }
-
- public static AndWhichConstraint<HttpResponseMessageAssertions, CommonDataResponse<TData>> HaveCommonDataBody<TData>(this HttpResponseMessageAssertions assertions, string because = "", params object[] becauseArgs)
- {
- return assertions.HaveJsonBody<CommonDataResponse<TData>>(because, becauseArgs);
- }
-
- public static void BePut(this HttpResponseMessageAssertions assertions, bool create, string because = "", params object[] becauseArgs)
- {
- var body = assertions.HaveStatusCode(create ? 201 : 200, because, becauseArgs)
- .And.HaveJsonBody<CommonPutResponse>(because, becauseArgs)
- .Which;
- body.Code.Should().Be(0);
- body.Data.Create.Should().Be(create);
- }
-
- public static void BeDelete(this HttpResponseMessageAssertions assertions, bool delete, string because = "", params object[] becauseArgs)
- {
- var body = assertions.HaveStatusCode(200, because, becauseArgs)
- .And.HaveJsonBody<CommonDeleteResponse>(because, becauseArgs)
- .Which;
- body.Code.Should().Be(0);
- body.Data.Delete.Should().Be(delete);
- }
-
- public static void BeInvalidModel(this HttpResponseMessageAssertions assertions, string message = null)
- {
- message = string.IsNullOrEmpty(message) ? "" : ", " + message;
- assertions.HaveStatusCode(400, "Invalid Model Error must have 400 status code{0}", message)
- .And.HaveCommonBody("Invalid Model Error must have CommonResponse body{0}", message)
- .Which.Code.Should().Be(ErrorCodes.Common.InvalidModel,
- "Invalid Model Error must have code {0} in body{1}",
- ErrorCodes.Common.InvalidModel, message);
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/TestApplication.cs b/Timeline.Tests/Helpers/TestApplication.cs
deleted file mode 100644
index 684ffe2c..00000000
--- a/Timeline.Tests/Helpers/TestApplication.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.TestHost;
-using Microsoft.Data.Sqlite;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-using Timeline.Configs;
-using Timeline.Entities;
-using Xunit;
-
-namespace Timeline.Tests.Helpers
-{
- public class TestApplication : IAsyncLifetime
- {
- public TestDatabase Database { get; }
-
- public IHost Host { get; private set; }
-
- public string WorkDir { get; private set; }
-
- public TestApplication()
- {
- Database = new TestDatabase(false);
- }
-
- public async Task InitializeAsync()
- {
- await Database.InitializeAsync();
-
- WorkDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
- Directory.CreateDirectory(WorkDir);
-
- Host = await Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder()
- .ConfigureAppConfiguration((context, config) =>
- {
- config.AddInMemoryCollection(new Dictionary<string, string>
- {
- [ApplicationConfiguration.UseMockFrontEndKey] = "true",
- ["WorkDir"] = WorkDir
- });
- })
- .ConfigureServices(services =>
- {
- services.AddDbContext<DatabaseContext>(options =>
- {
- options.UseSqlite(Database.Connection);
- });
- })
- .ConfigureWebHost(webBuilder =>
- {
- webBuilder
- .UseTestServer()
- .UseStartup<Startup>();
- })
- .StartAsync();
- }
-
- public async Task DisposeAsync()
- {
- await Host.StopAsync();
- Host.Dispose();
-
- Directory.Delete(WorkDir, true);
-
- await Database.DisposeAsync();
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/TestClock.cs b/Timeline.Tests/Helpers/TestClock.cs
deleted file mode 100644
index 34adb245..00000000
--- a/Timeline.Tests/Helpers/TestClock.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Timeline.Services;
-
-namespace Timeline.Tests.Helpers
-{
- public class TestClock : IClock
- {
- private DateTime? _currentTime;
-
- public DateTime GetCurrentTime()
- {
- return _currentTime ?? DateTime.UtcNow;
- }
-
- public void SetCurrentTime(DateTime? mockTime)
- {
- _currentTime = mockTime;
- }
-
- public DateTime SetMockCurrentTime()
- {
- var time = new DateTime(3000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
- _currentTime = time;
- return time;
- }
-
- public DateTime ForwardCurrentTime()
- {
- return ForwardCurrentTime(TimeSpan.FromDays(1));
- }
-
- public DateTime ForwardCurrentTime(TimeSpan timeSpan)
- {
- if (_currentTime == null)
- return SetMockCurrentTime();
- _currentTime += timeSpan;
- return _currentTime.Value;
- }
- }
-}
diff --git a/Timeline.Tests/Helpers/TestDatabase.cs b/Timeline.Tests/Helpers/TestDatabase.cs
deleted file mode 100644
index f0c26180..00000000
--- a/Timeline.Tests/Helpers/TestDatabase.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using Microsoft.Data.Sqlite;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging.Abstractions;
-using System.Threading.Tasks;
-using Timeline.Entities;
-using Timeline.Migrations;
-using Timeline.Models;
-using Timeline.Services;
-using Xunit;
-
-namespace Timeline.Tests.Helpers
-{
- public class TestDatabase : IAsyncLifetime
- {
- private readonly bool _createUser;
-
- public TestDatabase(bool createUser = true)
- {
- _createUser = createUser;
- Connection = new SqliteConnection("Data Source=:memory:;");
- }
-
- public async Task InitializeAsync()
- {
- await Connection.OpenAsync();
-
- using (var context = CreateContext())
- {
- await context.Database.EnsureCreatedAsync();
- context.JwtToken.Add(new JwtTokenEntity
- {
- Key = JwtTokenGenerateHelper.GenerateKey()
- });
- await context.SaveChangesAsync();
-
- if (_createUser)
- {
- var passwordService = new PasswordService();
- var userService = new UserService(NullLogger<UserService>.Instance, context, passwordService, new Clock());
-
- await userService.CreateUser(new User
- {
- Username = "admin",
- Password = "adminpw",
- Administrator = true,
- Nickname = "administrator"
- });
-
- await userService.CreateUser(new User
- {
- Username = "user",
- Password = "userpw",
- Administrator = false,
- Nickname = "imuser"
- });
- }
- }
- }
-
- public async Task DisposeAsync()
- {
- await Connection.CloseAsync();
- await Connection.DisposeAsync();
- }
-
- public SqliteConnection Connection { get; }
-
- public DatabaseContext CreateContext()
- {
- var options = new DbContextOptionsBuilder<DatabaseContext>()
- .UseSqlite(Connection).Options;
-
- return new DatabaseContext(options);
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/AuthorizationTest.cs b/Timeline.Tests/IntegratedTests/AuthorizationTest.cs
deleted file mode 100644
index 38071394..00000000
--- a/Timeline.Tests/IntegratedTests/AuthorizationTest.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using FluentAssertions;
-using System.Net;
-using System.Threading.Tasks;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class AuthorizationTest : IntegratedTestBase
- {
- private const string BaseUrl = "testing/auth/";
- private const string AuthorizeUrl = BaseUrl + "Authorize";
- private const string UserUrl = BaseUrl + "User";
- private const string AdminUrl = BaseUrl + "Admin";
-
- [Fact]
- public async Task UnauthenticationTest()
- {
- using var client = await CreateDefaultClient();
- var response = await client.GetAsync(AuthorizeUrl);
- response.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
-
- [Fact]
- public async Task AuthenticationTest()
- {
- using var client = await CreateClientAsUser();
- var response = await client.GetAsync(AuthorizeUrl);
- response.Should().HaveStatusCode(HttpStatusCode.OK);
- }
-
- [Fact]
- public async Task UserAuthorizationTest()
- {
- using var client = await CreateClientAsUser();
- var response1 = await client.GetAsync(UserUrl);
- response1.Should().HaveStatusCode(HttpStatusCode.OK);
- var response2 = await client.GetAsync(AdminUrl);
- response2.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- [Fact]
- public async Task AdminAuthorizationTest()
- {
- using var client = await CreateClientAsAdministrator();
- var response1 = await client.GetAsync(UserUrl);
- response1.Should().HaveStatusCode(HttpStatusCode.OK);
- var response2 = await client.GetAsync(AdminUrl);
- response2.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/FrontEndTest.cs b/Timeline.Tests/IntegratedTests/FrontEndTest.cs
deleted file mode 100644
index 39a6e545..00000000
--- a/Timeline.Tests/IntegratedTests/FrontEndTest.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using FluentAssertions;
-using System.Net.Mime;
-using System.Threading.Tasks;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class FrontEndTest : IntegratedTestBase
- {
- [Fact]
- public async Task Index()
- {
- using var client = await CreateDefaultClient(false);
- var res = await client.GetAsync("index.html");
- res.Should().HaveStatusCode(200);
- res.Content.Headers.ContentType.MediaType.Should().Be(MediaTypeNames.Text.Html);
- }
-
- [Fact]
- public async Task Fallback()
- {
- using var client = await CreateDefaultClient(false);
- var res = await client.GetAsync("aaaaaaaaaaaaaaa");
- res.Should().HaveStatusCode(200);
- res.Content.Headers.ContentType.MediaType.Should().Be(MediaTypeNames.Text.Html);
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs b/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
deleted file mode 100644
index 7cf27297..00000000
--- a/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
+++ /dev/null
@@ -1,164 +0,0 @@
-using FluentAssertions;
-using Microsoft.AspNetCore.TestHost;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Threading.Tasks;
-using Timeline.Models;
-using Timeline.Models.Converters;
-using Timeline.Models.Http;
-using Timeline.Services;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public abstract class IntegratedTestBase : IAsyncLifetime
- {
- protected TestApplication TestApp { get; }
-
- public IReadOnlyList<UserInfo> UserInfos { get; private set; }
-
- private readonly int _userCount;
-
- public IntegratedTestBase() : this(1)
- {
-
- }
-
- public IntegratedTestBase(int userCount)
- {
- if (userCount < 0)
- throw new ArgumentOutOfRangeException(nameof(userCount), userCount, "User count can't be negative.");
-
- _userCount = userCount;
-
- TestApp = new TestApplication();
- }
-
- protected virtual Task OnInitializeAsync()
- {
- return Task.CompletedTask;
- }
-
- protected virtual Task OnDisposeAsync()
- {
- return Task.CompletedTask;
- }
-
- protected virtual void OnDispose()
- {
-
- }
-
- public async Task InitializeAsync()
- {
- await TestApp.InitializeAsync();
-
- using (var scope = TestApp.Host.Services.CreateScope())
- {
- var users = new List<User>()
- {
- new User
- {
- Username = "admin",
- Password = "adminpw",
- Administrator = true,
- Nickname = "administrator"
- }
- };
-
- for (int i = 1; i <= _userCount; i++)
- {
- users.Add(new User
- {
- Username = $"user{i}",
- Password = $"user{i}pw",
- Administrator = false,
- Nickname = $"imuser{i}"
- });
- }
-
- var userInfoList = new List<UserInfo>();
-
- var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
- foreach (var user in users)
- {
- await userService.CreateUser(user);
- }
-
- using var client = await CreateDefaultClient();
- var options = new JsonSerializerOptions
- {
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase
- };
- options.Converters.Add(new JsonStringEnumConverter());
- options.Converters.Add(new JsonDateTimeConverter());
- foreach (var user in users)
- {
- var s = await client.GetStringAsync($"users/{user.Username}");
- userInfoList.Add(JsonSerializer.Deserialize<UserInfo>(s, options));
- }
-
- UserInfos = userInfoList;
- }
-
- await OnInitializeAsync();
- }
-
- public async Task DisposeAsync()
- {
- await OnDisposeAsync();
- OnDispose();
- await TestApp.DisposeAsync();
- }
-
- public Task<HttpClient> CreateDefaultClient(bool setApiBase = true)
- {
- var client = TestApp.Host.GetTestServer().CreateClient();
- if (setApiBase)
- {
- client.BaseAddress = new Uri(client.BaseAddress, "api/");
- }
- return Task.FromResult(client);
- }
-
- public async Task<HttpClient> CreateClientWithCredential(string username, string password, bool setApiBase = true)
- {
- var client = TestApp.Host.GetTestServer().CreateClient();
- if (setApiBase)
- {
- client.BaseAddress = new Uri(client.BaseAddress, "api/");
- }
- var response = await client.PostAsJsonAsync("token/create",
- new CreateTokenRequest { Username = username, Password = password });
- var token = response.Should().HaveStatusCode(200)
- .And.HaveJsonBody<CreateTokenResponse>().Which.Token;
- client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
- return client;
- }
-
- public Task<HttpClient> CreateClientAs(int userNumber, bool setApiBase = true)
- {
- if (userNumber < 0)
- return CreateDefaultClient(setApiBase);
- if (userNumber == 0)
- return CreateClientWithCredential("admin", "adminpw", setApiBase);
- else
- return CreateClientWithCredential($"user{userNumber}", $"user{userNumber}pw", setApiBase);
- }
-
- public Task<HttpClient> CreateClientAsAdministrator(bool setApiBase = true)
- {
- return CreateClientAs(0, setApiBase);
- }
-
- public Task<HttpClient> CreateClientAsUser(bool setApiBase = true)
- {
- return CreateClientAs(1, setApiBase);
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/TimelineTest.cs b/Timeline.Tests/IntegratedTests/TimelineTest.cs
deleted file mode 100644
index ec46b96a..00000000
--- a/Timeline.Tests/IntegratedTests/TimelineTest.cs
+++ /dev/null
@@ -1,1523 +0,0 @@
-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.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using Timeline.Entities;
-using Timeline.Models;
-using Timeline.Models.Http;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public static class TimelineHelper
- {
- public static TimelinePostContentInfo TextPostContent(string text)
- {
- return new TimelinePostContentInfo
- {
- Type = "text",
- Text = text
- };
- }
-
- public static TimelinePostCreateRequest TextPostCreateRequest(string text, DateTime? time = null)
- {
- return new TimelinePostCreateRequest
- {
- Content = new TimelinePostCreateRequestContent
- {
- Type = "text",
- Text = text
- },
- Time = time
- };
- }
- }
-
- public class TimelineTest : IntegratedTestBase
- {
- public TimelineTest() : base(3)
- {
- }
-
- protected override async Task OnInitializeAsync()
- {
- await CreateTestTimelines();
- }
-
- private List<TimelineInfo> _testTimelines;
-
- private async Task CreateTestTimelines()
- {
- _testTimelines = new List<TimelineInfo>();
- for (int i = 0; i <= 3; i++)
- {
- var client = await CreateClientAs(i);
- var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = $"t{i}" });
- var timelineInfo = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- _testTimelines.Add(timelineInfo);
- }
- }
-
- private static string CalculateUrlTail(string subpath, ICollection<KeyValuePair<string, string>> query)
- {
- StringBuilder result = new StringBuilder();
- if (subpath != null)
- {
- if (!subpath.StartsWith("/", StringComparison.OrdinalIgnoreCase))
- result.Append('/');
- result.Append(subpath);
- }
-
- if (query != null && query.Count != 0)
- {
- result.Append('?');
- foreach (var (key, value, index) in query.Select((pair, index) => (pair.Key, pair.Value, index)))
- {
- result.Append(WebUtility.UrlEncode(key));
- result.Append('=');
- result.Append(WebUtility.UrlEncode(value));
- if (index != query.Count - 1)
- result.Append('&');
- }
- }
-
- return result.ToString();
- }
-
- private static string GeneratePersonalTimelineUrl(int id, string subpath = null, ICollection<KeyValuePair<string, string>> query = null)
- {
- return $"timelines/@{(id == 0 ? "admin" : ("user" + id))}{CalculateUrlTail(subpath, query)}";
- }
-
- private static string GenerateOrdinaryTimelineUrl(int id, string subpath = null, ICollection<KeyValuePair<string, string>> query = null)
- {
- return $"timelines/t{id}{CalculateUrlTail(subpath, query)}";
- }
-
- public delegate string TimelineUrlGenerator(int userId, string subpath = null, ICollection<KeyValuePair<string, string>> query = null);
-
- public static IEnumerable<object[]> TimelineUrlGeneratorData()
- {
- yield return new[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl) };
- yield return new[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl) };
- }
-
- private static string GeneratePersonalTimelineUrlByName(string name, string subpath = null)
- {
- return $"timelines/@{name}{(subpath == null ? "" : "/" + subpath)}";
- }
-
- private static string GenerateOrdinaryTimelineUrlByName(string name, string subpath = null)
- {
- return $"timelines/{name}{(subpath == null ? "" : "/" + subpath)}";
- }
-
- public static IEnumerable<object[]> TimelineUrlByNameGeneratorData()
- {
- yield return new[] { new Func<string, string, string>(GeneratePersonalTimelineUrlByName) };
- yield return new[] { new Func<string, string, string>(GenerateOrdinaryTimelineUrlByName) };
- }
-
- [Fact]
- public async Task TimelineGet_Should_Work()
- {
- using var client = await CreateDefaultClient();
- {
- var res = await client.GetAsync("timelines/@user1");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- body.Owner.Should().BeEquivalentTo(UserInfos[1]);
- body.Visibility.Should().Be(TimelineVisibility.Register);
- body.Description.Should().Be("");
- body.Members.Should().NotBeNull().And.BeEmpty();
- var links = body._links;
- links.Should().NotBeNull();
- links.Self.Should().EndWith("timelines/@user1");
- links.Posts.Should().EndWith("timelines/@user1/posts");
- }
-
- {
- var res = await client.GetAsync("timelines/t1");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- body.Owner.Should().BeEquivalentTo(UserInfos[1]);
- body.Visibility.Should().Be(TimelineVisibility.Register);
- body.Description.Should().Be("");
- body.Members.Should().NotBeNull().And.BeEmpty();
- var links = body._links;
- links.Should().NotBeNull();
- links.Self.Should().EndWith("timelines/t1");
- links.Posts.Should().EndWith("timelines/t1/posts");
- }
- }
-
- [Fact]
- public async Task TimelineList()
- {
- TimelineInfo user1Timeline;
-
- var client = await CreateDefaultClient();
-
- {
- var res = await client.GetAsync("timelines/@user1");
- user1Timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- }
-
- {
- var testResult = new List<TimelineInfo>();
- testResult.Add(user1Timeline);
- testResult.AddRange(_testTimelines);
-
- var res = await client.GetAsync("timelines");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which.Should().BeEquivalentTo(testResult);
- }
- }
-
- [Fact]
- public async Task TimelineList_WithQuery()
- {
- var testResultRelate = new List<TimelineInfo>();
- var testResultOwn = new List<TimelineInfo>();
- var testResultJoin = new List<TimelineInfo>();
- var testResultOwnPrivate = new List<TimelineInfo>();
- var testResultRelatePublic = new List<TimelineInfo>();
- var testResultRelateRegister = new List<TimelineInfo>();
- var testResultJoinPrivate = new List<TimelineInfo>();
- var testResultPublic = new List<TimelineInfo>();
-
- {
- var client = await CreateClientAsUser();
-
- {
- var res = await client.PutAsync("timelines/@user1/members/user3", null);
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PutAsync("timelines/t1/members/user3", null);
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PatchAsJsonAsync("timelines/@user1", new TimelinePatchRequest { Visibility = TimelineVisibility.Public });
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PatchAsJsonAsync("timelines/t1", new TimelinePatchRequest { Visibility = TimelineVisibility.Register });
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.GetAsync("timelines/@user1");
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- testResultRelate.Add(timeline);
- testResultJoin.Add(timeline);
- testResultRelatePublic.Add(timeline);
- testResultPublic.Add(timeline);
- }
-
- {
- var res = await client.GetAsync("timelines/t1");
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- testResultRelate.Add(timeline);
- testResultJoin.Add(timeline);
- testResultRelateRegister.Add(timeline);
- }
- }
-
- {
- var client = await CreateClientAs(2);
-
- {
- var res = await client.PutAsync("timelines/@user2/members/user3", null);
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PutAsync("timelines/t2/members/user3", null);
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PatchAsJsonAsync("timelines/@user2", new TimelinePatchRequest { Visibility = TimelineVisibility.Register });
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PatchAsJsonAsync("timelines/t2", new TimelinePatchRequest { Visibility = TimelineVisibility.Private });
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.GetAsync("timelines/@user2");
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- testResultRelate.Add(timeline);
- testResultJoin.Add(timeline);
- testResultRelateRegister.Add(timeline);
- }
-
- {
- var res = await client.GetAsync("timelines/t2");
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- testResultRelate.Add(timeline);
- testResultJoin.Add(timeline);
- testResultJoinPrivate.Add(timeline);
- }
- }
-
- {
- var client = await CreateClientAs(3);
-
- {
- var res = await client.PatchAsJsonAsync("timelines/@user3", new TimelinePatchRequest { Visibility = TimelineVisibility.Private });
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PatchAsJsonAsync("timelines/t3", new TimelinePatchRequest { Visibility = TimelineVisibility.Register });
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.GetAsync("timelines/@user3");
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- testResultRelate.Add(timeline);
- testResultOwn.Add(timeline);
- testResultOwnPrivate.Add(timeline);
- }
-
- {
- var res = await client.GetAsync("timelines/t3");
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- testResultRelate.Add(timeline);
- testResultOwn.Add(timeline);
- testResultRelateRegister.Add(timeline);
- }
- }
-
- {
- var client = await CreateClientAs(3);
- {
- var res = await client.GetAsync("timelines?relate=user3");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultRelate);
- }
-
- {
- var res = await client.GetAsync("timelines?relate=user3&relateType=own");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultOwn);
- }
-
- {
- var res = await client.GetAsync("timelines?relate=user3&visibility=public");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultRelatePublic);
- }
-
- {
- var res = await client.GetAsync("timelines?relate=user3&visibility=register");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultRelateRegister);
- }
-
- {
- var res = await client.GetAsync("timelines?relate=user3&relateType=join&visibility=private");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultJoinPrivate);
- }
-
- {
- var res = await client.GetAsync("timelines?relate=user3&relateType=own&visibility=private");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultOwnPrivate);
- }
- }
-
- {
- var client = await CreateDefaultClient();
- {
- var res = await client.GetAsync("timelines?visibility=public");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelineInfo>>()
- .Which;
- body.Should().BeEquivalentTo(testResultPublic);
- }
- }
- }
-
- [Fact]
- public async Task TimelineList_InvalidModel()
- {
- var client = await CreateClientAsUser();
-
- {
- var res = await client.GetAsync("timelines?relate=us!!");
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.GetAsync("timelines?relateType=aaa");
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.GetAsync("timelines?visibility=aaa");
- res.Should().BeInvalidModel();
- }
- }
-
- [Fact]
- public async Task TimelineCreate_Should_Work()
- {
- {
- using var client = await CreateDefaultClient();
- var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "aaa" });
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
-
- using (var client = await CreateClientAsUser())
- {
- {
- var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "!!!" });
- res.Should().BeInvalidModel();
- }
-
- TimelineInfo timelineInfo;
- {
- var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "aaa" });
- timelineInfo = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- }
-
- {
- var res = await client.GetAsync("timelines/aaa");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Should().BeEquivalentTo(timelineInfo);
- }
-
- {
- var res = await client.PostAsJsonAsync("timelines", new TimelineCreateRequest { Name = "aaa" });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody(ErrorCodes.TimelineController.NameConflict);
- }
- }
- }
-
- [Fact]
- public async Task TimelineDelete_Should_Work()
- {
- {
- using var client = await CreateDefaultClient();
- var res = await client.DeleteAsync("timelines/t1");
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
-
- {
- using var client = await CreateClientAs(2);
- var res = await client.DeleteAsync("timelines/t1");
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- {
- using var client = await CreateClientAsAdministrator();
-
- {
- var res = await client.DeleteAsync("timelines/!!!");
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.DeleteAsync("timelines/t2");
- res.Should().BeDelete(true);
- }
-
- {
- var res = await client.DeleteAsync("timelines/t2");
- res.Should().BeDelete(false);
- }
- }
-
- {
- using var client = await CreateClientAs(1);
-
- {
- var res = await client.DeleteAsync("timelines/!!!");
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.DeleteAsync("timelines/t1");
- res.Should().BeDelete(true);
- }
-
- {
- var res = await client.DeleteAsync("timelines/t1");
- res.Should().HaveStatusCode(400);
- }
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlByNameGeneratorData))]
- public async Task InvalidModel_BadName(Func<string, string, string> generator)
- {
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.GetAsync(generator("aaa!!!", null));
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.PatchAsJsonAsync(generator("aaa!!!", null), new TimelinePatchRequest { });
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.PutAsync(generator("aaa!!!", "members/user1"), null);
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.DeleteAsync(generator("aaa!!!", "members/user1"));
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.GetAsync(generator("aaa!!!", "posts"));
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.PostAsJsonAsync(generator("aaa!!!", "posts"), TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.DeleteAsync(generator("aaa!!!", "posts/123"));
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.GetAsync(generator("aaa!!!", "posts/123/data"));
- res.Should().BeInvalidModel();
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlByNameGeneratorData))]
- public async Task Ordinary_NotFound(Func<string, string, string> generator)
- {
- var errorCode = generator == GenerateOrdinaryTimelineUrlByName ? ErrorCodes.TimelineController.NotExist : ErrorCodes.UserCommon.NotExist;
-
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.GetAsync(generator("notexist", null));
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.PatchAsJsonAsync(generator("notexist", null), new TimelinePatchRequest { });
- res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.PutAsync(generator("notexist", "members/user1"), null);
- res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.DeleteAsync(generator("notexist", "members/user1"));
- res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.GetAsync(generator("notexist", "posts"));
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.PostAsJsonAsync(generator("notexist", "posts"), TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.DeleteAsync(generator("notexist", "posts/123"));
- res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
- }
- {
- var res = await client.GetAsync(generator("notexist", "posts/123/data"));
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Description_Should_Work(TimelineUrlGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- async Task AssertDescription(string description)
- {
- var res = await client.GetAsync(generator(1, null));
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Description.Should().Be(description);
- }
-
- const string mockDescription = "haha";
-
- await AssertDescription("");
- {
- var res = await client.PatchAsJsonAsync(generator(1, null),
- new TimelinePatchRequest { Description = mockDescription });
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which.Description.Should().Be(mockDescription);
- await AssertDescription(mockDescription);
- }
- {
- var res = await client.PatchAsJsonAsync(generator(1, null),
- new TimelinePatchRequest { Description = null });
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which.Description.Should().Be(mockDescription);
- await AssertDescription(mockDescription);
- }
- {
- var res = await client.PatchAsJsonAsync(generator(1, null),
- new TimelinePatchRequest { Description = "" });
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which.Description.Should().Be("");
- await AssertDescription("");
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Member_Should_Work(TimelineUrlGenerator generator)
- {
- var getUrl = generator(1, null);
- using var client = await CreateClientAsUser();
-
- async Task AssertMembers(IList<UserInfo> members)
- {
- var res = await client.GetAsync(getUrl);
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Members.Should().NotBeNull().And.BeEquivalentTo(members);
- }
-
- async Task AssertEmptyMembers()
- {
- var res = await client.GetAsync(getUrl);
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Members.Should().NotBeNull().And.BeEmpty();
- }
-
- await AssertEmptyMembers();
- {
- var res = await client.PutAsync(generator(1, "members/usernotexist"), null);
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody(ErrorCodes.TimelineController.MemberPut_NotExist);
- }
- await AssertEmptyMembers();
- {
- var res = await client.PutAsync(generator(1, "members/user2"), null);
- res.Should().HaveStatusCode(200);
- }
- await AssertMembers(new List<UserInfo> { UserInfos[2] });
- {
- var res = await client.DeleteAsync(generator(1, "members/user2"));
- res.Should().BeDelete(true);
- }
- await AssertEmptyMembers();
- {
- var res = await client.DeleteAsync(generator(1, "members/aaa"));
- res.Should().BeDelete(false);
- }
- await AssertEmptyMembers();
- }
-
- public static IEnumerable<object[]> Permission_Timeline_Data()
- {
- yield return new object[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl), -1, 200, 401, 401, 401, 401 };
- yield return new object[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl), 1, 200, 200, 403, 200, 403 };
- yield return new object[] { new TimelineUrlGenerator(GenerateOrdinaryTimelineUrl), 0, 200, 200, 200, 200, 200 };
- yield return new object[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl), -1, 200, 401, 401, 401, 401 };
- yield return new object[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl), 1, 200, 200, 403, 200, 403 };
- yield return new object[] { new TimelineUrlGenerator(GeneratePersonalTimelineUrl), 0, 200, 200, 200, 200, 200 };
- }
-
- [Theory]
- [MemberData(nameof(Permission_Timeline_Data))]
- public async Task Permission_Timeline(TimelineUrlGenerator generator, int userNumber, int get, int opPatchUser, int opPatchAdmin, int opMemberUser, int opMemberAdmin)
- {
- using var client = await CreateClientAs(userNumber);
- {
- var res = await client.GetAsync("timelines/t1");
- res.Should().HaveStatusCode(get);
- }
-
- {
- var res = await client.PatchAsJsonAsync(generator(1, null), new TimelinePatchRequest { Description = "hahaha" });
- res.Should().HaveStatusCode(opPatchUser);
- }
-
- {
- var res = await client.PatchAsJsonAsync(generator(0, null), new TimelinePatchRequest { Description = "hahaha" });
- res.Should().HaveStatusCode(opPatchAdmin);
- }
-
- {
- var res = await client.PutAsync(generator(1, "members/user2"), null);
- res.Should().HaveStatusCode(opMemberUser);
- }
-
- {
- var res = await client.DeleteAsync(generator(1, "members/user2"));
- res.Should().HaveStatusCode(opMemberUser);
- }
-
- {
- var res = await client.PutAsync(generator(0, "members/user2"), null);
- res.Should().HaveStatusCode(opMemberAdmin);
- }
-
- {
- var res = await client.DeleteAsync(generator(0, "members/user2"));
- res.Should().HaveStatusCode(opMemberAdmin);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Visibility_Test(TimelineUrlGenerator generator)
- {
- var userUrl = generator(1, "posts");
- var adminUrl = generator(0, "posts");
- {
-
- using var client = await CreateClientAsUser();
- using var content = new StringContent(@"{""visibility"":""abcdefg""}", System.Text.Encoding.UTF8, System.Net.Mime.MediaTypeNames.Application.Json);
- var res = await client.PatchAsync(generator(1, null), content);
- res.Should().BeInvalidModel();
- }
- { // default visibility is registered
- {
- using var client = await CreateDefaultClient();
- var res = await client.GetAsync(userUrl);
- res.Should().HaveStatusCode(403);
- }
-
- {
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync(adminUrl);
- res.Should().HaveStatusCode(200);
- }
- }
-
- { // change visibility to public
- {
- using var client = await CreateClientAsUser();
- var res = await client.PatchAsJsonAsync(generator(1, null),
- new TimelinePatchRequest { Visibility = TimelineVisibility.Public });
- res.Should().HaveStatusCode(200);
- }
- {
- using var client = await CreateDefaultClient();
- var res = await client.GetAsync(userUrl);
- res.Should().HaveStatusCode(200);
- }
- }
-
- { // change visibility to private
- {
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.PatchAsJsonAsync(generator(1, null),
- new TimelinePatchRequest { Visibility = TimelineVisibility.Private });
- res.Should().HaveStatusCode(200);
- }
- {
- var res = await client.PatchAsJsonAsync(generator(0, null),
- new TimelinePatchRequest { Visibility = TimelineVisibility.Private });
- res.Should().HaveStatusCode(200);
- }
- }
- {
- using var client = await CreateDefaultClient();
- var res = await client.GetAsync(userUrl);
- res.Should().HaveStatusCode(403);
- }
- { // user can't read admin's
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync(adminUrl);
- res.Should().HaveStatusCode(403);
- }
- { // admin can read user's
- using var client = await CreateClientAsAdministrator();
- var res = await client.GetAsync(userUrl);
- res.Should().HaveStatusCode(200);
- }
- { // add member
- using var client = await CreateClientAsAdministrator();
- var res = await client.PutAsync(generator(0, "members/user1"), null);
- res.Should().HaveStatusCode(200);
- }
- { // now user can read admin's
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync(adminUrl);
- res.Should().HaveStatusCode(200);
- }
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Permission_Post_Create(TimelineUrlGenerator generator)
- {
- using (var client = await CreateClientAsUser())
- {
- var res = await client.PutAsync(generator(1, "members/user2"), null);
- res.Should().HaveStatusCode(200);
- }
-
- using (var client = await CreateDefaultClient())
- {
- { // no auth should get 401
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(401);
- }
- }
-
- using (var client = await CreateClientAsUser())
- {
- { // post self's
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(200);
- }
- { // post other not as a member should get 403
- var res = await client.PostAsJsonAsync(generator(0, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(403);
- }
- }
-
- using (var client = await CreateClientAsAdministrator())
- {
- { // post as admin
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(200);
- }
- }
-
- using (var client = await CreateClientAs(2))
- {
- { // post as member
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(200);
- }
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Permission_Post_Delete(TimelineUrlGenerator generator)
- {
- async Task<long> CreatePost(int userNumber)
- {
- using var client = await CreateClientAs(userNumber);
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- return res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>()
- .Which.Id;
- }
-
- using (var client = await CreateClientAsUser())
- {
- {
- var res = await client.PutAsync(generator(1, "members/user2"), null);
- res.Should().HaveStatusCode(200);
- }
- {
- var res = await client.PutAsync(generator(1, "members/user3"), null);
- res.Should().HaveStatusCode(200);
- }
- }
-
- { // no auth should get 401
- using var client = await CreateDefaultClient();
- var res = await client.DeleteAsync(generator(1, "posts/12"));
- res.Should().HaveStatusCode(401);
- }
-
- { // self can delete self
- var postId = await CreatePost(1);
- using var client = await CreateClientAsUser();
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().HaveStatusCode(200);
- }
-
- { // admin can delete any
- var postId = await CreatePost(1);
- using var client = await CreateClientAsAdministrator();
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().HaveStatusCode(200);
- }
-
- { // owner can delete other
- var postId = await CreatePost(2);
- using var client = await CreateClientAsUser();
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().HaveStatusCode(200);
- }
-
- { // author can delete self
- var postId = await CreatePost(2);
- using var client = await CreateClientAs(2);
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().HaveStatusCode(200);
- }
-
- { // otherwise is forbidden
- var postId = await CreatePost(2);
- using var client = await CreateClientAs(3);
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().HaveStatusCode(403);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task TextPost_ShouldWork(TimelineUrlGenerator generator)
- {
- {
- using var client = await CreateClientAsUser();
- {
- var res = await client.GetAsync(generator(1, "posts"));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEmpty();
- }
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest(null));
- res.Should().BeInvalidModel();
- }
- const string mockContent = "aaa";
- TimelinePostInfo createRes;
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest(mockContent));
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>()
- .Which;
- body.Should().NotBeNull();
- body.Content.Should().BeEquivalentTo(TimelineHelper.TextPostContent(mockContent));
- body.Author.Should().BeEquivalentTo(UserInfos[1]);
- body.Deleted.Should().BeFalse();
- createRes = body;
- }
- {
- var res = await client.GetAsync(generator(1, "posts"));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEquivalentTo(createRes);
- }
- const string mockContent2 = "bbb";
- var mockTime2 = DateTime.UtcNow.AddDays(-1);
- TimelinePostInfo createRes2;
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest(mockContent2, mockTime2));
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>()
- .Which;
- body.Should().NotBeNull();
- body.Content.Should().BeEquivalentTo(TimelineHelper.TextPostContent(mockContent2));
- body.Author.Should().BeEquivalentTo(UserInfos[1]);
- body.Time.Should().BeCloseTo(mockTime2, 1000);
- body.Deleted.Should().BeFalse();
- createRes2 = body;
- }
- {
- var res = await client.GetAsync(generator(1, "posts"));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEquivalentTo(createRes, createRes2);
- }
- {
- var res = await client.DeleteAsync(generator(1, $"posts/{createRes.Id}"));
- res.Should().BeDelete(true);
- }
- {
- var res = await client.DeleteAsync(generator(1, $"posts/{createRes.Id}"));
- res.Should().BeDelete(false);
- }
- {
- var res = await client.DeleteAsync(generator(1, "posts/30000"));
- res.Should().BeDelete(false);
- }
- {
- var res = await client.GetAsync(generator(1, "posts"));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEquivalentTo(createRes2);
- }
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task GetPost_Should_Ordered(TimelineUrlGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- async Task<long> CreatePost(DateTime time)
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa", time));
- return res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>()
- .Which.Id;
- }
-
- var now = DateTime.UtcNow;
- var id0 = await CreatePost(now.AddDays(1));
- var id1 = await CreatePost(now.AddDays(-1));
- var id2 = await CreatePost(now);
-
- {
- var res = await client.GetAsync(generator(1, "posts"));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Select(p => p.Id).Should().Equal(id1, id2, id0);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task CreatePost_InvalidModel(TimelineUrlGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = null });
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Type = null } });
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Type = "hahaha" } });
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Type = "text", Text = null } });
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Type = "image", Data = null } });
- res.Should().BeInvalidModel();
- }
-
- {
- // image not base64
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Type = "image", Data = "!!!" } });
- res.Should().BeInvalidModel();
- }
-
- {
- // image base64 not image
- var res = await client.PostAsJsonAsync(generator(1, "posts"), new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Type = "image", Data = Convert.ToBase64String(new byte[] { 0x01, 0x02, 0x03 }) } });
- res.Should().BeInvalidModel();
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task ImagePost_ShouldWork(TimelineUrlGenerator generator)
- {
- var imageData = ImageHelper.CreatePngWithSize(100, 200);
-
- long postId;
- string postImageUrl;
-
- void AssertPostContent(TimelinePostContentInfo content)
- {
- content.Type.Should().Be(TimelinePostContentTypes.Image);
- content.Url.Should().EndWith(generator(1, $"posts/{postId}/data"));
- content.Text.Should().Be(null);
- }
-
- using var client = await CreateClientAsUser();
-
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- new TimelinePostCreateRequest
- {
- Content = new TimelinePostCreateRequestContent
- {
- Type = TimelinePostContentTypes.Image,
- Data = Convert.ToBase64String(imageData)
- }
- });
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>().Which;
- postId = body.Id;
- postImageUrl = body.Content.Url;
- AssertPostContent(body.Content);
- }
-
- {
- var res = await client.GetAsync(generator(1, "posts"));
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>().Which;
- body.Should().HaveCount(1);
- var post = body[0];
- post.Id.Should().Be(postId);
- AssertPostContent(post.Content);
- }
-
- {
- var res = await client.GetAsync(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, generator(1, $"posts/{postId}/data"));
- }
-
- {
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().BeDelete(true);
- }
-
- {
- var res = await client.DeleteAsync(generator(1, $"posts/{postId}"));
- res.Should().BeDelete(false);
- }
-
- {
- var res = await client.GetAsync(generator(1, "posts"));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.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(TimelineUrlGeneratorData))]
- public async Task ImagePost_400(TimelineUrlGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- {
- var res = await client.GetAsync(generator(1, "posts/11234/data"));
- res.Should().HaveStatusCode(404)
- .And.HaveCommonBody(ErrorCodes.TimelineController.PostNotExist);
- }
-
- long postId;
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- TimelineHelper.TextPostCreateRequest("aaa"));
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>()
- .Which;
- postId = body.Id;
- }
-
- {
- var res = await client.GetAsync(generator(1, $"posts/{postId}/data"));
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody(ErrorCodes.TimelineController.PostNoData);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Timeline_LastModified(TimelineUrlGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- DateTime lastModified;
-
- {
- var res = await client.GetAsync(generator(1));
- lastModified = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.LastModified;
- }
-
- await Task.Delay(1000);
-
- {
- var res = await client.PatchAsJsonAsync(generator(1), new TimelinePatchRequest { Description = "123" });
- lastModified = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.LastModified.Should().BeAfter(lastModified).And.Subject.Value;
- }
-
- {
- var res = await client.GetAsync(generator(1));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.LastModified.Should().Be(lastModified);
- }
-
- await Task.Delay(1000);
-
- {
- var res = await client.PutAsync(generator(1, "members/user2"), null);
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.GetAsync(generator(1));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.LastModified.Should().BeAfter(lastModified);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Post_ModifiedSince(TimelineUrlGenerator generator)
- {
- using var client = await CreateClientAsUser();
-
- var postContentList = new List<string> { "a", "b", "c", "d" };
- var posts = new List<TimelinePostInfo>();
-
- foreach (var content in postContentList)
- {
- var res = await client.PostAsJsonAsync(generator(1, "posts"),
- new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Text = content, Type = TimelinePostContentTypes.Text } });
- var post = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>().Which;
- posts.Add(post);
- await Task.Delay(1000);
- }
-
- {
- var res = await client.DeleteAsync(generator(1, $"posts/{posts[2].Id}"));
- res.Should().BeDelete(true);
- }
-
- {
- var res = await client.GetAsync(generator(1, "posts",
- new Dictionary<string, string> { { "modifiedSince", posts[1].LastUpdated.ToString("s", CultureInfo.InvariantCulture) } }));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelinePostInfo>>()
- .Which.Should().HaveCount(2)
- .And.Subject.Select(p => p.Content.Text).Should().Equal("b", "d");
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task PostList_IncludeDeleted(TimelineUrlGenerator urlGenerator)
- {
- using var client = await CreateClientAsUser();
-
- var postContentList = new List<string> { "a", "b", "c", "d" };
- var posts = new List<TimelinePostInfo>();
-
- foreach (var content in postContentList)
- {
- var res = await client.PostAsJsonAsync(urlGenerator(1, "posts"),
- new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Text = content, Type = TimelinePostContentTypes.Text } });
- posts.Add(res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>().Which);
- }
-
- foreach (var id in new long[] { posts[0].Id, posts[2].Id })
- {
- var res = await client.DeleteAsync(urlGenerator(1, $"posts/{id}"));
- res.Should().BeDelete(true);
- }
-
- {
- var res = await client.GetAsync(urlGenerator(1, "posts", new Dictionary<string, string> { ["includeDeleted"] = "true" }));
- posts = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelinePostInfo>>()
- .Which;
- 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);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Post_ModifiedSince_And_IncludeDeleted(TimelineUrlGenerator urlGenerator)
- {
- using var client = await CreateClientAsUser();
-
- var postContentList = new List<string> { "a", "b", "c", "d" };
- var posts = new List<TimelinePostInfo>();
-
- foreach (var (content, index) in postContentList.Select((v, i) => (v, i)))
- {
- var res = await client.PostAsJsonAsync(urlGenerator(1, "posts"),
- new TimelinePostCreateRequest { Content = new TimelinePostCreateRequestContent { Text = content, Type = TimelinePostContentTypes.Text } });
- var post = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostInfo>().Which;
- posts.Add(post);
- await Task.Delay(1000);
- }
-
- {
- var res = await client.DeleteAsync(urlGenerator(1, $"posts/{posts[2].Id}"));
- res.Should().BeDelete(true);
- }
-
- {
-
- var res = await client.GetAsync(urlGenerator(1, "posts",
- new Dictionary<string, string> {
- { "modifiedSince", posts[1].LastUpdated.ToString("s", CultureInfo.InvariantCulture) },
- { "includeDeleted", "true" }
- }));
- posts = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<List<TimelinePostInfo>>()
- .Which;
- 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);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Timeline_Get_IfModifiedSince_And_CheckUniqueId(TimelineUrlGenerator urlGenerator)
- {
- using var client = await CreateClientAsUser();
-
- DateTime lastModifiedTime;
- TimelineInfo timeline;
- string uniqueId;
-
- {
- var res = await client.GetAsync(urlGenerator(1));
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>().Which;
- timeline = body;
- lastModifiedTime = body.LastModified;
- uniqueId = body.UniqueId;
- }
-
- {
- using var req = new HttpRequestMessage
- {
- RequestUri = new Uri(client.BaseAddress, urlGenerator(1)),
- Method = HttpMethod.Get,
- };
- req.Headers.IfModifiedSince = lastModifiedTime.AddSeconds(1);
- var res = await client.SendAsync(req);
- res.Should().HaveStatusCode(304);
- }
-
- {
- using var req = new HttpRequestMessage
- {
- RequestUri = new Uri(client.BaseAddress, urlGenerator(1)),
- Method = HttpMethod.Get,
- };
- req.Headers.IfModifiedSince = lastModifiedTime.AddSeconds(-1);
- var res = await client.SendAsync(req);
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Should().BeEquivalentTo(timeline);
- }
-
- {
- var res = await client.GetAsync(urlGenerator(1, null,
- new Dictionary<string, string> { { "ifModifiedSince", lastModifiedTime.AddSeconds(1).ToString("s", CultureInfo.InvariantCulture) } }));
- res.Should().HaveStatusCode(304);
- }
-
- {
- var res = await client.GetAsync(urlGenerator(1, null,
- new Dictionary<string, string> { { "ifModifiedSince", lastModifiedTime.AddSeconds(-1).ToString("s", CultureInfo.InvariantCulture) } }));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Should().BeEquivalentTo(timeline);
- }
-
- {
- var res = await client.GetAsync(urlGenerator(1, null,
- new Dictionary<string, string> { { "ifModifiedSince", lastModifiedTime.AddSeconds(1).ToString("s", CultureInfo.InvariantCulture) },
- {"checkUniqueId", uniqueId } }));
- res.Should().HaveStatusCode(304);
- }
-
- {
- var testUniqueId = (uniqueId[0] == 'a' ? "b" : "a") + uniqueId[1..];
- var res = await client.GetAsync(urlGenerator(1, null,
- new Dictionary<string, string> { { "ifModifiedSince", lastModifiedTime.AddSeconds(1).ToString("s", CultureInfo.InvariantCulture) },
- {"checkUniqueId", testUniqueId } }));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Should().BeEquivalentTo(timeline);
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task Title(TimelineUrlGenerator urlGenerator)
- {
- using var client = await CreateClientAsUser();
-
- {
- var res = await client.GetAsync(urlGenerator(1));
- var timeline = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which;
- timeline.Title.Should().Be(timeline.Name);
- }
-
- {
- var res = await client.PatchAsJsonAsync(urlGenerator(1), new TimelinePatchRequest { Title = "atitle" });
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Title.Should().Be("atitle");
- }
-
- {
- var res = await client.GetAsync(urlGenerator(1));
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelineInfo>()
- .Which.Title.Should().Be("atitle");
- }
- }
-
- [Fact]
- public async Task ChangeName()
- {
- {
- using var client = await CreateDefaultClient();
- var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "t1", NewName = "tttttttt" });
- res.Should().HaveStatusCode(401);
- }
-
- {
- using var client = await CreateClientAs(2);
- var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "t1", NewName = "tttttttt" });
- res.Should().HaveStatusCode(403);
- }
-
- using (var client = await CreateClientAsUser())
- {
- {
- var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "!!!", NewName = "tttttttt" });
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "ttt", NewName = "!!!!" });
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "ttttt", NewName = "tttttttt" });
- res.Should().HaveStatusCode(400).And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.TimelineController.NotExist);
- }
-
- {
- var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "t1", NewName = "newt" });
- res.Should().HaveStatusCode(200).And.HaveJsonBody<TimelineInfo>().Which.Name.Should().Be("newt");
- }
-
- {
- var res = await client.GetAsync("timelines/t1");
- res.Should().HaveStatusCode(404);
- }
-
- {
- var res = await client.GetAsync("timelines/newt");
- res.Should().HaveStatusCode(200).And.HaveJsonBody<TimelineInfo>().Which.Name.Should().Be("newt");
- }
- }
- }
-
- [Theory]
- [MemberData(nameof(TimelineUrlGeneratorData))]
- public async Task PostDataETag(TimelineUrlGenerator urlGenerator)
- {
- using var client = await CreateClientAsUser();
-
- long id;
- string etag;
-
- {
- var res = await client.PostAsJsonAsync(urlGenerator(1, "posts"), new TimelinePostCreateRequest
- {
- Content = new TimelinePostCreateRequestContent
- {
- Type = TimelinePostContentTypes.Image,
- Data = Convert.ToBase64String(ImageHelper.CreatePngWithSize(100, 50))
- }
- });
- res.Should().HaveStatusCode(200);
- var body = await res.ReadBodyAsJsonAsync<TimelinePostInfo>();
- body.Content.ETag.Should().NotBeNullOrEmpty();
-
- id = body.Id;
- etag = body.Content.ETag;
- }
-
- {
- var res = await client.GetAsync(urlGenerator(1, $"posts/{id}/data"));
- res.Should().HaveStatusCode(200);
- res.Headers.ETag.Should().NotBeNull();
- res.Headers.ETag.ToString().Should().Be(etag);
- }
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/TokenTest.cs b/Timeline.Tests/IntegratedTests/TokenTest.cs
deleted file mode 100644
index 480d66cd..00000000
--- a/Timeline.Tests/IntegratedTests/TokenTest.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-using FluentAssertions;
-using Microsoft.Extensions.DependencyInjection;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Timeline.Models;
-using Timeline.Models.Http;
-using Timeline.Services;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class TokenTest : IntegratedTestBase
- {
- private const string CreateTokenUrl = "token/create";
- private const string VerifyTokenUrl = "token/verify";
-
- private static async Task<CreateTokenResponse> CreateUserTokenAsync(HttpClient client, string username, string password, int? expireOffset = null)
- {
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password, Expire = expireOffset });
- return response.Should().HaveStatusCode(200)
- .And.HaveJsonBody<CreateTokenResponse>().Which;
- }
-
- public static IEnumerable<object[]> CreateToken_InvalidModel_Data()
- {
- yield return new[] { null, "p", null };
- yield return new[] { "u", null, null };
- yield return new object[] { "u", "p", 2000 };
- yield return new object[] { "u", "p", -1 };
- }
-
- [Theory]
- [MemberData(nameof(CreateToken_InvalidModel_Data))]
- public async Task CreateToken_InvalidModel(string username, string password, int expire)
- {
- using var client = await CreateDefaultClient();
- (await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest
- {
- Username = username,
- Password = password,
- Expire = expire
- })).Should().BeInvalidModel();
- }
-
- public static IEnumerable<object[]> CreateToken_UserCredential_Data()
- {
- yield return new[] { "usernotexist", "p" };
- yield return new[] { "user1", "???" };
- }
-
- [Theory]
- [MemberData(nameof(CreateToken_UserCredential_Data))]
- public async void CreateToken_UserCredential(string username, string password)
- {
- using var client = await CreateDefaultClient();
- var response = await client.PostAsJsonAsync(CreateTokenUrl,
- new CreateTokenRequest { Username = username, Password = password });
- response.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.TokenController.Create_BadCredential);
- }
-
- [Fact]
- public async Task CreateToken_Success()
- {
- using var client = await CreateDefaultClient();
- var response = await client.PostAsJsonAsync(CreateTokenUrl,
- new CreateTokenRequest { Username = "user1", Password = "user1pw" });
- var body = response.Should().HaveStatusCode(200)
- .And.HaveJsonBody<CreateTokenResponse>().Which;
- body.Token.Should().NotBeNullOrWhiteSpace();
- body.User.Should().BeEquivalentTo(UserInfos[1]);
- }
-
- [Fact]
- public async Task VerifyToken_InvalidModel()
- {
- using var client = await CreateDefaultClient();
- (await client.PostAsJsonAsync(VerifyTokenUrl,
- new VerifyTokenRequest { Token = null })).Should().BeInvalidModel();
- }
-
- [Fact]
- public async Task VerifyToken_BadFormat()
- {
- using var client = await CreateDefaultClient();
- var response = await client.PostAsJsonAsync(VerifyTokenUrl,
- new VerifyTokenRequest { Token = "bad token hahaha" });
- response.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.TokenController.Verify_BadFormat);
- }
-
- [Fact]
- public async Task VerifyToken_OldVersion()
- {
- using var client = await CreateDefaultClient();
- var token = (await CreateUserTokenAsync(client, "user1", "user1pw")).Token;
-
- using (var scope = TestApp.Host.Services.CreateScope()) // UserService is scoped.
- {
- // create a user for test
- var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
- await userService.ModifyUser("user1", new User { Password = "user1pw" });
- }
-
- (await client.PostAsJsonAsync(VerifyTokenUrl,
- new VerifyTokenRequest { Token = token }))
- .Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.TokenController.Verify_OldVersion);
- }
-
- [Fact]
- public async Task VerifyToken_UserNotExist()
- {
- using var client = await CreateDefaultClient();
- var token = (await CreateUserTokenAsync(client, "user1", "user1pw")).Token;
-
- using (var scope = TestApp.Host.Services.CreateScope()) // UserDeleteService is scoped.
- {
- var userService = scope.ServiceProvider.GetRequiredService<IUserDeleteService>();
- await userService.DeleteUser("user1");
- }
-
- (await client.PostAsJsonAsync(VerifyTokenUrl,
- new VerifyTokenRequest { Token = token }))
- .Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.TokenController.Verify_UserNotExist);
- }
-
- //[Fact]
- //public async Task VerifyToken_Expired()
- //{
- // using (var client = await CreateClientWithNoAuth())
- // {
- // // I can only control the token expired time but not current time
- // // because verify logic is encapsuled in other library.
- // var mockClock = _factory.GetTestClock();
- // mockClock.MockCurrentTime = DateTime.Now - TimeSpan.FromDays(2);
- // var token = (await client.CreateUserTokenAsync(MockUsers.UserUsername, MockUsers.UserPassword, 1)).Token;
- // var response = await client.PostAsJsonAsync(VerifyTokenUrl,
- // new VerifyTokenRequest { Token = token });
- // response.Should().HaveStatusCodeBadRequest()
- // .And.Should().HaveBodyAsCommonResponseWithCode(TokenController.ErrorCodes.Verify_Expired);
- // mockClock.MockCurrentTime = null;
- // }
- //}
-
- [Fact]
- public async Task VerifyToken_Success()
- {
- using var client = await CreateDefaultClient();
- var createTokenResult = await CreateUserTokenAsync(client, "user1", "user1pw");
- var response = await client.PostAsJsonAsync(VerifyTokenUrl,
- new VerifyTokenRequest { Token = createTokenResult.Token });
- response.Should().HaveStatusCode(200)
- .And.HaveJsonBody<VerifyTokenResponse>()
- .Which.User.Should().BeEquivalentTo(UserInfos[1]);
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/UnknownEndpointTest.cs b/Timeline.Tests/IntegratedTests/UnknownEndpointTest.cs
deleted file mode 100644
index 732232e2..00000000
--- a/Timeline.Tests/IntegratedTests/UnknownEndpointTest.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using FluentAssertions;
-using System.Threading.Tasks;
-using Timeline.Models.Http;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class UnknownEndpointTest : IntegratedTestBase
- {
- [Fact]
- public async Task UnknownEndpoint()
- {
- using var client = await CreateDefaultClient();
- var res = await client.GetAsync("unknownEndpoint");
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Common.UnknownEndpoint);
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
deleted file mode 100644
index f2796005..00000000
--- a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
+++ /dev/null
@@ -1,251 +0,0 @@
-using FluentAssertions;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.DependencyInjection;
-using SixLabors.ImageSharp.Formats;
-using SixLabors.ImageSharp.Formats.Gif;
-using SixLabors.ImageSharp.Formats.Jpeg;
-using SixLabors.ImageSharp.Formats.Png;
-using System.Collections.Generic;
-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;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class UserAvatarTest : IntegratedTestBase
- {
- [Fact]
- public async Task Test()
- {
- Avatar mockAvatar = new Avatar
- {
- Data = ImageHelper.CreatePngWithSize(100, 100),
- Type = PngFormat.Instance.DefaultMimeType
- };
-
- using (var client = await CreateClientAsUser())
- {
- {
- var res = await client.GetAsync("users/usernotexist/avatar");
- res.Should().HaveStatusCode(404)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
- }
-
- var env = TestApp.Host.Services.GetRequiredService<IWebHostEnvironment>();
- var defaultAvatarData = await File.ReadAllBytesAsync(Path.Combine(env.ContentRootPath, "default-avatar.png"));
-
- async Task GetReturnDefault(string username = "user1")
- {
- var res = await client.GetAsync($"users/{username}/avatar");
- res.Should().HaveStatusCode(200);
- res.Content.Headers.ContentType.MediaType.Should().Be("image/png");
- var body = await res.Content.ReadAsByteArrayAsync();
- body.Should().Equal(defaultAvatarData);
- }
-
- {
- var res = await client.GetAsync("users/user1/avatar");
- res.Should().HaveStatusCode(200);
- res.Content.Headers.ContentType.MediaType.Should().Be("image/png");
- var body = await res.Content.ReadAsByteArrayAsync();
- body.Should().Equal(defaultAvatarData);
- }
-
- await CacheTestHelper.TestCache(client, "users/user1/avatar");
-
- await GetReturnDefault("admin");
-
- {
- using var content = new ByteArrayContent(new[] { (byte)0x00 });
- content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user1/avatar", content);
- res.Should().BeInvalidModel();
- }
-
- {
- using var content = new ByteArrayContent(new[] { (byte)0x00 });
- content.Headers.ContentLength = 1;
- var res = await client.PutAsync("users/user1/avatar", content);
- res.Should().BeInvalidModel();
- }
-
- {
- using var content = new ByteArrayContent(new[] { (byte)0x00 });
- content.Headers.ContentLength = 0;
- content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user1/avatar", content);
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", new[] { (byte)0x00 }, "image/notaccept");
- res.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType);
- }
-
- {
- using var content = new ByteArrayContent(new[] { (byte)0x00 });
- content.Headers.ContentLength = 1000 * 1000 * 11;
- content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user1/avatar", content);
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Content.TooBig);
- }
-
- {
- using var content = new ByteArrayContent(new[] { (byte)0x00 });
- content.Headers.ContentLength = 2;
- content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user1/avatar", content);
- res.Should().BeInvalidModel();
- }
-
- {
- using var content = new ByteArrayContent(new[] { (byte)0x00, (byte)0x01 });
- content.Headers.ContentLength = 1;
- content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user1/avatar", content);
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", new[] { (byte)0x00 }, "image/png");
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserAvatar.BadFormat_CantDecode);
- }
-
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", mockAvatar.Data, "image/jpeg");
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserAvatar.BadFormat_UnmatchedFormat);
- }
-
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", ImageHelper.CreatePngWithSize(100, 200), "image/png");
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserAvatar.BadFormat_BadSize);
- }
-
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.Type);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
-
- var res2 = await client.GetAsync("users/user1/avatar");
- res2.Should().HaveStatusCode(200);
- res2.Content.Headers.ContentType.MediaType.Should().Be(mockAvatar.Type);
- var body = await res2.Content.ReadAsByteArrayAsync();
- body.Should().Equal(mockAvatar.Data);
- }
-
- IEnumerable<(string, IImageFormat)> formats = new (string, IImageFormat)[]
- {
- ("image/jpeg", JpegFormat.Instance),
- ("image/gif", GifFormat.Instance),
- ("image/png", PngFormat.Instance),
- };
-
- foreach ((var mimeType, var format) in formats)
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", ImageHelper.CreateImageWithSize(100, 100, format), mimeType);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
-
- {
- var res = await client.PutByteArrayAsync("users/admin/avatar", new[] { (byte)0x00 }, "image/png");
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Forbid);
- }
-
- {
- var res = await client.DeleteAsync("users/admin/avatar");
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Forbid);
- }
-
- for (int i = 0; i < 2; i++) // double delete should work.
- {
- var res = await client.DeleteAsync("users/user1/avatar");
- res.Should().HaveStatusCode(200);
- await GetReturnDefault();
- }
- }
-
- // Authorization check.
- using (var client = await CreateClientAsAdministrator())
- {
- {
- var res = await client.PutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.Type);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
-
- {
- var res = await client.DeleteAsync("users/user1/avatar");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
-
- {
- var res = await client.PutByteArrayAsync("users/usernotexist/avatar", new[] { (byte)0x00 }, "image/png");
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
- }
-
- {
- var res = await client.DeleteAsync("users/usernotexist/avatar");
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
- }
- }
-
- // bad username check
- using (var client = await CreateClientAsAdministrator())
- {
- {
- var res = await client.GetAsync("users/u!ser/avatar");
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.PutByteArrayAsync("users/u!ser/avatar", ImageHelper.CreatePngWithSize(100, 100), "image/png");
- res.Should().BeInvalidModel();
- }
-
- {
- var res = await client.DeleteAsync("users/u!ser/avatar");
- res.Should().BeInvalidModel();
- }
- }
- }
-
- [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.Tests/IntegratedTests/UserTest.cs b/Timeline.Tests/IntegratedTests/UserTest.cs
deleted file mode 100644
index 9dfcc6a5..00000000
--- a/Timeline.Tests/IntegratedTests/UserTest.cs
+++ /dev/null
@@ -1,447 +0,0 @@
-using FluentAssertions;
-using System.Collections.Generic;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Timeline.Models.Http;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class UserTest : IntegratedTestBase
- {
- [Fact]
- public void UserListShouldHaveUniqueId()
- {
- foreach (var user in UserInfos)
- {
- user.UniqueId.Should().NotBeNullOrWhiteSpace();
- }
- }
-
- [Fact]
- public async Task GetList_NoAuth()
- {
- using var client = await CreateDefaultClient();
- var res = await client.GetAsync("users");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo[]>()
- .Which.Should().BeEquivalentTo(UserInfos);
- }
-
- [Fact]
- public async Task GetList_User()
- {
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync("users");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo[]>()
- .Which.Should().BeEquivalentTo(UserInfos);
- }
-
- [Fact]
- public async Task GetList_Admin()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.GetAsync("users");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo[]>()
- .Which.Should().BeEquivalentTo(UserInfos);
- }
-
- [Fact]
- public async Task Get_NoAuth()
- {
- using var client = await CreateDefaultClient();
- var res = await client.GetAsync($"users/admin");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Should().BeEquivalentTo(UserInfos[0]);
- }
-
- [Fact]
- public async Task Get_User()
- {
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync($"users/admin");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Should().BeEquivalentTo(UserInfos[0]);
- }
-
- [Fact]
- public async Task Get_Admin()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.GetAsync($"users/user1");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Should().BeEquivalentTo(UserInfos[1]);
- }
-
- [Fact]
- public async Task Get_InvalidModel()
- {
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync("users/aaa!a");
- res.Should().BeInvalidModel();
- }
-
- [Fact]
- public async Task Get_404()
- {
- using var client = await CreateClientAsUser();
- var res = await client.GetAsync("users/usernotexist");
- res.Should().HaveStatusCode(404)
- .And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
- }
-
- [Fact]
- public async Task Patch_User()
- {
- using var client = await CreateClientAsUser();
- {
- var res = await client.PatchAsJsonAsync("users/user1",
- new UserPatchRequest { Nickname = "aaa" });
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Nickname.Should().Be("aaa");
- }
-
- {
- var res = await client.GetAsync("users/user1");
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Nickname.Should().Be("aaa");
- }
- }
-
- [Fact]
- public async Task Patch_Admin()
- {
- using var client = await CreateClientAsAdministrator();
- using var userClient = await CreateClientAsUser();
-
- {
- var res = await client.PatchAsJsonAsync("users/user1",
- new UserPatchRequest
- {
- Username = "newuser",
- Password = "newpw",
- Administrator = true,
- Nickname = "aaa"
- });
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which;
- body.Administrator.Should().Be(true);
- body.Nickname.Should().Be("aaa");
- }
-
- {
- var res = await client.GetAsync("users/newuser");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which;
- body.Administrator.Should().Be(true);
- body.Nickname.Should().Be("aaa");
- }
-
- {
- // Token should expire.
- var res = await userClient.GetAsync("testing/auth/Authorize");
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
-
- {
- // Check password.
- (await CreateClientWithCredential("newuser", "newpw")).Dispose();
- }
- }
-
- [Fact]
- public async Task Patch_NotExist()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.PatchAsJsonAsync("users/usernotexist", new UserPatchRequest { });
- res.Should().HaveStatusCode(404)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
- }
-
- [Fact]
- public async Task Patch_InvalidModel()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.PatchAsJsonAsync("users/aaa!a", new UserPatchRequest { });
- res.Should().BeInvalidModel();
- }
-
- public static IEnumerable<object[]> Patch_InvalidModel_Body_Data()
- {
- yield return new[] { new UserPatchRequest { Username = "aaa!a" } };
- yield return new[] { new UserPatchRequest { Password = "" } };
- yield return new[] { new UserPatchRequest { Nickname = new string('a', 50) } };
- }
-
- [Theory]
- [MemberData(nameof(Patch_InvalidModel_Body_Data))]
- public async Task Patch_InvalidModel_Body(UserPatchRequest body)
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.PatchAsJsonAsync("users/user1", body);
- res.Should().BeInvalidModel();
- }
-
- [Fact]
- public async Task Patch_UsernameConflict()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Username = "admin" });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict);
- }
-
- [Fact]
- public async Task Patch_NoAuth_Unauthorized()
- {
- using var client = await CreateDefaultClient();
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Nickname = "aaa" });
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
-
- [Fact]
- public async Task Patch_User_Forbid()
- {
- using var client = await CreateClientAsUser();
- var res = await client.PatchAsJsonAsync("users/admin", new UserPatchRequest { Nickname = "aaa" });
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- [Fact]
- public async Task Patch_Username_Forbid()
- {
- using var client = await CreateClientAsUser();
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Username = "aaa" });
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- [Fact]
- public async Task Patch_Password_Forbid()
- {
- using var client = await CreateClientAsUser();
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Password = "aaa" });
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- [Fact]
- public async Task Patch_Administrator_Forbid()
- {
- using var client = await CreateClientAsUser();
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Administrator = true });
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- [Fact]
- public async Task Delete_Deleted()
- {
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.DeleteAsync("users/user1");
- res.Should().BeDelete(true);
- }
-
- {
- var res = await client.GetAsync("users/user1");
- res.Should().HaveStatusCode(404);
- }
- }
-
- [Fact]
- public async Task Delete_NotExist()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.DeleteAsync("users/usernotexist");
- res.Should().BeDelete(false);
- }
-
- [Fact]
- public async Task Delete_InvalidModel()
- {
- using var client = await CreateClientAsAdministrator();
- var res = await client.DeleteAsync("users/aaa!a");
- res.Should().BeInvalidModel();
- }
-
- [Fact]
- public async Task Delete_NoAuth_Unauthorized()
- {
- using var client = await CreateDefaultClient();
- var res = await client.DeleteAsync("users/aaa!a");
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
-
- [Fact]
- public async Task Delete_User_Forbid()
- {
- using var client = await CreateClientAsUser();
- var res = await client.DeleteAsync("users/aaa!a");
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
-
- private const string createUserUrl = "userop/createuser";
-
- [Fact]
- public async Task Op_CreateUser()
- {
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
- {
- Username = "aaa",
- Password = "bbb",
- Administrator = true,
- Nickname = "ccc"
- });
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>().Which;
- body.Username.Should().Be("aaa");
- body.Nickname.Should().Be("ccc");
- body.Administrator.Should().BeTrue();
- }
- {
- var res = await client.GetAsync("users/aaa");
- var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>().Which;
- body.Username.Should().Be("aaa");
- body.Nickname.Should().Be("ccc");
- body.Administrator.Should().BeTrue();
- }
- {
- // Test password.
- (await CreateClientWithCredential("aaa", "bbb")).Dispose();
- }
- }
-
- public static IEnumerable<object[]> Op_CreateUser_InvalidModel_Data()
- {
- yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb" } };
- yield return new[] { new CreateUserRequest { Username = "aaa", Administrator = true } };
- yield return new[] { new CreateUserRequest { Password = "bbb", Administrator = true } };
- yield return new[] { new CreateUserRequest { Username = "a!a", Password = "bbb", Administrator = true } };
- yield return new[] { new CreateUserRequest { Username = "aaa", Password = "", Administrator = true } };
- yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb", Administrator = true, Nickname = new string('a', 40) } };
- }
-
- [Theory]
- [MemberData(nameof(Op_CreateUser_InvalidModel_Data))]
- public async Task Op_CreateUser_InvalidModel(CreateUserRequest body)
- {
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.PostAsJsonAsync(createUserUrl, body);
- res.Should().BeInvalidModel();
- }
- }
-
- [Fact]
- public async Task Op_CreateUser_UsernameConflict()
- {
- using var client = await CreateClientAsAdministrator();
- {
- var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
- {
- Username = "user1",
- Password = "bbb",
- Administrator = false
- });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict);
- }
- }
-
- [Fact]
- public async Task Op_CreateUser_NoAuth_Unauthorized()
- {
- using var client = await CreateDefaultClient();
- {
- var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
- {
- Username = "aaa",
- Password = "bbb",
- Administrator = false
- });
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
- }
-
- [Fact]
- public async Task Op_CreateUser_User_Forbid()
- {
- using var client = await CreateClientAsUser();
- {
- var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
- {
- Username = "aaa",
- Password = "bbb",
- Administrator = false
- });
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
- }
-
- private const string changePasswordUrl = "userop/changepassword";
-
- [Fact]
- public async Task Op_ChangePassword()
- {
- using var client = await CreateClientAsUser();
- {
- var res = await client.PostAsJsonAsync(changePasswordUrl,
- new ChangePasswordRequest { OldPassword = "user1pw", NewPassword = "newpw" });
- res.Should().HaveStatusCode(200);
- }
- {
- var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { });
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
- {
- (await CreateClientWithCredential("user1", "newpw")).Dispose();
- }
- }
-
- public static IEnumerable<object[]> Op_ChangePassword_InvalidModel_Data()
- {
- yield return new[] { null, "ppp" };
- yield return new[] { "ppp", null };
- }
-
- [Theory]
- [MemberData(nameof(Op_ChangePassword_InvalidModel_Data))]
- public async Task Op_ChangePassword_InvalidModel(string oldPassword, string newPassword)
- {
- using var client = await CreateClientAsUser();
- var res = await client.PostAsJsonAsync(changePasswordUrl,
- new ChangePasswordRequest { OldPassword = oldPassword, NewPassword = newPassword });
- res.Should().BeInvalidModel();
- }
-
- [Fact]
- public async Task Op_ChangePassword_BadOldPassword()
- {
- using var client = await CreateClientAsUser();
- var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody(ErrorCodes.UserController.ChangePassword_BadOldPassword);
- }
-
- [Fact]
- public async Task Op_ChangePassword_NoAuth_Unauthorized()
- {
- using var client = await CreateDefaultClient();
- var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" });
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
- }
-}
diff --git a/Timeline.Tests/PasswordGenerator.cs b/Timeline.Tests/PasswordGenerator.cs
deleted file mode 100644
index 863439b5..00000000
--- a/Timeline.Tests/PasswordGenerator.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using Timeline.Services;
-using Xunit;
-using Xunit.Abstractions;
-
-namespace Timeline.Tests
-{
- public class PasswordGenerator
- {
- private readonly ITestOutputHelper _output;
-
- public PasswordGenerator(ITestOutputHelper output)
- {
- _output = output;
- }
-
- [Fact]
- public void Generate()
- {
- var service = new PasswordService();
- _output.WriteLine(service.HashPassword("crupest"));
- }
- }
-}
diff --git a/Timeline.Tests/Properties/launchSettings.json b/Timeline.Tests/Properties/launchSettings.json
deleted file mode 100644
index f3ee419d..00000000
--- a/Timeline.Tests/Properties/launchSettings.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
diff --git a/Timeline.Tests/Services/TimelineServiceTest.cs b/Timeline.Tests/Services/TimelineServiceTest.cs
deleted file mode 100644
index 5a774b78..00000000
--- a/Timeline.Tests/Services/TimelineServiceTest.cs
+++ /dev/null
@@ -1,329 +0,0 @@
-using FluentAssertions;
-using Microsoft.Extensions.Logging.Abstractions;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Timeline.Entities;
-using Timeline.Models;
-using Timeline.Services;
-using Timeline.Services.Exceptions;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.Services
-{
- public class TimelineServiceTest : IAsyncLifetime, IDisposable
- {
- private readonly TestDatabase _testDatabase = new TestDatabase();
-
- private DatabaseContext _databaseContext;
-
- private readonly PasswordService _passwordService = new PasswordService();
-
- private readonly ETagGenerator _eTagGenerator = new ETagGenerator();
-
- private readonly ImageValidator _imageValidator = new ImageValidator();
-
- private readonly TestClock _clock = new TestClock();
-
- private DataManager _dataManager;
-
- private UserService _userService;
-
- private TimelineService _timelineService;
-
- private UserDeleteService _userDeleteService;
-
- public TimelineServiceTest()
- {
- }
-
- public async Task InitializeAsync()
- {
- await _testDatabase.InitializeAsync();
- _databaseContext = _testDatabase.CreateContext();
- _dataManager = new DataManager(_databaseContext, _eTagGenerator);
- _userService = new UserService(NullLogger<UserService>.Instance, _databaseContext, _passwordService, _clock);
- _timelineService = new TimelineService(NullLogger<TimelineService>.Instance, _databaseContext, _dataManager, _userService, _imageValidator, _clock);
- _userDeleteService = new UserDeleteService(NullLogger<UserDeleteService>.Instance, _databaseContext, _timelineService);
- }
-
- public async Task DisposeAsync()
- {
- await _testDatabase.DisposeAsync();
- await _databaseContext.DisposeAsync();
- }
-
- public void Dispose()
- {
- _eTagGenerator.Dispose();
- }
-
- [Theory]
- [InlineData("@user")]
- [InlineData("tl")]
- public async Task Timeline_GetLastModified(string timelineName)
- {
- var time = _clock.ForwardCurrentTime();
-
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, await _userService.GetUserIdByUsername("user"));
-
- var t = await _timelineService.GetTimelineLastModifiedTime(timelineName);
-
- t.Should().Be(time);
- }
-
- [Theory]
- [InlineData("@user")]
- [InlineData("tl")]
- public async Task Timeline_GetUnqiueId(string timelineName)
- {
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, await _userService.GetUserIdByUsername("user"));
-
- var uniqueId = await _timelineService.GetTimelineUniqueId(timelineName);
-
- uniqueId.Should().NotBeNullOrEmpty();
- }
-
- [Theory]
- [InlineData("@user")]
- [InlineData("tl")]
- public async Task Timeline_LastModified(string timelineName)
- {
- var initTime = _clock.ForwardCurrentTime();
-
- void Check(Models.Timeline timeline)
- {
- timeline.NameLastModified.Should().Be(initTime);
- timeline.LastModified.Should().Be(_clock.GetCurrentTime());
- }
-
- async Task GetAndCheck()
- {
- Check(await _timelineService.GetTimeline(timelineName));
- }
-
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- Check(await _timelineService.CreateTimeline(timelineName, await _userService.GetUserIdByUsername("user")));
-
- await GetAndCheck();
-
- _clock.ForwardCurrentTime();
- await _timelineService.ChangeProperty(timelineName, new TimelineChangePropertyRequest { Visibility = TimelineVisibility.Public });
- await GetAndCheck();
-
- _clock.ForwardCurrentTime();
- await _timelineService.ChangeMember(timelineName, new List<string> { "admin" }, null);
- await GetAndCheck();
- }
-
- [Theory]
- [InlineData("@user")]
- [InlineData("tl")]
- public async Task GetPosts_ModifiedSince(string timelineName)
- {
- _clock.ForwardCurrentTime();
-
- var userId = await _userService.GetUserIdByUsername("user");
-
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, userId);
-
- var postContentList = new string[] { "a", "b", "c", "d" };
-
- DateTime testPoint = new DateTime();
-
- foreach (var (content, index) in postContentList.Select((v, i) => (v, i)))
- {
- var t = _clock.ForwardCurrentTime();
- if (index == 1)
- testPoint = t;
- await _timelineService.CreateTextPost(timelineName, userId, content, null);
- }
-
- var posts = await _timelineService.GetPosts(timelineName, testPoint);
- posts.Should().HaveCount(3)
- .And.Subject.Select(p => (p.Content as TextTimelinePostContent).Text).Should().Equal(postContentList.Skip(1));
- }
-
- [Theory]
- [InlineData("@user")]
- [InlineData("tl")]
- public async Task GetPosts_IncludeDeleted(string timelineName)
- {
- var userId = await _userService.GetUserIdByUsername("user");
-
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, userId);
-
- var postContentList = new string[] { "a", "b", "c", "d" };
-
- foreach (var content in postContentList)
- {
- await _timelineService.CreateTextPost(timelineName, userId, content, null);
- }
-
- var posts = await _timelineService.GetPosts(timelineName);
- posts.Should().HaveCount(4);
- posts.Select(p => p.Deleted).Should().Equal(Enumerable.Repeat(false, posts.Count));
- posts.Select(p => ((TextTimelinePostContent)p.Content).Text).Should().Equal(postContentList);
-
- foreach (var id in new long[] { posts[0].Id, posts[2].Id })
- {
- await _timelineService.DeletePost(timelineName, id);
- }
-
- posts = await _timelineService.GetPosts(timelineName);
- posts.Should().HaveCount(2);
- posts.Select(p => p.Deleted).Should().Equal(Enumerable.Repeat(false, posts.Count));
- posts.Select(p => ((TextTimelinePostContent)p.Content).Text).Should().Equal(new string[] { "b", "d" });
-
- posts = await _timelineService.GetPosts(timelineName, includeDeleted: true);
- posts.Should().HaveCount(4);
- posts.Select(p => p.Deleted).Should().Equal(new bool[] { true, false, true, false });
- posts.Where(p => !p.Deleted).Select(p => ((TextTimelinePostContent)p.Content).Text).Should().Equal(new string[] { "b", "d" });
- }
-
- [Theory]
- [InlineData("@admin")]
- [InlineData("tl")]
- public async Task GetPosts_ModifiedSince_UsernameChange(string timelineName)
- {
- var time1 = _clock.ForwardCurrentTime();
-
- var userId = await _userService.GetUserIdByUsername("user");
-
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, userId);
-
- var postContentList = new string[] { "a", "b", "c", "d" };
-
- foreach (var (content, index) in postContentList.Select((v, i) => (v, i)))
- {
- await _timelineService.CreateTextPost(timelineName, userId, content, null);
- }
-
- var time2 = _clock.ForwardCurrentTime();
-
- {
- var posts = await _timelineService.GetPosts(timelineName, time2);
- posts.Should().HaveCount(0);
- }
-
- {
- await _userService.ModifyUser(userId, new User { Nickname = "haha" });
- var posts = await _timelineService.GetPosts(timelineName, time2);
- posts.Should().HaveCount(0);
- }
-
- {
- await _userService.ModifyUser(userId, new User { Username = "haha" });
- var posts = await _timelineService.GetPosts(timelineName, time2);
- posts.Should().HaveCount(4);
- }
- }
-
- [Theory]
- [InlineData("@admin")]
- [InlineData("tl")]
- public async Task GetPosts_ModifiedSince_UserDelete(string timelineName)
- {
- var time1 = _clock.ForwardCurrentTime();
-
- var userId = await _userService.GetUserIdByUsername("user");
- var adminId = await _userService.GetUserIdByUsername("admin");
-
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, adminId);
-
- var postContentList = new string[] { "a", "b", "c", "d" };
-
- foreach (var (content, index) in postContentList.Select((v, i) => (v, i)))
- {
- await _timelineService.CreateTextPost(timelineName, userId, content, null);
- }
-
- var time2 = _clock.ForwardCurrentTime();
-
- {
- var posts = await _timelineService.GetPosts(timelineName, time2);
- posts.Should().HaveCount(0);
- }
-
- await _userDeleteService.DeleteUser("user");
-
- {
- var posts = await _timelineService.GetPosts(timelineName, time2);
- posts.Should().HaveCount(0);
- }
-
- {
- var posts = await _timelineService.GetPosts(timelineName, time2, true);
- posts.Should().HaveCount(4);
- }
- }
-
- [Theory]
- [InlineData("@admin")]
- [InlineData("tl")]
- public async Task Title(string timelineName)
- {
- var _ = TimelineHelper.ExtractTimelineName(timelineName, out var isPersonal);
- if (!isPersonal)
- await _timelineService.CreateTimeline(timelineName, await _userService.GetUserIdByUsername("user"));
-
- {
- var timeline = await _timelineService.GetTimeline(timelineName);
- timeline.Title.Should().Be(timelineName);
- }
-
- {
- await _timelineService.ChangeProperty(timelineName, new TimelineChangePropertyRequest { Title = null });
- var timeline = await _timelineService.GetTimeline(timelineName);
- timeline.Title.Should().Be(timelineName);
- }
-
- {
- await _timelineService.ChangeProperty(timelineName, new TimelineChangePropertyRequest { Title = "atitle" });
- var timeline = await _timelineService.GetTimeline(timelineName);
- timeline.Title.Should().Be("atitle");
- }
- }
-
- [Fact]
- public async Task ChangeName()
- {
- _clock.ForwardCurrentTime();
-
- await _timelineService.Awaiting(s => s.ChangeTimelineName("!!!", "newtl")).Should().ThrowAsync<ArgumentException>();
- await _timelineService.Awaiting(s => s.ChangeTimelineName("tl", "!!!")).Should().ThrowAsync<ArgumentException>();
- await _timelineService.Awaiting(s => s.ChangeTimelineName("tl", "newtl")).Should().ThrowAsync<TimelineNotExistException>();
-
- await _timelineService.CreateTimeline("tl", await _userService.GetUserIdByUsername("user"));
- await _timelineService.CreateTimeline("tl2", await _userService.GetUserIdByUsername("user"));
-
- await _timelineService.Awaiting(s => s.ChangeTimelineName("tl", "tl2")).Should().ThrowAsync<EntityAlreadyExistException>();
-
- var time = _clock.ForwardCurrentTime();
-
- await _timelineService.ChangeTimelineName("tl", "newtl");
-
- {
- var timeline = await _timelineService.GetTimeline("newtl");
- timeline.Name.Should().Be("newtl");
- timeline.LastModified.Should().Be(time);
- timeline.NameLastModified.Should().Be(time);
- }
- }
- }
-}
diff --git a/Timeline.Tests/Timeline.Tests.csproj b/Timeline.Tests/Timeline.Tests.csproj
deleted file mode 100644
index 973e0fc0..00000000
--- a/Timeline.Tests/Timeline.Tests.csproj
+++ /dev/null
@@ -1,34 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
-
- <PropertyGroup>
- <TargetFramework>netcoreapp3.1</TargetFramework>
-
- <LangVersion>8.0</LangVersion>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="coverlet.collector" Version="1.3.0">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- <PackageReference Include="FluentAssertions" Version="5.10.3" />
- <PackageReference Include="JunitXml.TestLogger" Version="2.1.78" />
- <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
- <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.1.9" />
- <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
- <PackageReference Include="Moq" Version="4.14.7" />
- <PackageReference Include="xunit" Version="2.4.1" />
- <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
- </PackageReference>
- </ItemGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\Timeline\Timeline.csproj" />
- </ItemGroup>
-</Project>
diff --git a/Timeline.Tests/UsernameValidatorUnitTest.cs b/Timeline.Tests/UsernameValidatorUnitTest.cs
deleted file mode 100644
index 5b568adf..00000000
--- a/Timeline.Tests/UsernameValidatorUnitTest.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using FluentAssertions;
-using Timeline.Models.Validation;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests
-{
- public class UsernameValidatorUnitTest : IClassFixture<UsernameValidator>
- {
- private readonly UsernameValidator _validator;
-
- public UsernameValidatorUnitTest(UsernameValidator validator)
- {
- _validator = validator;
- }
-
- private string FailAndMessage(string username)
- {
- var (result, message) = _validator.Validate(username);
- result.Should().BeFalse();
- return message;
- }
-
- [Fact]
- public void NotString()
- {
- var (result, message) = _validator.Validate(123);
- result.Should().BeFalse();
- message.Should().ContainEquivalentOf("type");
- }
-
- [Fact]
- public void Empty()
- {
- FailAndMessage("").Should().ContainEquivalentOf("empty");
- }
-
- [Theory]
- [InlineData("!")]
- [InlineData("!abc")]
- [InlineData("ab c")]
- [InlineData("ab c!")] // This is a chinese ! .
- public void BadCharactor(string value)
- {
- FailAndMessage(value).Should().ContainEquivalentOf("invalid")
- .And.ContainEquivalentOf("character");
- }
-
- [Fact]
- public void TooLong()
- {
- FailAndMessage(new string('a', 40)).Should().ContainEquivalentOf("long");
- }
-
- [Fact(Skip = "Currently name can't be longer than 26. So this will print message of too long.")]
- public void UniqueId()
- {
- FailAndMessage("e4c80127d092d9b2fc19c5e04612d4c0").Should().ContainEquivalentOf("unique id");
- }
-
- [Theory]
- [InlineData(null)]
- [InlineData("abc")]
- [InlineData("-abc")]
- [InlineData("_abc")]
- [InlineData("abc-")]
- [InlineData("abc_")]
- [InlineData("a-bc")]
- [InlineData("a-b-c")]
- [InlineData("a-b_c")]
- [InlineData("a-你好_c")]
- public void Success(string value)
- {
- var (result, _) = _validator.Validate(value);
- result.Should().BeTrue();
- }
- }
-}
diff --git a/Timeline.Tests/coverletArgs.runsettings b/Timeline.Tests/coverletArgs.runsettings
deleted file mode 100644
index 24cd1822..00000000
--- a/Timeline.Tests/coverletArgs.runsettings
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<RunSettings>
- <DataCollectionRunSettings>
- <DataCollectors>
- <DataCollector friendlyName="XPlat code coverage">
- <Configuration>
- <!-- [Assembly-Filter]Type-Filter -->
- <Exclude>[xunit.*]*,[Timeline]Timeline.Migrations.*</Exclude>
- </Configuration>
- </DataCollector>
- </DataCollectors>
- </DataCollectionRunSettings>
-</RunSettings>
diff --git a/Timeline.Tests/packages.lock.json b/Timeline.Tests/packages.lock.json
deleted file mode 100644
index 7150a222..00000000
--- a/Timeline.Tests/packages.lock.json
+++ /dev/null
@@ -1,2040 +0,0 @@
-{
- "version": 1,
- "dependencies": {
- ".NETCoreApp,Version=v3.1": {
- "coverlet.collector": {
- "type": "Direct",
- "requested": "[1.3.0, )",
- "resolved": "1.3.0",
- "contentHash": "t8pnf5SX2ya0RX4vjoxsbhDMQCZJcpPun2neHKJ4FouMmObylo25FvoOydvf3Bl+l+IzWw7u2vjEeCBHnleB9g=="
- },
- "FluentAssertions": {
- "type": "Direct",
- "requested": "[5.10.3, )",
- "resolved": "5.10.3",
- "contentHash": "gVPEVp1hLVqcv+7Q2wiDf7kqCNn7+bQcQ0jbJ2mcRT6CeRoZl1tNkqvzSIhvekyldDptk77j1b03MXTTRIqqpg==",
- "dependencies": {
- "System.Configuration.ConfigurationManager": "4.4.0"
- }
- },
- "JunitXml.TestLogger": {
- "type": "Direct",
- "requested": "[2.1.78, )",
- "resolved": "2.1.78",
- "contentHash": "4y4FSfKWxlked8ilQdqBBSeRMf5jD/Hkvyp744hc54yQcABLt4rR2Q+4hNqAqrSo+mhwAlusj2rpXpN/5TICCA=="
- },
- "Microsoft.AspNet.WebApi.Client": {
- "type": "Direct",
- "requested": "[5.2.7, )",
- "resolved": "5.2.7",
- "contentHash": "/76fAHknzvFqbznS6Uj2sOyE9rJB3PltY+f53TH8dX9RiGhk02EhuFCWljSj5nnqKaTsmma8DFR50OGyQ4yJ1g==",
- "dependencies": {
- "Newtonsoft.Json": "10.0.1",
- "Newtonsoft.Json.Bson": "1.0.1"
- }
- },
- "Microsoft.AspNetCore.TestHost": {
- "type": "Direct",
- "requested": "[3.1.9, )",
- "resolved": "3.1.9",
- "contentHash": "0DBtfgmM2yS4h0v+gS4JHRX4nuyQmW7Yi5/G4yB5KelA2dDXPsAiipw9z47B1jVEs9QZdOwSqPQm2R/owl2TnA==",
- "dependencies": {
- "System.IO.Pipelines": "4.7.3"
- }
- },
- "Microsoft.CodeAnalysis.FxCopAnalyzers": {
- "type": "Direct",
- "requested": "[3.3.0, )",
- "resolved": "3.3.0",
- "contentHash": "k3Icqx8kc+NrHImuiB8Jc/wd32Xeyd2B/7HOR5Qu9pyKzXQ4ikPeBAwzG2FSTuYhyIuNWvwL5k9yYBbbVz6w9w==",
- "dependencies": {
- "Microsoft.CodeAnalysis.VersionCheckAnalyzer": "[3.3.0]",
- "Microsoft.CodeQuality.Analyzers": "[3.3.0]",
- "Microsoft.NetCore.Analyzers": "[3.3.0]",
- "Microsoft.NetFramework.Analyzers": "[3.3.0]"
- }
- },
- "Microsoft.NET.Test.Sdk": {
- "type": "Direct",
- "requested": "[16.7.1, )",
- "resolved": "16.7.1",
- "contentHash": "7T3XYuLT2CRMZXwlp8p4cEEf6y7VifxTdKwYNzCYp31CN4iyrcDKneIJvNTo0YVnTxJn+CSlGVlUnZHUlAwt9A==",
- "dependencies": {
- "Microsoft.CodeCoverage": "16.7.1",
- "Microsoft.TestPlatform.TestHost": "16.7.1"
- }
- },
- "Moq": {
- "type": "Direct",
- "requested": "[4.14.7, )",
- "resolved": "4.14.7",
- "contentHash": "z1jwY3lL3d4l+92cdSnhRDUUco68HiRNfLKB9r9/PLP5lrN+ZL1Qtt3brVGVB8iY+ioBXhlFue2JtycBczE8Pw==",
- "dependencies": {
- "Castle.Core": "4.4.0",
- "System.Threading.Tasks.Extensions": "4.5.1"
- }
- },
- "xunit": {
- "type": "Direct",
- "requested": "[2.4.1, )",
- "resolved": "2.4.1",
- "contentHash": "XNR3Yz9QTtec16O0aKcO6+baVNpXmOnPUxDkCY97J+8krUYxPvXT1szYYEUdKk4sB8GOI2YbAjRIOm8ZnXRfzQ==",
- "dependencies": {
- "xunit.analyzers": "0.10.0",
- "xunit.assert": "[2.4.1]",
- "xunit.core": "[2.4.1]"
- }
- },
- "xunit.runner.visualstudio": {
- "type": "Direct",
- "requested": "[2.4.3, )",
- "resolved": "2.4.3",
- "contentHash": "kZZSmOmKA8OBlAJaquPXnJJLM9RwQ27H7BMVqfMLUcTi9xHinWGJiWksa3D4NEtz0wZ/nxd2mogObvBgJKCRhQ=="
- },
- "AutoMapper": {
- "type": "Transitive",
- "resolved": "10.1.1",
- "contentHash": "uMgbqOdu9ZG5cIOty0C85hzzayBH2i9BthnS5FlMqKtMSHDv4ts81a2jS1VFaDBVhlBeIqJ/kQKjQY95BZde9w==",
- "dependencies": {
- "Microsoft.CSharp": "4.7.0",
- "System.Reflection.Emit": "4.7.0"
- }
- },
- "AutoMapper.Extensions.Microsoft.DependencyInjection": {
- "type": "Transitive",
- "resolved": "8.1.0",
- "contentHash": "dQyGCAYcHbGuimVvCMu4Ea2S1oYOlgO9XfVdClmY5wgygJMZoS57emPzH0qNfknmtzMm4QbDO9i237W5IDjU1A==",
- "dependencies": {
- "AutoMapper": "[10.1.0, 11.0.0)",
- "Microsoft.Extensions.DependencyInjection.Abstractions": "3.0.0",
- "Microsoft.Extensions.Options": "3.0.0"
- }
- },
- "Castle.Core": {
- "type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "b5rRL5zeaau1y/5hIbI+6mGw3cwun16YjkHZnV9RRT5UyUIFsgLmNXJ0YnIN9p8Hw7K7AbG1q1UclQVU3DinAQ==",
- "dependencies": {
- "NETStandard.Library": "1.6.1",
- "System.Collections.Specialized": "4.3.0",
- "System.ComponentModel": "4.3.0",
- "System.ComponentModel.TypeConverter": "4.3.0",
- "System.Diagnostics.TraceSource": "4.3.0",
- "System.Dynamic.Runtime": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Emit": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Xml.XmlDocument": "4.3.0"
- }
- },
- "Microsoft.AspNetCore.Authorization": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "cN2KJkfHcKwh82c9WGx4Tqfd2h5HflU/Mu5vYLMHON8WahHU9hE32ciIXcEIoKLNpu+zs1u1cN/qxcKTdqu89w==",
- "dependencies": {
- "Microsoft.Extensions.Logging.Abstractions": "1.0.2",
- "Microsoft.Extensions.Options": "1.0.2",
- "System.Security.Claims": "4.0.1"
- }
- },
- "Microsoft.AspNetCore.Hosting.Abstractions": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "ybY8FOkdNfBPB5PLv1JO+It/94ftBzGUI1WqU4XySbIWyhw2TPmmKAUuO9uvJoR0qpsFup8FJz6trsBcBITg9w==",
- "dependencies": {
- "Microsoft.AspNetCore.Hosting.Server.Abstractions": "1.0.4",
- "Microsoft.AspNetCore.Http.Abstractions": "1.0.3",
- "Microsoft.Extensions.Configuration.Abstractions": "1.0.2",
- "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.2",
- "Microsoft.Extensions.FileProviders.Abstractions": "1.0.1",
- "Microsoft.Extensions.Logging.Abstractions": "1.0.2"
- }
- },
- "Microsoft.AspNetCore.Hosting.Server.Abstractions": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "XUiQPe/CflK1i0Voo9S6/G1iQh00gQ6sMqi3LRtKeceBbO6AOostaAUdhjyME92MapI4VFNl+Z+/KXUlMAExJQ==",
- "dependencies": {
- "Microsoft.AspNetCore.Http.Features": "1.0.3",
- "Microsoft.Extensions.Configuration.Abstractions": "1.0.2"
- }
- },
- "Microsoft.AspNetCore.Http": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "kfNOIGGgVtMzsSWZzXBqz5zsdo8ssBa90YHzZt95N8ARGXoolSaBHy6yBoMm/XcpbXM+m/x1fixTTMIWMgzJdQ==",
- "dependencies": {
- "Microsoft.AspNetCore.Http.Abstractions": "1.0.3",
- "Microsoft.AspNetCore.WebUtilities": "1.0.3",
- "Microsoft.Extensions.ObjectPool": "1.0.1",
- "Microsoft.Extensions.Options": "1.0.2",
- "Microsoft.Net.Http.Headers": "1.0.3",
- "System.Buffers": "4.0.0",
- "System.Threading": "4.0.11"
- }
- },
- "Microsoft.AspNetCore.Http.Abstractions": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "nnjvAf7ag6P0DyD/0nhRGjLpv+3DkPU0juF8aQh46X8uF4kzjJdrh65oL+4PVOu3K6BgSg6OVUs0QC0SE0FRtg==",
- "dependencies": {
- "Microsoft.AspNetCore.Http.Features": "1.0.3",
- "System.Globalization.Extensions": "4.0.1",
- "System.Linq.Expressions": "4.1.1",
- "System.Reflection.TypeExtensions": "4.1.0",
- "System.Runtime.InteropServices": "4.1.0",
- "System.Text.Encodings.Web": "4.0.1"
- }
- },
- "Microsoft.AspNetCore.Http.Extensions": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "+7Sd+14nexIJqcB4S1Eur9kzeMZ5CBtrxkei+PNbD78fg8vO3+TcCgrl5SBNTsUB/VJAfD/s0fgs5t+hHRj2Pg==",
- "dependencies": {
- "Microsoft.AspNetCore.Http.Abstractions": "1.0.3",
- "Microsoft.Extensions.FileProviders.Abstractions": "1.0.1",
- "Microsoft.Net.Http.Headers": "1.0.3",
- "System.Buffers": "4.0.0",
- "System.IO.FileSystem": "4.0.1"
- }
- },
- "Microsoft.AspNetCore.Http.Features": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "Ihq57tseNyPbJTmFXY4jQ4JkxLP0lh45VRwocQci/sFx+qcJGvWB+sJJ2/YPLy/qTWFAEfNAcswuY3OsNH9Gwg==",
- "dependencies": {
- "Microsoft.Extensions.Primitives": "1.0.1",
- "System.Collections": "4.0.11",
- "System.ComponentModel": "4.0.1",
- "System.Linq": "4.1.0",
- "System.Net.Primitives": "4.0.11",
- "System.Net.WebSockets": "4.0.0",
- "System.Runtime.Extensions": "4.1.0",
- "System.Security.Claims": "4.0.1",
- "System.Security.Cryptography.X509Certificates": "4.1.0",
- "System.Security.Principal": "4.0.1"
- }
- },
- "Microsoft.AspNetCore.JsonPatch": {
- "type": "Transitive",
- "resolved": "1.0.0",
- "contentHash": "WVaSVS+dDlWCR/qerHnBxU9tIeJ9GMA3M5tg4cxH7/cJYZZLnr2zvaFHGB+cRRNCKKTJ0pFRxT7ES8knhgAAaA==",
- "dependencies": {
- "Microsoft.CSharp": "4.0.1",
- "Newtonsoft.Json": "9.0.1",
- "System.Collections.Concurrent": "4.0.12",
- "System.ComponentModel.TypeConverter": "4.1.0",
- "System.Diagnostics.Debug": "4.0.11",
- "System.Globalization": "4.0.11",
- "System.Linq": "4.1.0",
- "System.Reflection.Extensions": "4.0.1",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime.Extensions": "4.1.0",
- "System.Runtime.Serialization.Primitives": "4.1.1",
- "System.Text.Encoding.Extensions": "4.0.11"
- }
- },
- "Microsoft.AspNetCore.Mvc.Abstractions": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "Isqgif1nuB+um86cEkpL8KnoxFCUCXBsbs9PuiuzElvlSiv4Ek3LvtrSUcbivekDDfys8CDbJhxwEI7WKJieAQ==",
- "dependencies": {
- "Microsoft.AspNetCore.Routing.Abstractions": "1.0.4",
- "Microsoft.CSharp": "4.0.1",
- "Microsoft.Net.Http.Headers": "1.0.3",
- "System.ComponentModel.TypeConverter": "4.1.0",
- "System.Reflection.Extensions": "4.0.1",
- "System.Text.Encoding.Extensions": "4.0.11"
- }
- },
- "Microsoft.AspNetCore.Mvc.ApiExplorer": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "ujCFTM42U2WKUBhdaoLoiI+wVHgYhrmDrkl5+hWJ7EJW4fhp42w4cRZ97tjuveWr+M6JZjpS0q+7PVofQzFUiw==",
- "dependencies": {
- "Microsoft.AspNetCore.Mvc.Core": "1.0.4"
- }
- },
- "Microsoft.AspNetCore.Mvc.Core": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "1ukcttN1+T82hWXE8WS5kawkruolKI6LPVqVI4rTzN16kFszS/UqTrcwSUEnmTRpmWgFo665V3c2GpdQ9B6znw==",
- "dependencies": {
- "Microsoft.AspNetCore.Authorization": "1.0.3",
- "Microsoft.AspNetCore.Hosting.Abstractions": "1.0.3",
- "Microsoft.AspNetCore.Http": "1.0.3",
- "Microsoft.AspNetCore.Mvc.Abstractions": "1.0.4",
- "Microsoft.AspNetCore.Routing": "1.0.4",
- "Microsoft.Extensions.DependencyModel": "1.0.0",
- "Microsoft.Extensions.FileProviders.Abstractions": "1.0.1",
- "Microsoft.Extensions.Logging.Abstractions": "1.0.2",
- "Microsoft.Extensions.PlatformAbstractions": "1.0.0",
- "System.Buffers": "4.0.0",
- "System.Diagnostics.DiagnosticSource": "4.0.0",
- "System.Text.Encoding": "4.0.11"
- }
- },
- "Microsoft.AspNetCore.Mvc.Formatters.Json": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "i8WWK2GwlBHfOL+d+kknJWPks6DS9tbN6nfJZU4yb+/wfUAYd311B2CIHzdat3IewubnK1TYONwrhQcs2FbLeA==",
- "dependencies": {
- "Microsoft.AspNetCore.JsonPatch": "1.0.0",
- "Microsoft.AspNetCore.Mvc.Core": "1.0.4"
- }
- },
- "Microsoft.AspNetCore.NodeServices": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "bbd3FlSPWiRQrIcBLa5TaOvo4gjmmiNMkxA8VmZ6u0eIpS0Yj35/eTopaGdtzqwlqj5jXbdRoib1MruXuPaW8A==",
- "dependencies": {
- "Microsoft.Extensions.Logging.Console": "3.1.9",
- "Newtonsoft.Json": "12.0.2"
- }
- },
- "Microsoft.AspNetCore.Routing": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "mdIF3ckRothHWuCSFkk6YXACj5zxi5qM+cEAHjcpP04/wCHUoV0gGVnW+HI+LyFXE6JUwu2zXn5tfsCpW0U+SA==",
- "dependencies": {
- "Microsoft.AspNetCore.Http.Extensions": "1.0.3",
- "Microsoft.AspNetCore.Routing.Abstractions": "1.0.4",
- "Microsoft.Extensions.Logging.Abstractions": "1.0.2",
- "Microsoft.Extensions.ObjectPool": "1.0.1",
- "Microsoft.Extensions.Options": "1.0.2",
- "System.Collections": "4.0.11",
- "System.Text.RegularExpressions": "4.1.0"
- }
- },
- "Microsoft.AspNetCore.Routing.Abstractions": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "GHxVt6LlXHFsCUd2Un+/vY1tBTXxnogfbDO0b8G5EGmkapSK+dOGOLJviscxQkp338Uabs081JEIdkRymI5GXA==",
- "dependencies": {
- "Microsoft.AspNetCore.Http.Abstractions": "1.0.3",
- "System.Collections.Concurrent": "4.0.12",
- "System.Reflection.Extensions": "4.0.1",
- "System.Threading.Tasks": "4.0.11"
- }
- },
- "Microsoft.AspNetCore.SpaServices": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "Fb+N2ZyF1wNrGeWggT+Ovv6W8AAVxfi4V/SnuEsBOR+nmkFhty9zyh6IDRRS98GJK6OE3adqqPbWMtJqbxYnNA==",
- "dependencies": {
- "Microsoft.AspNetCore.NodeServices": "3.1.9"
- }
- },
- "Microsoft.AspNetCore.SpaServices.Extensions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "ciy2GCvRnh9C22laArLsaItS+72U6Hqf4nDYShdvFgcen2ZV+NNSitb/B3vsmFfIPM8m4mf2x4T+vZ6OlI5XaA==",
- "dependencies": {
- "Microsoft.AspNetCore.SpaServices": "3.1.9",
- "Microsoft.Extensions.FileProviders.Physical": "3.1.9"
- }
- },
- "Microsoft.AspNetCore.StaticFiles": {
- "type": "Transitive",
- "resolved": "1.0.4",
- "contentHash": "2pNvwewAazhaaCdw2CGUvIcDrNQMlqP57JgBDf3v+pRj1rZ29HVnpvkX6a+TrmRYlJNmmxHOKEt468uE/gDcFw==",
- "dependencies": {
- "Microsoft.AspNetCore.Hosting.Abstractions": "1.0.4",
- "Microsoft.AspNetCore.Http.Extensions": "1.0.3",
- "Microsoft.Extensions.FileProviders.Abstractions": "1.0.1",
- "Microsoft.Extensions.Logging.Abstractions": "1.0.2",
- "Microsoft.Extensions.WebEncoders": "1.0.3"
- }
- },
- "Microsoft.AspNetCore.WebUtilities": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "snSGNs5EEisqivDjDiskFkFyu+DV2Ib9sMPOBQKtoFwI5H1W5YNB/rIVqDZQL16zj/uzdwwxrdE/5xhkVyf6gQ==",
- "dependencies": {
- "Microsoft.Extensions.Primitives": "1.0.1",
- "System.Buffers": "4.0.0",
- "System.Collections": "4.0.11",
- "System.IO": "4.1.0",
- "System.IO.FileSystem": "4.0.1",
- "System.Text.Encodings.Web": "4.0.1"
- }
- },
- "Microsoft.Bcl.AsyncInterfaces": {
- "type": "Transitive",
- "resolved": "1.1.1",
- "contentHash": "yuvf07qFWFqtK3P/MRkEKLhn5r2UbSpVueRziSqj0yJQIKFwG1pq9mOayK3zE5qZCTs0CbrwL9M6R8VwqyGy2w=="
- },
- "Microsoft.Bcl.HashCode": {
- "type": "Transitive",
- "resolved": "1.1.0",
- "contentHash": "J2G1k+u5unBV+aYcwxo94ip16Rkp65pgWFb0R6zwJipzWNMgvqlWeuI7/+R+e8bob66LnSG+llLJ+z8wI94cHg=="
- },
- "Microsoft.CodeAnalysis.VersionCheckAnalyzer": {
- "type": "Transitive",
- "resolved": "3.3.0",
- "contentHash": "xjLM3DRFZMan3nQyBQEM1mBw6VqQybi4iMJhMFW6Ic1E1GCvqJR3ABOwEL7WtQjDUzxyrGld9bASnAos7G/Xyg=="
- },
- "Microsoft.CodeCoverage": {
- "type": "Transitive",
- "resolved": "16.7.1",
- "contentHash": "PhSppbk+kvAyD9yGJIcBRJ/XYwY+21YK88l22PGTtixaxNdjnx1idVKh88LCGwKaTL8HhlnQ41VmBiBdZJzIQw=="
- },
- "Microsoft.CodeQuality.Analyzers": {
- "type": "Transitive",
- "resolved": "3.3.0",
- "contentHash": "zZ3miq6u22UFQKhfJyLnVEJ+DgeOopLh3eKJnKAcOetPP2hiv3wa7kHZlBDeTvtqJQiAQhAVbttket8XxjN1zw=="
- },
- "Microsoft.CSharp": {
- "type": "Transitive",
- "resolved": "4.7.0",
- "contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
- },
- "Microsoft.Data.Sqlite.Core": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "+u4PeT1npi2EzhxGc5r1Z2z73zuXw+TlKVZm44WQhNCUw4LtUVDaxGSpUhrjW+X4snBCBfr4kT/uJyKnL4R4og==",
- "dependencies": {
- "SQLitePCLRaw.core": "2.0.2"
- }
- },
- "Microsoft.DotNet.PlatformAbstractions": {
- "type": "Transitive",
- "resolved": "3.1.6",
- "contentHash": "jek4XYaQ/PGUwDKKhwR8K47Uh1189PFzMeLqO83mXrXQVIpARZCcfuDedH50YDTepBkfijCZN5U/vZi++erxtg=="
- },
- "Microsoft.EntityFrameworkCore": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "u3A2W0BvAuAF2jgW+WX+C+Sh8sMGX5Kl1hdA0gu6A/XSrZQoW/BUP4a/q2n3iitDGndaorqjAKx+Spb9gBto+w==",
- "dependencies": {
- "Microsoft.Bcl.AsyncInterfaces": "1.1.1",
- "Microsoft.Bcl.HashCode": "1.1.0",
- "Microsoft.EntityFrameworkCore.Abstractions": "3.1.9",
- "Microsoft.EntityFrameworkCore.Analyzers": "3.1.9",
- "Microsoft.Extensions.Caching.Memory": "3.1.9",
- "Microsoft.Extensions.DependencyInjection": "3.1.9",
- "Microsoft.Extensions.Logging": "3.1.9",
- "System.Collections.Immutable": "1.7.1",
- "System.ComponentModel.Annotations": "4.7.0",
- "System.Diagnostics.DiagnosticSource": "4.7.1"
- }
- },
- "Microsoft.EntityFrameworkCore.Abstractions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "IR6Y4RJVlw0QXdWXjF3Kx9s1QLiicJus+BFBKr43lBtriV20j3yrWMoaZ9W1AUUgnicZXpXVcNfklqtmwb9Sxw=="
- },
- "Microsoft.EntityFrameworkCore.Analyzers": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "eXGyx/Lb1fiiKtnIStdxGrfBSSQg8oZytE10f1T/2xAx12W9dKB9U9fg05cwNCDC0S2CXILsmZHYaGqCSXVAqQ=="
- },
- "Microsoft.EntityFrameworkCore.Relational": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "7fhWuSfrCYlv/hvOX5OhbFJF/G9f8sifqTrJiYnAYLDOvNizwv7t9tFPD8JwaF3zM2S54O5/Vni2NxvwzSaW2w==",
- "dependencies": {
- "Microsoft.EntityFrameworkCore": "3.1.9"
- }
- },
- "Microsoft.EntityFrameworkCore.Sqlite": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "sMFCWv/1UcsFQZeGQcbfPbEZKZ1oKZqWZXTbc7PEZVMIXu82nbavstdNQ84x5IBXJkxl8iW3zjChb/FRBr5uLQ==",
- "dependencies": {
- "Microsoft.EntityFrameworkCore.Sqlite.Core": "3.1.9",
- "SQLitePCLRaw.bundle_e_sqlite3": "2.0.2"
- }
- },
- "Microsoft.EntityFrameworkCore.Sqlite.Core": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "Da6h8LdpJwKc1az9DMWt2Mt6gHXPRZqwiumV1Zx0AuM3EThyokVDzBGy2sti0AcBhcQMLJHPEr5R9xuiWvaYYQ==",
- "dependencies": {
- "Microsoft.Data.Sqlite.Core": "3.1.9",
- "Microsoft.DotNet.PlatformAbstractions": "3.1.6",
- "Microsoft.EntityFrameworkCore.Relational": "3.1.9",
- "Microsoft.Extensions.DependencyModel": "3.1.6"
- }
- },
- "Microsoft.Extensions.ApiDescription.Server": {
- "type": "Transitive",
- "resolved": "3.0.0",
- "contentHash": "LH4OE/76F6sOCslif7+Xh3fS/wUUrE5ryeXAMcoCnuwOQGT5Smw0p57IgDh/pHgHaGz/e+AmEQb7pRgb++wt0w=="
- },
- "Microsoft.Extensions.Caching.Abstractions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "/2QsPAsUZD4qvftZkUKHRRRryPDXWh606/iNXPLrulwHLMr9JNsKBJWVqylT3qU92nJok5VoqSblkY9mSyxFyg==",
- "dependencies": {
- "Microsoft.Extensions.Primitives": "3.1.9"
- }
- },
- "Microsoft.Extensions.Caching.Memory": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "/JrVMVetX/kpJQUIlJ6NLQ3zbF0yyryXpo4+uFCqYIUZzgmWk8DS/zSKcyj1tQ3410+vhDEAPngxC+hg0IlJeg==",
- "dependencies": {
- "Microsoft.Extensions.Caching.Abstractions": "3.1.9",
- "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.9",
- "Microsoft.Extensions.Logging.Abstractions": "3.1.9",
- "Microsoft.Extensions.Options": "3.1.9"
- }
- },
- "Microsoft.Extensions.Configuration": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "lqdkOGNeTMKG981Q7yWGlRiFbIlsRwTlMMiybT+WOzUCFBS/wc25tZgh7Wm/uRoBbWefgvokzmnea7ZjmFedmA==",
- "dependencies": {
- "Microsoft.Extensions.Configuration.Abstractions": "3.1.9"
- }
- },
- "Microsoft.Extensions.Configuration.Abstractions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "vOJxPKczaHpXeZFrxARxYwsEulhEouXc5aZGgMdkhV/iEXX9/pfjqKk76rTG+4CsJjHV+G/4eMhvOIaQMHENNA==",
- "dependencies": {
- "Microsoft.Extensions.Primitives": "3.1.9"
- }
- },
- "Microsoft.Extensions.Configuration.Binder": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "BG6HcT7tARYakftqfQu+cLksgIWG1NdxMY+igI12hdZrUK+WjS973NiRyuao/U9yyTeM9NPwRnC61hCmG3G3jg==",
- "dependencies": {
- "Microsoft.Extensions.Configuration": "3.1.9"
- }
- },
- "Microsoft.Extensions.DependencyInjection": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "ORqfrAACcvTInie1oGola5uky344/PiNfgayTPuZWV4WnSfIQZJQm/ZLpGshJE3h7TqwYaYElGazK/yaM2bFLA==",
- "dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.9"
- }
- },
- "Microsoft.Extensions.DependencyInjection.Abstractions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "8PkcaPwiTPOhqshoY4+rQUbz86X6YpLDLUqXOezh7L2A3pgpBmeBBByYIffofBlvQxDdQ0zB2DkWjbZWyCxRWg=="
- },
- "Microsoft.Extensions.DependencyModel": {
- "type": "Transitive",
- "resolved": "3.1.6",
- "contentHash": "/UlDKULIVkLQYn1BaHcy/rc91ApDxJb7T75HcCbGdqwvxhnRQRKM2di1E70iCPMF9zsr6f4EgQTotBGxFIfXmw==",
- "dependencies": {
- "System.Text.Json": "4.7.2"
- }
- },
- "Microsoft.Extensions.FileProviders.Abstractions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "Q4SGwEFZKiZbpzPgdGbQUULxtcH1zXMOwCPKSm6QwVcOCGshf3QLfBh+O/GyFH4B0RfZ16nKyeW1mMONlRyjUw==",
- "dependencies": {
- "Microsoft.Extensions.Primitives": "3.1.9"
- }
- },
- "Microsoft.Extensions.FileProviders.Embedded": {
- "type": "Transitive",
- "resolved": "1.0.1",
- "contentHash": "nSEa8bH3fVdTYGqK4twOKLxxgKIW3cz9g9mrzhPh/CmdvGJWKRTIlBIZi7lz+lqNQpxean5vbAo84R/mU+JpGA==",
- "dependencies": {
- "Microsoft.Extensions.FileProviders.Abstractions": "1.0.1",
- "System.Runtime.Extensions": "4.1.0"
- }
- },
- "Microsoft.Extensions.FileProviders.Physical": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "HWDSsblTCQp7EEJJmnLzttIhFGzDu+DGqBbOvGCdFT0+pkCuBkn3EiWpEEcm5WMTO5njmsbLSK9ZuUUf2zPsFg==",
- "dependencies": {
- "Microsoft.Extensions.FileProviders.Abstractions": "3.1.9",
- "Microsoft.Extensions.FileSystemGlobbing": "3.1.9"
- }
- },
- "Microsoft.Extensions.FileSystemGlobbing": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "5bnewG1aBiSESPNwcXGIxDDRN95uqdy+fqZZ8Z63Et5rRNlAwAfXHOrg+FTht7UjHobjvtjzquMCbAWhWEPHIw=="
- },
- "Microsoft.Extensions.Logging": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "+V3i0jCQCO6IIOf6e+fL0SqrZd2x/Krug9EEL1JHa9R03RsbEpltCtjVY5hxedyuyuQKwvLoR12sCfu/9XEUAw==",
- "dependencies": {
- "Microsoft.Extensions.Configuration.Binder": "3.1.9",
- "Microsoft.Extensions.DependencyInjection": "3.1.9",
- "Microsoft.Extensions.Logging.Abstractions": "3.1.9",
- "Microsoft.Extensions.Options": "3.1.9"
- }
- },
- "Microsoft.Extensions.Logging.Abstractions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "W5fbF8qVR9SMVVJqDQLIR7meWbev6Pu/lbrm7LDNr4Sp7HOotr4k2UULTdFSXOi5aoDdkQZpWnq0ZSpjrR3tjg=="
- },
- "Microsoft.Extensions.Logging.Configuration": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "hv6XsGgikrbkolBJdF1usl9R/nrliC5mifMqHMEY9zWcCLwNkXMJiS8p0lbosrnpVAMi4PbNx39DB51Dqscd0w==",
- "dependencies": {
- "Microsoft.Extensions.Logging": "3.1.9",
- "Microsoft.Extensions.Options.ConfigurationExtensions": "3.1.9"
- }
- },
- "Microsoft.Extensions.Logging.Console": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "8Dusl1rkDivmvLrwj6QAo917xMHPiDBzG3IG3agiyDdtsC/fRp+1VN5iIN+O09PtEaMged2OLA6wCDwfSTSTZw==",
- "dependencies": {
- "Microsoft.Extensions.Configuration.Abstractions": "3.1.9",
- "Microsoft.Extensions.Logging": "3.1.9",
- "Microsoft.Extensions.Logging.Configuration": "3.1.9"
- }
- },
- "Microsoft.Extensions.ObjectPool": {
- "type": "Transitive",
- "resolved": "1.0.1",
- "contentHash": "pJMOnxuqmG37OjccfvtqVoo3bQGoN+0EJUzzp7+2uxSdioER82caAk6Yi/z5aysapn5XENNIIa7SaYnYKSS69A==",
- "dependencies": {
- "System.Diagnostics.Debug": "4.0.11",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime.Extensions": "4.1.0",
- "System.Threading": "4.0.11"
- }
- },
- "Microsoft.Extensions.Options": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "EIb3G1DL+Rl9MvJR7LjI1wCy2nfTN4y8MflbOftn1HLYQBj/Rwl8kUbGTrSFE01c99Wm4ETjWVsjqKcpFvhPng==",
- "dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.9",
- "Microsoft.Extensions.Primitives": "3.1.9"
- }
- },
- "Microsoft.Extensions.Options.ConfigurationExtensions": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "u5jh7RW+Ev81YqK1ZoBG0lftp2MA9xqXiTiRL46XzaPj2ScNUyiVbzcVY0fPbE27UOpT2hj+yPzRSOMIIo55UA==",
- "dependencies": {
- "Microsoft.Extensions.Configuration.Abstractions": "3.1.9",
- "Microsoft.Extensions.Configuration.Binder": "3.1.9",
- "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.9",
- "Microsoft.Extensions.Options": "3.1.9"
- }
- },
- "Microsoft.Extensions.PlatformAbstractions": {
- "type": "Transitive",
- "resolved": "1.0.0",
- "contentHash": "zyjUzrOmuevOAJpIo3Mt5GmpALVYCVdLZ99keMbmCxxgQH7oxzU58kGHzE6hAgYEiWsdfMJLjVR7r+vSmaJmtg==",
- "dependencies": {
- "System.AppContext": "4.1.0",
- "System.Reflection": "4.1.0",
- "System.Reflection.Extensions": "4.0.1",
- "System.Reflection.TypeExtensions": "4.1.0",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime.Extensions": "4.1.0"
- }
- },
- "Microsoft.Extensions.Primitives": {
- "type": "Transitive",
- "resolved": "3.1.9",
- "contentHash": "IrHecH0eGG7/XoeEtv++oLg/sJHRNyeCqlA9RhAo6ig4GpOTjtDr32sBMYuuLtUq8ALahneWkrOzoBAwJ4L4iA=="
- },
- "Microsoft.Extensions.WebEncoders": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "TClNvczWRxF6bVPhn5EK3Y3QNi5jTP68Qur+5Fk+MQLPeBI18WN7X145DDJ6bFeNOwgdCHl73lHs5uZp9ish1A==",
- "dependencies": {
- "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.2",
- "Microsoft.Extensions.Options": "1.0.2",
- "System.Text.Encodings.Web": "4.0.1"
- }
- },
- "Microsoft.IdentityModel.JsonWebTokens": {
- "type": "Transitive",
- "resolved": "6.8.0",
- "contentHash": "+7JIww64PkMt7NWFxoe4Y/joeF7TAtA/fQ0b2GFGcagzB59sKkTt/sMZWR6aSZht5YC7SdHi3W6yM1yylRGJCQ==",
- "dependencies": {
- "Microsoft.IdentityModel.Tokens": "6.8.0"
- }
- },
- "Microsoft.IdentityModel.Logging": {
- "type": "Transitive",
- "resolved": "6.8.0",
- "contentHash": "Rfh/p4MaN4gkmhPxwbu8IjrmoDncGfHHPh1sTnc0AcM/Oc39/fzC9doKNWvUAjzFb8LqA6lgZyblTrIsX/wDXg=="
- },
- "Microsoft.IdentityModel.Tokens": {
- "type": "Transitive",
- "resolved": "6.8.0",
- "contentHash": "gTqzsGcmD13HgtNePPcuVHZ/NXWmyV+InJgalW/FhWpII1D7V1k0obIseGlWMeA4G+tZfeGMfXr0klnWbMR/mQ==",
- "dependencies": {
- "Microsoft.CSharp": "4.5.0",
- "Microsoft.IdentityModel.Logging": "6.8.0",
- "System.Security.Cryptography.Cng": "4.5.0"
- }
- },
- "Microsoft.Net.Http.Headers": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "2F8USh4hR5xppvaxtw2EStX74Ih+HhRj7aQD1uaB9JmTGy478F7t4VU+IdZXauEDrvS7LYAyyhmOExsUFK3PAw==",
- "dependencies": {
- "System.Buffers": "4.0.0",
- "System.Collections": "4.0.11",
- "System.Diagnostics.Contracts": "4.0.1",
- "System.Globalization": "4.0.11",
- "System.Linq": "4.1.0",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime.Extensions": "4.1.0",
- "System.Text.Encoding": "4.0.11"
- }
- },
- "Microsoft.NetCore.Analyzers": {
- "type": "Transitive",
- "resolved": "3.3.0",
- "contentHash": "6qptTHUu1Wfszuf83NhU0IoAb4j7YWOpJs6oc6S4G/nI6aGGWKH/Xi5Vs9L/8lrI74ijEEzPcIwafSQW5ASHtA=="
- },
- "Microsoft.NETCore.Platforms": {
- "type": "Transitive",
- "resolved": "1.1.0",
- "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
- },
- "Microsoft.NETCore.Targets": {
- "type": "Transitive",
- "resolved": "1.1.0",
- "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg=="
- },
- "Microsoft.NetFramework.Analyzers": {
- "type": "Transitive",
- "resolved": "3.3.0",
- "contentHash": "JTfMic5fEFWICePbr7GXOGPranqS9Qxu2U/BZEcnnGbK1SFW8TxRyGp6O1L52xsbfOdqmzjc0t5ubhDrjj+Xpg=="
- },
- "Microsoft.TestPlatform.ObjectModel": {
- "type": "Transitive",
- "resolved": "16.7.1",
- "contentHash": "FL+VpAC/nCCzj80MwX6L8gJD06u2m1SKcQQLAymDLFqNtgtI9h3J5n0mVN+s18qcMzybsmO9GK7rMuHYx11KMg==",
- "dependencies": {
- "NuGet.Frameworks": "5.0.0"
- }
- },
- "Microsoft.TestPlatform.TestHost": {
- "type": "Transitive",
- "resolved": "16.7.1",
- "contentHash": "mv7MnBDtqwQAjoH+AphE+Tu0dsF6x/c7Zs8umkb2McbvNALJdfBuWJQbiXGWqhNq7k8eMmnkNO6klJz4pkgekw==",
- "dependencies": {
- "Microsoft.TestPlatform.ObjectModel": "16.7.1",
- "Newtonsoft.Json": "9.0.1"
- }
- },
- "Microsoft.Win32.Primitives": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "Namotion.Reflection": {
- "type": "Transitive",
- "resolved": "1.0.14",
- "contentHash": "wuJGiFvGfehH2w7jAhMbCJt0/rvUuHyqSZn0sMhNTviDfBZRyX8LFlR/ndQcofkGWulPDfH5nKYTeGXE8xBHPA==",
- "dependencies": {
- "Microsoft.CSharp": "4.3.0"
- }
- },
- "NETStandard.Library": {
- "type": "Transitive",
- "resolved": "1.6.1",
- "contentHash": "WcSp3+vP+yHNgS8EV5J7pZ9IRpeDuARBPN28by8zqff1wJQXm26PVU8L3/fYLBJVU7BtDyqNVWq2KlCVvSSR4A==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.Win32.Primitives": "4.3.0",
- "System.AppContext": "4.3.0",
- "System.Collections": "4.3.0",
- "System.Collections.Concurrent": "4.3.0",
- "System.Console": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Diagnostics.Tools": "4.3.0",
- "System.Diagnostics.Tracing": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Globalization.Calendars": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.Compression": "4.3.0",
- "System.IO.Compression.ZipFile": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.IO.FileSystem.Primitives": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Linq.Expressions": "4.3.0",
- "System.Net.Http": "4.3.0",
- "System.Net.Primitives": "4.3.0",
- "System.Net.Sockets": "4.3.0",
- "System.ObjectModel": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Runtime.InteropServices.RuntimeInformation": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "System.Security.Cryptography.Encoding": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Security.Cryptography.X509Certificates": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Text.Encoding.Extensions": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "System.Threading.Timer": "4.3.0",
- "System.Xml.ReaderWriter": "4.3.0",
- "System.Xml.XDocument": "4.3.0"
- }
- },
- "Newtonsoft.Json": {
- "type": "Transitive",
- "resolved": "12.0.2",
- "contentHash": "rTK0s2EKlfHsQsH6Yx2smvcTCeyoDNgCW7FEYyV01drPlh2T243PR2DiDXqtC5N4GDm4Ma/lkxfW5a/4793vbA=="
- },
- "Newtonsoft.Json.Bson": {
- "type": "Transitive",
- "resolved": "1.0.1",
- "contentHash": "5PYT/IqQ+UK31AmZiSS102R6EsTo+LGTSI8bp7WAUqDKaF4wHXD8U9u4WxTI1vc64tYi++8p3dk3WWNqPFgldw==",
- "dependencies": {
- "NETStandard.Library": "1.6.1",
- "Newtonsoft.Json": "10.0.1"
- }
- },
- "NJsonSchema": {
- "type": "Transitive",
- "resolved": "10.2.1",
- "contentHash": "/BtWbYTusyoSgQkCB4eYijMfZotB/rfASDsl1k9evlkm5vlOP4s4Y09TOzBChU77d/qUABVYL1Xf+TB8E0Wfpw==",
- "dependencies": {
- "Namotion.Reflection": "1.0.14",
- "Newtonsoft.Json": "9.0.1"
- }
- },
- "NSwag.Annotations": {
- "type": "Transitive",
- "resolved": "13.8.2",
- "contentHash": "/GO+35CjPYQTPS5/Q8udM5JAMEWVo8JsrkV2Uw3OW4/AJU9iOS7t6WJid6ZlkpLMjnW7oex9mvJ2EZNE4eOG/Q=="
- },
- "NSwag.AspNetCore": {
- "type": "Transitive",
- "resolved": "13.8.2",
- "contentHash": "SNGlVSZoMyywBWueZBxl3B/nfaIM0fAcuNhTD/cfMKUn3Cn/Oi8d45HZY5vAPqczvppTbk4cZXyVwWDOfgiPbA==",
- "dependencies": {
- "Microsoft.AspNetCore.Mvc.Core": "1.0.4",
- "Microsoft.AspNetCore.Mvc.Formatters.Json": "1.0.4",
- "Microsoft.AspNetCore.StaticFiles": "1.0.4",
- "Microsoft.Extensions.ApiDescription.Server": "3.0.0",
- "Microsoft.Extensions.FileProviders.Embedded": "1.0.1",
- "NSwag.Annotations": "13.8.2",
- "NSwag.Core": "13.8.2",
- "NSwag.Generation": "13.8.2",
- "NSwag.Generation.AspNetCore": "13.8.2",
- "System.IO.FileSystem": "4.3.0",
- "System.Xml.XPath.XDocument": "4.0.1"
- }
- },
- "NSwag.Core": {
- "type": "Transitive",
- "resolved": "13.8.2",
- "contentHash": "Hm6pU9qFJuXLo3b27+JTXztfeuI/15Ob1sDsfUu4rchN0+bMogtn8Lia8KVbcalw/M+hXc0rWTFp5ueP23e+iA==",
- "dependencies": {
- "NJsonSchema": "10.2.1",
- "Newtonsoft.Json": "9.0.1"
- }
- },
- "NSwag.Generation": {
- "type": "Transitive",
- "resolved": "13.8.2",
- "contentHash": "LBIrpHFRZeMMbqL1hdyGb7r8v+T52aOCARxwfAmzE+MlOHVpjsIxyNSXht9EzBFMbSH0tj7CK2Ugo7bm+zUssg==",
- "dependencies": {
- "NJsonSchema": "10.2.1",
- "NSwag.Core": "13.8.2",
- "Newtonsoft.Json": "9.0.1"
- }
- },
- "NSwag.Generation.AspNetCore": {
- "type": "Transitive",
- "resolved": "13.8.2",
- "contentHash": "0ydVv6OidspZ/MS6qmU8hswGtXwq5YZPg+2a2PHGD6jNp2Fef4j1wC3xa3hplDAq7cK+BgpyDKtvj9+X01+P5g==",
- "dependencies": {
- "Microsoft.AspNetCore.Mvc.ApiExplorer": "1.0.4",
- "Microsoft.AspNetCore.Mvc.Core": "1.0.4",
- "Microsoft.AspNetCore.Mvc.Formatters.Json": "1.0.4",
- "NJsonSchema": "10.2.1",
- "NSwag.Generation": "13.8.2"
- }
- },
- "NuGet.Frameworks": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "c5JVjuVAm4f7E9Vj+v09Z9s2ZsqFDjBpcsyS3M9xRo0bEdm/LVZSzLxxNvfvAwRiiE8nwe1h2G4OwiwlzFKXlA=="
- },
- "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q=="
- },
- "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA=="
- },
- "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw=="
- },
- "runtime.native.System": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0"
- }
- },
- "runtime.native.System.IO.Compression": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0"
- }
- },
- "runtime.native.System.Net.Http": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0"
- }
- },
- "runtime.native.System.Security.Cryptography.Apple": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
- "dependencies": {
- "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
- }
- },
- "runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==",
- "dependencies": {
- "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
- "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
- }
- },
- "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A=="
- },
- "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ=="
- },
- "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ=="
- },
- "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g=="
- },
- "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg=="
- },
- "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ=="
- },
- "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A=="
- },
- "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg=="
- },
- "SixLabors.ImageSharp": {
- "type": "Transitive",
- "resolved": "1.0.1",
- "contentHash": "DjLoFNdUfsDP7RhPpr5hcUhl1XiejqBML9uDWuOUwCkc0Y+sG9IJLLbqSOi9XeoWqPviwdcDm1F8nKdF0qTYIQ=="
- },
- "SQLitePCLRaw.bundle_e_sqlite3": {
- "type": "Transitive",
- "resolved": "2.0.2",
- "contentHash": "OVPI/nh5AqfLCIKhAYqjCa6AHhc7oKApGcGM3UhMRSerFiBx58nSpGwxVFdMgjOCWZR+fA49nzsnKlWp5hFo8w==",
- "dependencies": {
- "SQLitePCLRaw.core": "2.0.2",
- "SQLitePCLRaw.lib.e_sqlite3": "2.0.2",
- "SQLitePCLRaw.provider.dynamic_cdecl": "2.0.2"
- }
- },
- "SQLitePCLRaw.core": {
- "type": "Transitive",
- "resolved": "2.0.2",
- "contentHash": "TFSBX426OelS1tkaVC254NVVlrJIe9YLhWPkEvuqJj2104QpmDmEYOhfdfDJD1E/2SmqDhoRw1ek5cQHj8olcQ==",
- "dependencies": {
- "System.Memory": "4.5.3"
- }
- },
- "SQLitePCLRaw.lib.e_sqlite3": {
- "type": "Transitive",
- "resolved": "2.0.2",
- "contentHash": "S+Tsqe/M7wsc+9HeediI6UHtBKf2X586aRwhi1aBVLGe0WxkAo52O9ZxwEy/v8XMLefcrEMupd2e9CDlIT6QCw=="
- },
- "SQLitePCLRaw.provider.dynamic_cdecl": {
- "type": "Transitive",
- "resolved": "2.0.2",
- "contentHash": "ZSwacbKJUsxJEZxwT23uZVrGbaIvXcADZDz5Sr66fikO5eehdcceDncjzwzTzWfW13di8gpTpstx3WJSt/Ci5Q==",
- "dependencies": {
- "SQLitePCLRaw.core": "2.0.2"
- }
- },
- "System.AppContext": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==",
- "dependencies": {
- "System.Runtime": "4.3.0"
- }
- },
- "System.Buffers": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "ratu44uTIHgeBeI0dE8DWvmXVBSo4u7ozRZZHOMmK/JPpYyo0dAfgSiHlpiObMQ5lEtEyIXA40sKRYg5J6A8uQ==",
- "dependencies": {
- "System.Diagnostics.Debug": "4.3.0",
- "System.Diagnostics.Tracing": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Collections": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Collections.Concurrent": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Diagnostics.Tracing": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0"
- }
- },
- "System.Collections.Immutable": {
- "type": "Transitive",
- "resolved": "1.7.1",
- "contentHash": "B43Zsz5EfMwyEbnObwRxW5u85fzJma3lrDeGcSAV1qkhSRTNY5uXAByTn9h9ddNdhM+4/YoLc/CI43umjwIl9Q=="
- },
- "System.Collections.NonGeneric": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==",
- "dependencies": {
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Collections.Specialized": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "Epx8PoVZR0iuOnJJDzp7pWvdfMMOAvpUo95pC4ScH2mJuXkKA2Y4aR3cG9qt2klHgSons1WFh4kcGW7cSXvrxg==",
- "dependencies": {
- "System.Collections.NonGeneric": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Globalization.Extensions": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.ComponentModel": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "VyGn1jGRZVfxnh8EdvDCi71v3bMXrsu8aYJOwoV7SNDLVhiEqwP86pPMyRGsDsxhXAm2b3o9OIqeETfN5qfezw==",
- "dependencies": {
- "System.Runtime": "4.3.0"
- }
- },
- "System.ComponentModel.Annotations": {
- "type": "Transitive",
- "resolved": "4.7.0",
- "contentHash": "0YFqjhp/mYkDGpU0Ye1GjE53HMp9UVfGN7seGpAMttAC0C40v5gw598jCgpbBLMmCo0E5YRLBv5Z2doypO49ZQ=="
- },
- "System.ComponentModel.Primitives": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "j8GUkCpM8V4d4vhLIIoBLGey2Z5bCkMVNjEZseyAlm4n5arcsJOeI3zkUP+zvZgzsbLTYh4lYeP/ZD/gdIAPrw==",
- "dependencies": {
- "System.ComponentModel": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.ComponentModel.TypeConverter": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "16pQ6P+EdhcXzPiEK4kbA953Fu0MNG2ovxTZU81/qsCd1zPRsKc3uif5NgvllCY598k6bI0KUyKW8fanlfaDQg==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Collections.NonGeneric": "4.3.0",
- "System.Collections.Specialized": "4.3.0",
- "System.ComponentModel": "4.3.0",
- "System.ComponentModel.Primitives": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Configuration.ConfigurationManager": {
- "type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "gWwQv/Ug1qWJmHCmN17nAbxJYmQBM/E94QxKLksvUiiKB1Ld3Sc/eK1lgmbSjDFxkQhVuayI/cGFZhpBSodLrg==",
- "dependencies": {
- "System.Security.Cryptography.ProtectedData": "4.4.0"
- }
- },
- "System.Console": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.IO": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Text.Encoding": "4.3.0"
- }
- },
- "System.Diagnostics.Contracts": {
- "type": "Transitive",
- "resolved": "4.0.1",
- "contentHash": "HvQQjy712vnlpPxaloZYkuE78Gn353L0SJLJVeLcNASeg9c4qla2a1Xq8I7B3jZoDzKPtHTkyVO7AZ5tpeQGuA==",
- "dependencies": {
- "System.Runtime": "4.1.0"
- }
- },
- "System.Diagnostics.Debug": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Diagnostics.DiagnosticSource": {
- "type": "Transitive",
- "resolved": "4.7.1",
- "contentHash": "j81Lovt90PDAq8kLpaJfJKV/rWdWuEk6jfV+MBkee33vzYLEUsy4gXK8laa9V2nZlLM9VM9yA/OOQxxPEJKAMw=="
- },
- "System.Diagnostics.Tools": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Diagnostics.TraceSource": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "VnYp1NxGx8Ww731y2LJ1vpfb/DKVNKEZ8Jsh5SgQTZREL/YpWRArgh9pI8CDLmgHspZmLL697CaLvH85qQpRiw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0",
- "runtime.native.System": "4.3.0"
- }
- },
- "System.Diagnostics.Tracing": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Dynamic.Runtime": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "SNVi1E/vfWUAs/WYKhE9+qlS6KqK0YVhnlT0HQtr8pMIA8YX3lwy3uPMownDwdYISBdmAF/2holEIldVp85Wag==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Linq.Expressions": "4.3.0",
- "System.ObjectModel": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Emit": "4.3.0",
- "System.Reflection.Emit.ILGeneration": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Globalization": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Globalization.Calendars": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Globalization": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Globalization.Extensions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Globalization": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0"
- }
- },
- "System.IdentityModel.Tokens.Jwt": {
- "type": "Transitive",
- "resolved": "6.8.0",
- "contentHash": "5tBCjAub2Bhd5qmcd0WhR5s354e4oLYa//kOWrkX+6/7ZbDDJjMTfwLSOiZ/MMpWdE4DWPLOfTLOq/juj9CKzA==",
- "dependencies": {
- "Microsoft.IdentityModel.JsonWebTokens": "6.8.0",
- "Microsoft.IdentityModel.Tokens": "6.8.0"
- }
- },
- "System.IO": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading.Tasks": "4.3.0"
- }
- },
- "System.IO.Compression": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Buffers": "4.3.0",
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.IO": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "runtime.native.System": "4.3.0",
- "runtime.native.System.IO.Compression": "4.3.0"
- }
- },
- "System.IO.Compression.ZipFile": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "G4HwjEsgIwy3JFBduZ9quBkAu+eUwjIdJleuNSgmUojbH6O3mlvEIme+GHx/cLlTAPcrnnL7GqvB9pTlWRfhOg==",
- "dependencies": {
- "System.Buffers": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.Compression": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.IO.FileSystem.Primitives": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Text.Encoding": "4.3.0"
- }
- },
- "System.IO.FileSystem": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem.Primitives": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading.Tasks": "4.3.0"
- }
- },
- "System.IO.FileSystem.Primitives": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==",
- "dependencies": {
- "System.Runtime": "4.3.0"
- }
- },
- "System.IO.Pipelines": {
- "type": "Transitive",
- "resolved": "4.7.3",
- "contentHash": "zykThu9scJyg2Yeg27GMZCbjzniIsmjtNP5x6kQCd/8rEeKXRy20fP2NOMS7xQ+0pS/E85LZQA+K1aoQLxiUdw=="
- },
- "System.Linq": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0"
- }
- },
- "System.Linq.Expressions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.IO": "4.3.0",
- "System.Linq": "4.3.0",
- "System.ObjectModel": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Emit": "4.3.0",
- "System.Reflection.Emit.ILGeneration": "4.3.0",
- "System.Reflection.Emit.Lightweight": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Memory": {
- "type": "Transitive",
- "resolved": "4.5.3",
- "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
- },
- "System.Net.Http": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Diagnostics.DiagnosticSource": "4.3.0",
- "System.Diagnostics.Tracing": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Globalization.Extensions": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.Net.Primitives": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "System.Security.Cryptography.Encoding": "4.3.0",
- "System.Security.Cryptography.OpenSsl": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Security.Cryptography.X509Certificates": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "runtime.native.System": "4.3.0",
- "runtime.native.System.Net.Http": "4.3.0",
- "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
- }
- },
- "System.Net.Primitives": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Handles": "4.3.0"
- }
- },
- "System.Net.Sockets": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "m6icV6TqQOAdgt5N/9I5KNpjom/5NFtkmGseEH+AK/hny8XrytLH3+b5M8zL/Ycg3fhIocFpUMyl/wpFnVRvdw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.IO": "4.3.0",
- "System.Net.Primitives": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Threading.Tasks": "4.3.0"
- }
- },
- "System.Net.WebSockets": {
- "type": "Transitive",
- "resolved": "4.0.0",
- "contentHash": "2KJo8hir6Edi9jnMDAMhiJoI691xRBmKcbNpwjrvpIMOCTYOtBpSsSEGBxBDV7PKbasJNaFp1+PZz1D7xS41Hg==",
- "dependencies": {
- "Microsoft.Win32.Primitives": "4.0.1",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime": "4.1.0",
- "System.Threading.Tasks": "4.0.11"
- }
- },
- "System.ObjectModel": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Reflection": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.IO": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Reflection.Emit": {
- "type": "Transitive",
- "resolved": "4.7.0",
- "contentHash": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ=="
- },
- "System.Reflection.Emit.ILGeneration": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==",
- "dependencies": {
- "System.Reflection": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Reflection.Emit.Lightweight": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==",
- "dependencies": {
- "System.Reflection": "4.3.0",
- "System.Reflection.Emit.ILGeneration": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Reflection.Extensions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Reflection": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Reflection.Primitives": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Reflection.TypeExtensions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==",
- "dependencies": {
- "System.Reflection": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Resources.ResourceManager": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Globalization": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Runtime": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0"
- }
- },
- "System.Runtime.Extensions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Runtime.Handles": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Runtime.InteropServices": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Primitives": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Handles": "4.3.0"
- }
- },
- "System.Runtime.InteropServices.RuntimeInformation": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==",
- "dependencies": {
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Threading": "4.3.0",
- "runtime.native.System": "4.3.0"
- }
- },
- "System.Runtime.Numerics": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
- "dependencies": {
- "System.Globalization": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0"
- }
- },
- "System.Runtime.Serialization.Primitives": {
- "type": "Transitive",
- "resolved": "4.1.1",
- "contentHash": "HZ6Du5QrTG8MNJbf4e4qMO3JRAkIboGT5Fk804uZtg3Gq516S7hAqTm2UZKUHa7/6HUGdVy3AqMQKbns06G/cg==",
- "dependencies": {
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime": "4.1.0"
- }
- },
- "System.Security.Claims": {
- "type": "Transitive",
- "resolved": "4.0.1",
- "contentHash": "4Jlp0OgJLS/Voj1kyFP6MJlIYp3crgfH8kNQk2p7+4JYfc1aAmh9PZyAMMbDhuoolGNtux9HqSOazsioRiDvCw==",
- "dependencies": {
- "System.Collections": "4.0.11",
- "System.Globalization": "4.0.11",
- "System.IO": "4.1.0",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime": "4.1.0",
- "System.Runtime.Extensions": "4.1.0",
- "System.Security.Principal": "4.0.1"
- }
- },
- "System.Security.Cryptography.Algorithms": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections": "4.3.0",
- "System.IO": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Security.Cryptography.Encoding": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "runtime.native.System.Security.Cryptography.Apple": "4.3.0",
- "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
- }
- },
- "System.Security.Cryptography.Cng": {
- "type": "Transitive",
- "resolved": "4.5.0",
- "contentHash": "WG3r7EyjUe9CMPFSs6bty5doUqT+q9pbI80hlNzo2SkPkZ4VTuZkGWjpp77JB8+uaL4DFPRdBsAY+DX3dBK92A=="
- },
- "System.Security.Cryptography.Csp": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.IO": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "System.Security.Cryptography.Encoding": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading": "4.3.0"
- }
- },
- "System.Security.Cryptography.Encoding": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections": "4.3.0",
- "System.Collections.Concurrent": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
- }
- },
- "System.Security.Cryptography.OpenSsl": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.IO": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "System.Security.Cryptography.Encoding": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
- }
- },
- "System.Security.Cryptography.Primitives": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
- "dependencies": {
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.IO": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0"
- }
- },
- "System.Security.Cryptography.ProtectedData": {
- "type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
- },
- "System.Security.Cryptography.X509Certificates": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Globalization.Calendars": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.IO.FileSystem.Primitives": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "System.Security.Cryptography.Cng": "4.3.0",
- "System.Security.Cryptography.Csp": "4.3.0",
- "System.Security.Cryptography.Encoding": "4.3.0",
- "System.Security.Cryptography.OpenSsl": "4.3.0",
- "System.Security.Cryptography.Primitives": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading": "4.3.0",
- "runtime.native.System": "4.3.0",
- "runtime.native.System.Net.Http": "4.3.0",
- "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
- }
- },
- "System.Security.Principal": {
- "type": "Transitive",
- "resolved": "4.0.1",
- "contentHash": "On+SKhXY5rzxh/S8wlH1Rm0ogBlu7zyHNxeNBiXauNrhHRXAe9EuX8Yl5IOzLPGU5Z4kLWHMvORDOCG8iu9hww==",
- "dependencies": {
- "System.Runtime": "4.1.0"
- }
- },
- "System.Text.Encoding": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Text.Encoding.Extensions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0",
- "System.Text.Encoding": "4.3.0"
- }
- },
- "System.Text.Encodings.Web": {
- "type": "Transitive",
- "resolved": "4.0.1",
- "contentHash": "GgJDO6/1bW6kkttxIiPK2jsqllQ3ifaeeBAJJrcoJq0lAclIZsAZZdEqi6JHq+QLZXL2UsjyWb8K8EOH7nOSPw==",
- "dependencies": {
- "System.Diagnostics.Debug": "4.0.11",
- "System.IO": "4.1.0",
- "System.Reflection": "4.1.0",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime": "4.1.0",
- "System.Runtime.Extensions": "4.1.0",
- "System.Threading": "4.0.11"
- }
- },
- "System.Text.Json": {
- "type": "Transitive",
- "resolved": "4.7.2",
- "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg=="
- },
- "System.Text.RegularExpressions": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==",
- "dependencies": {
- "System.Runtime": "4.3.0"
- }
- },
- "System.Threading": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
- "dependencies": {
- "System.Runtime": "4.3.0",
- "System.Threading.Tasks": "4.3.0"
- }
- },
- "System.Threading.Tasks": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Threading.Tasks.Extensions": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "WSKUTtLhPR8gllzIWO2x6l4lmAIfbyMAiTlyXAis4QBDonXK4b4S6F8zGARX4/P8wH3DH+sLdhamCiHn+fTU1A=="
- },
- "System.Threading.Timer": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==",
- "dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Runtime": "4.3.0"
- }
- },
- "System.Xml.ReaderWriter": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.IO.FileSystem.Primitives": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Text.Encoding.Extensions": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "System.Threading.Tasks.Extensions": "4.3.0"
- }
- },
- "System.Xml.XDocument": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Diagnostics.Tools": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.IO": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Xml.ReaderWriter": "4.3.0"
- }
- },
- "System.Xml.XmlDocument": {
- "type": "Transitive",
- "resolved": "4.3.0",
- "contentHash": "lJ8AxvkX7GQxpC6GFCeBj8ThYVyQczx2+f/cWHJU8tjS7YfI6Cv6bon70jVEgs2CiFbmmM8b9j1oZVx0dSI2Ww==",
- "dependencies": {
- "System.Collections": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.IO": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Xml.ReaderWriter": "4.3.0"
- }
- },
- "System.Xml.XPath": {
- "type": "Transitive",
- "resolved": "4.0.1",
- "contentHash": "UWd1H+1IJ9Wlq5nognZ/XJdyj8qPE4XufBUkAW59ijsCPjZkZe0MUzKKJFBr+ZWBe5Wq1u1d5f2CYgE93uH7DA==",
- "dependencies": {
- "System.Collections": "4.0.11",
- "System.Diagnostics.Debug": "4.0.11",
- "System.Globalization": "4.0.11",
- "System.IO": "4.1.0",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime": "4.1.0",
- "System.Runtime.Extensions": "4.1.0",
- "System.Threading": "4.0.11",
- "System.Xml.ReaderWriter": "4.0.11"
- }
- },
- "System.Xml.XPath.XDocument": {
- "type": "Transitive",
- "resolved": "4.0.1",
- "contentHash": "FLhdYJx4331oGovQypQ8JIw2kEmNzCsjVOVYY/16kZTUoquZG85oVn7yUhBE2OZt1yGPSXAL0HTEfzjlbNpM7Q==",
- "dependencies": {
- "System.Diagnostics.Debug": "4.0.11",
- "System.Linq": "4.1.0",
- "System.Resources.ResourceManager": "4.0.1",
- "System.Runtime": "4.1.0",
- "System.Runtime.Extensions": "4.1.0",
- "System.Threading": "4.0.11",
- "System.Xml.ReaderWriter": "4.0.11",
- "System.Xml.XDocument": "4.0.11",
- "System.Xml.XPath": "4.0.1"
- }
- },
- "xunit.abstractions": {
- "type": "Transitive",
- "resolved": "2.0.3",
- "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg=="
- },
- "xunit.analyzers": {
- "type": "Transitive",
- "resolved": "0.10.0",
- "contentHash": "4/IDFCJfIeg6bix9apmUtIMwvOsiwqdEexeO/R2D4GReIGPLIRODTpId/l4LRSrAJk9lEO3Zx1H0Zx6uohJDNg=="
- },
- "xunit.assert": {
- "type": "Transitive",
- "resolved": "2.4.1",
- "contentHash": "O/Oe0BS5RmSsM+LQOb041TzuPo5MdH2Rov+qXGS37X+KFG1Hxz7kopYklM5+1Y+tRGeXrOx5+Xne1RuqLFQoyQ==",
- "dependencies": {
- "NETStandard.Library": "1.6.1"
- }
- },
- "xunit.core": {
- "type": "Transitive",
- "resolved": "2.4.1",
- "contentHash": "Zsj5OMU6JasNGERXZy8s72+pcheG6Q15atS5XpZXqAtULuyQiQ6XNnUsp1gyfC6WgqScqMvySiEHmHcOG6Eg0Q==",
- "dependencies": {
- "xunit.extensibility.core": "[2.4.1]",
- "xunit.extensibility.execution": "[2.4.1]"
- }
- },
- "xunit.extensibility.core": {
- "type": "Transitive",
- "resolved": "2.4.1",
- "contentHash": "yKZKm/8QNZnBnGZFD9SewkllHBiK0DThybQD/G4PiAmQjKtEZyHi6ET70QPU9KtSMJGRYS6Syk7EyR2EVDU4Kg==",
- "dependencies": {
- "NETStandard.Library": "1.6.1",
- "xunit.abstractions": "2.0.3"
- }
- },
- "xunit.extensibility.execution": {
- "type": "Transitive",
- "resolved": "2.4.1",
- "contentHash": "7e/1jqBpcb7frLkB6XDrHCGXAbKN4Rtdb88epYxCSRQuZDRW8UtTfdTEVpdTl8s4T56e07hOBVd4G0OdCxIY2A==",
- "dependencies": {
- "NETStandard.Library": "1.6.1",
- "xunit.extensibility.core": "[2.4.1]"
- }
- },
- "timeline": {
- "type": "Project",
- "dependencies": {
- "AutoMapper": "10.1.1",
- "AutoMapper.Extensions.Microsoft.DependencyInjection": "8.1.0",
- "Microsoft.AspNetCore.SpaServices.Extensions": "3.1.9",
- "Microsoft.EntityFrameworkCore": "3.1.9",
- "Microsoft.EntityFrameworkCore.Analyzers": "3.1.9",
- "Microsoft.EntityFrameworkCore.Sqlite": "3.1.9",
- "NSwag.AspNetCore": "13.8.2",
- "SixLabors.ImageSharp": "1.0.1",
- "System.IdentityModel.Tokens.Jwt": "6.8.0",
- "Timeline.ErrorCodes": "1.0.0"
- }
- },
- "timeline.errorcodes": {
- "type": "Project"
- }
- }
- }
-} \ No newline at end of file