diff --git a/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/AuthenticationServiceTests.cs b/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/AuthenticationServiceTests.cs
deleted file mode 100644
index ed80c6f3..00000000
--- a/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/AuthenticationServiceTests.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-//
-// Copyright Shuai Zhang. All rights reserved.
-// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using GeothermalResearchInstitute.ServerConsole.GrpcServices;
-using GeothermalResearchInstitute.ServerConsole.Options;
-using GeothermalResearchInstitute.v1;
-using Grpc.Core;
-using Grpc.Core.Testing;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.MSTest;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace GeothermalResearchInstitute.ServerConsole.UnitTest
-{
- [TestClass]
- public class AuthenticationServiceTests
- {
- private static IHost Host { get; set; }
-
- [ClassInitialize]
- [System.Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "Required by MSTest Framework.")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage(
- "样式", "IDE0060:删除未使用的参数", Justification = "Required by MSTest Framework.")]
- public static void Init(TestContext testContext)
- {
- Host = new HostBuilder()
- .ConfigureHostConfiguration(builder =>
- {
- builder.AddInMemoryCollection(new Dictionary
- {
- { "Environment", "UnitTest" },
- });
- })
- .ConfigureAppConfiguration(builder =>
- {
- builder.AddInMemoryCollection(new Dictionary
- {
- { "credentials:0:nickname", "测试用户0" },
- { "credentials:0:username", "user0_username" },
- { "credentials:0:password", "user0_password" },
- { "credentials:0:role", "User" },
- { "credentials:1:nickname", "测试用户1" },
- { "credentials:1:username", "user1_username" },
- { "credentials:1:password", "user1_password" },
- { "credentials:1:role", "Administrator" },
- });
- })
- .ConfigureLogging((context, builder) =>
- {
- builder.AddProvider(new MsTestLoggerProvider());
- })
- .ConfigureServices((context, builder) =>
- {
- IConfiguration config = context.Configuration;
-
- // Configuration options.
- builder.Configure(context.Configuration);
-
- // Grpc services.
- builder.AddSingleton(serviceProvider =>
- {
- return new GrpcLoggerAdapater.GrpcLoggerAdapter(
- serviceProvider.GetRequiredService(),
- serviceProvider.GetRequiredService>());
- });
- builder.AddTransient();
- })
- .Build();
- }
-
- [ClassCleanup]
- public static void Cleanup()
- {
- Host.Dispose();
- Host = null;
- }
-
- [TestMethod]
- public async Task LoginUser0Success()
- {
- var service = Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.Authenticate),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service.Authenticate(
- new AuthenticateRequest
- {
- Username = "user0_username",
- Password = "user0_password",
- },
- fakeServerCallContext).ConfigureAwait(false);
- Assert.AreEqual(
- new AuthenticateResponse
- {
- Nickname = "测试用户0",
- Role = UserRole.User,
- },
- response);
- }
-
- [TestMethod]
- public async Task LoginUser1Success()
- {
- var service = Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.Authenticate),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service.Authenticate(
- new AuthenticateRequest
- {
- Username = "user1_username",
- Password = "user1_password",
- },
- fakeServerCallContext).ConfigureAwait(false);
- Assert.AreEqual(
- new AuthenticateResponse
- {
- Nickname = "测试用户1",
- Role = UserRole.Administrator,
- },
- response);
- }
-
- [TestMethod]
- public async Task LoginUser1Failed()
- {
- var service = Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.Authenticate),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var rpcException = await Assert.ThrowsExceptionAsync(() => service.Authenticate(
- new AuthenticateRequest
- {
- Username = "user1_username",
- },
- fakeServerCallContext)).ConfigureAwait(false);
- Assert.AreEqual(StatusCode.Unauthenticated, rpcException.StatusCode);
- }
-
- [TestMethod]
- public async Task LoginFailed()
- {
- var service = Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.Authenticate),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var rpcException = await Assert.ThrowsExceptionAsync(() => service.Authenticate(
- new AuthenticateRequest
- {
- },
- fakeServerCallContext)).ConfigureAwait(false);
- Assert.AreEqual(StatusCode.Unauthenticated, rpcException.StatusCode);
- }
- }
-}
diff --git a/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/DeviceServiceTests.cs b/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/DeviceServiceTests.cs
deleted file mode 100644
index 3c1a4daa..00000000
--- a/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/DeviceServiceTests.cs
+++ /dev/null
@@ -1,375 +0,0 @@
-//
-// Copyright Shuai Zhang. All rights reserved.
-// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using GeothermalResearchInstitute.ServerConsole.GrpcServices;
-using GeothermalResearchInstitute.ServerConsole.Options;
-using GeothermalResearchInstitute.v1;
-using Google.Protobuf;
-using Grpc.Core;
-using Grpc.Core.Testing;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.MSTest;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace GeothermalResearchInstitute.ServerConsole.UnitTest
-{
- [TestClass]
- public class DeviceServiceTests
- {
- private IHost Host { get; set; }
-
- [TestInitialize]
- public void Init()
- {
- this.Host = new HostBuilder()
- .ConfigureHostConfiguration(builder =>
- {
- builder.AddInMemoryCollection(new Dictionary
- {
- { "Environment", "UnitTest" },
- });
- })
- .ConfigureAppConfiguration(builder =>
- {
- builder.AddInMemoryCollection(new Dictionary
- {
- { "devices:0:id", "10:BF:48:79:B2:A4" },
- { "devices:0:name", "测试设备0" },
- { "devices:1:id", "BC:96:80:E6:70:16" },
- { "devices:1:name", "测试设备1" },
- });
- })
- .ConfigureLogging((context, builder) =>
- {
- builder.AddProvider(new MsTestLoggerProvider());
- })
- .ConfigureServices((context, builder) =>
- {
- IConfiguration config = context.Configuration;
-
- builder.AddDbContext(options => options.UseInMemoryDatabase("bjdire"));
-
- // Configuration options.
- builder.Configure(context.Configuration);
-
- // Grpc services.
- builder.AddSingleton(serviceProvider =>
- {
- return new GrpcLoggerAdapater.GrpcLoggerAdapter(
- serviceProvider.GetRequiredService(),
- serviceProvider.GetRequiredService>());
- });
- builder.AddSingleton();
- })
- .Build();
- }
-
- [TestCleanup]
- public void Cleanup()
- {
- this.Host.Dispose();
- this.Host = null;
- }
-
- [TestMethod]
- public async Task ListDevices()
- {
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.ListDevices),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
- var response = await service.ListDevices(new ListDevicesRequest(), fakeServerCallContext).ConfigureAwait(false);
-
- CollectionAssert.AreEqual(
- new List
- {
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- Name = "测试设备0",
- },
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0xBC, 0x96, 0x80, 0xE6, 0x70, 0x16 }),
- Name = "测试设备1",
- },
- },
- response.Devices);
- }
-
- [TestMethod]
- public async Task GetDeviceInvalidId()
- {
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.GetDevice),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var rpcException = await Assert
- .ThrowsExceptionAsync(() => service.GetDevice(
- new GetDeviceRequest
- {
- Id = ByteString.CopyFromUtf8("NOT_EXIST"),
- View = DeviceView.NameOnly,
- },
- fakeServerCallContext))
- .ConfigureAwait(false);
- Assert.AreEqual(StatusCode.NotFound, rpcException.StatusCode);
- }
-
- [TestMethod]
- public async Task GetDeviceNameOnly()
- {
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.GetDevice),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service
- .GetDevice(
- new GetDeviceRequest
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- View = DeviceView.NameOnly,
- },
- fakeServerCallContext)
- .ConfigureAwait(false);
- Assert.AreEqual(
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- Name = "测试设备0",
- },
- response);
- }
-
- [TestMethod]
- public async Task GetDeviceWorkingModeOnlyNonExisting()
- {
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.GetDevice),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service
- .GetDevice(
- new GetDeviceRequest
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- View = DeviceView.WorkingModeOnly,
- },
- fakeServerCallContext)
- .ConfigureAwait(false);
- Assert.AreEqual(
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- WorkingMode = DeviceWorkingMode.Unspecified,
- },
- response);
- }
-
- [TestMethod]
- public async Task GetDeviceWorkingModeOnlyExisting()
- {
- var bjdireContext = this.Host.Services.GetRequiredService();
- var actualStates = new DeviceActualStates
- {
- Id = new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 },
- WorkingMode = DeviceWorkingMode.KeepWarmCapacity,
- };
- bjdireContext.DevicesActualStates.Add(actualStates);
- bjdireContext.SaveChanges();
-
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.GetDevice),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service
- .GetDevice(
- new GetDeviceRequest
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- View = DeviceView.WorkingModeOnly,
- },
- fakeServerCallContext)
- .ConfigureAwait(false);
- Assert.AreEqual(
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- WorkingMode = DeviceWorkingMode.KeepWarmCapacity,
- },
- response);
- }
-
- [TestMethod]
- public async Task UpdateDeviceWorkingModeNonExisting()
- {
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.UpdateDevice),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service
- .UpdateDevice(
- new UpdateDeviceRequest
- {
- Device = new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- WorkingMode = DeviceWorkingMode.MeasureTemperature,
- },
- UpdateMask = Google.Protobuf.WellKnownTypes.FieldMask.FromString("working_mode"),
- },
- fakeServerCallContext)
- .ConfigureAwait(false);
-
- Assert.AreEqual(
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- WorkingMode = DeviceWorkingMode.MeasureTemperature,
- },
- response);
-
- var bjdireContext = this.Host.Services.GetRequiredService();
- Assert.AreEqual(
- new DeviceDesiredStates
- {
- Id = new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 },
- WorkingMode = DeviceWorkingMode.MeasureTemperature,
- },
- bjdireContext.DevicesDesiredStates.SingleOrDefault());
- }
-
- [TestMethod]
- public async Task UpdateDeviceWorkingModeExisting()
- {
- var bjdireContext = this.Host.Services.GetRequiredService();
- var desiredStates = new DeviceDesiredStates
- {
- Id = new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 },
- WorkingMode = DeviceWorkingMode.KeepWarmCapacity,
- ColdCapacity = 5,
- };
- bjdireContext.DevicesDesiredStates.Add(desiredStates);
- bjdireContext.SaveChanges();
-
- var service = this.Host.Services.GetRequiredService();
- var fakeServerCallContext = TestServerCallContext.Create(
- nameof(service.UpdateDevice),
- null,
- DateTime.UtcNow.AddHours(1),
- new Metadata(),
- CancellationToken.None,
- null,
- null,
- null,
- (metadata) => Task.CompletedTask,
- () => new WriteOptions(),
- (writeOptions) => { });
-
- var response = await service
- .UpdateDevice(
- new UpdateDeviceRequest
- {
- Device = new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- WorkingMode = DeviceWorkingMode.MeasureTemperature,
- DeviceOption = new DeviceOption
- {
- ColdCapacity = 20,
- },
- },
- UpdateMask = Google.Protobuf.WellKnownTypes.FieldMask.FromString("working_mode"),
- },
- fakeServerCallContext)
- .ConfigureAwait(false);
-
- Assert.AreEqual(
- new Device
- {
- Id = ByteString.CopyFrom(new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 }),
- WorkingMode = DeviceWorkingMode.MeasureTemperature,
- },
- response);
-
- Assert.AreEqual(
- new DeviceDesiredStates
- {
- Id = new byte[] { 0x10, 0xBF, 0x48, 0x79, 0xB2, 0xA4 },
- WorkingMode = DeviceWorkingMode.MeasureTemperature,
- ColdCapacity = 5,
- },
- bjdireContext.DevicesDesiredStates.SingleOrDefault());
- }
- }
-}
diff --git a/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/GeothermalResearchInstitute.ServerConsole.UnitTest.csproj b/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/GeothermalResearchInstitute.ServerConsole.UnitTest.csproj
deleted file mode 100644
index 80dd49c5..00000000
--- a/GeothermalResearchInstitute/GeothermalResearchInstitute.ServerConsole.UnitTest/GeothermalResearchInstitute.ServerConsole.UnitTest.csproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- $(NetcoreCurrentTargetFramework)
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git "a/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.docx" "b/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.docx"
index 724c332d..73b13b21 100644
--- "a/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.docx"
+++ "b/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.docx"
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:320959faef7bb82bd45ee862146087f172b340b1f66d46fd50c7424279ee9883
-size 78559
+oid sha256:f8967c46c910353b01d9a57ccf040fbe0d8fbab0bf19a379e697748b10c96bc9
+size 77496
diff --git "a/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.pdf" "b/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.pdf"
index bbc7ec72..977b2dde 100644
Binary files "a/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.pdf" and "b/GeothermalResearchInstitute/docs/\345\234\260\347\203\255\351\231\242\351\241\271\347\233\256\344\270\213\344\275\215\346\234\272\351\200\232\344\277\241\346\226\207\346\241\243.pdf" differ