Setpoint API #1
@ -16,31 +16,33 @@ namespace Persistence.API.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("current")]
|
||||
|
||||
public Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrentAsync(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost("history")]
|
||||
on.nemtina
commented
Здесь метод [HttpGet] Здесь метод [HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistoryAsync(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetHistoryAsync(setpointKeys, historyMoment, token);
|
||||
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost("log")]
|
||||
on.nemtina
commented
Здесь метод [HttpGet] Здесь метод [HttpGet]
|
||||
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLogAsync([FromBody] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromBody] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.GetLogAsync(setpointKeys, token);
|
||||
var result = await setpointRepository.GetLog(setpointKeys, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost("save")]
|
||||
on.nemtina
commented
Здесь можно просто [HttpPost] Здесь можно просто [HttpPost]
|
||||
public async Task<ActionResult<int>> SaveAsync(Guid setpointKey, object newValue, CancellationToken token)
|
||||
public async Task<ActionResult<int>> Save(Guid setpointKey, object newValue, CancellationToken token)
|
||||
{
|
||||
var result = await setpointRepository.SaveAsync(setpointKey, newValue, token);
|
||||
var result = await setpointRepository.Save(setpointKey, newValue, 0, token);
|
||||
on.nemtina
commented
Добавить todo, что необходимо решить вопрос с получением пользователя и авторизацией Добавить todo, что необходимо решить вопрос с получением пользователя и авторизацией
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
namespace Persistence.Database.Model
|
||||
{
|
||||
public interface ISetpointData
|
||||
{
|
||||
public Guid Key { get; set; }
|
||||
public object Value { get; set; }
|
||||
public DateTimeOffset Created { get; set; }
|
||||
public int IdUser { get; set; }
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
namespace Persistence.Database.Model
|
||||
{
|
||||
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||
public class Setpoint : ISetpointData
|
||||
public class Setpoint
|
||||
{
|
||||
[Comment("Ключ")]
|
||||
public Guid Key { get; set; }
|
||||
|
@ -5,13 +5,16 @@ namespace Persistence.IntegrationTests.Clients
|
||||
{
|
||||
public interface ISetpointClient
|
||||
{
|
||||
[Post("/api/Setpoint/history")]
|
||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetHistoryAsync(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment);
|
||||
[Post("/current")]
|
||||
on.nemtina
commented
Заголовки методов запроса должны соответствовать тем, что в контроллере (там часть нужно поменять с post на get) Заголовки методов запроса должны соответствовать тем, что в контроллере (там часть нужно поменять с post на get)
|
||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetCurrent(IEnumerable<Guid> setpointKeys);
|
||||
|
||||
[Post("/api/Setpoint/log")]
|
||||
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLogAsync(IEnumerable<Guid> setpoitKeys);
|
||||
[Post("/history")]
|
||||
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment);
|
||||
|
||||
[Post("/api/Setpoint/save")]
|
||||
Task<IApiResponse<int>> SaveAsync(Guid setpointKey, object newValue);
|
||||
[Post("/log")]
|
||||
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys);
|
||||
|
||||
[Post("/save")]
|
||||
Task<IApiResponse<int>> Save(Guid setpointKey, object newValue);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using Mapster;
|
||||
using Persistence.IntegrationTests.Clients;
|
||||
using Xunit;
|
||||
|
||||
@ -10,16 +12,36 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
private class TestObject
|
||||
{
|
||||
public string? value1 { get; set; }
|
||||
public int value2 { get; set; }
|
||||
public double value3 { get; set; }
|
||||
public int? value2 { get; set; }
|
||||
}
|
||||
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
factory.ClientOptions.BaseAddress = new Uri($"http://localhost/api/Setpoint");
|
||||
on.nemtina
commented
Эту строчку лучше убрать, а в интерфейсе ISetpointClient прописать так:
Эту строчку лучше убрать, а в интерфейсе ISetpointClient прописать так:
```
private const string BaseRoute = "/api/setpoint";
[Post($"{BaseRoute}/current")]
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetCurrent(IEnumerable<Guid> setpointKeys);```
|
||||
|
||||
client = factory.GetHttpClient<ISetpointClient>(string.Empty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHistoryAsync_returns_success()
|
||||
public async Task GetCurrent_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
{
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid()
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await client.GetCurrent(setpointKeys);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Empty(response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetHistory_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
@ -30,14 +52,16 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
var historyMoment = DateTimeOffset.Now.ToUniversalTime();
|
||||
|
||||
//act
|
||||
var response = await client.GetHistoryAsync(setpointKeys, historyMoment);
|
||||
var response = await client.GetHistory(setpointKeys, historyMoment);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Empty(response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetLogAsync_returns_success()
|
||||
public async Task GetLog_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKeys = new List<Guid>()
|
||||
@ -47,30 +71,77 @@ namespace Persistence.IntegrationTests.Controllers
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await client.GetLogAsync(setpointKeys);
|
||||
var response = await client.GetLog(setpointKeys);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Empty(response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SaveAsync_returns_success()
|
||||
public async Task Save_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var setpointKey = Guid.NewGuid();
|
||||
var setpointValue = new TestObject()
|
||||
{
|
||||
value1 = "1",
|
||||
value2 = 2,
|
||||
value3 = 3.3
|
||||
value2 = 2
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await client.SaveAsync(setpointKey, setpointValue);
|
||||
var response = await client.Save(setpointKey, setpointValue);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(1, response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task General_test_success()
|
||||
on.nemtina
commented
General_test_success не нужен, вместо него нужно для каждого кейса написать свой тест. General_test_success не нужен, вместо него нужно для каждого кейса написать свой тест.
Данные тесты должны быть аналогичны GetCurrent_returns_success, GetHistory_returns_success, GetLog_returns_success, только внутри блока //arrange вызвать метод Save.
Метод Save сделать отдельным приватным методом.
|
||||
{
|
||||
//save
|
||||
var setpointKey = Guid.NewGuid();
|
||||
var setpointValue = new TestObject()
|
||||
{
|
||||
value1 = "1",
|
||||
value2 = 2
|
||||
};
|
||||
|
||||
var saveResponse = await client.Save(setpointKey, setpointValue);
|
||||
Assert.Equal(HttpStatusCode.OK, saveResponse.StatusCode);
|
||||
Assert.Equal(1, saveResponse.Content);
|
||||
|
||||
//current
|
||||
var currentResponse = await client.GetCurrent([setpointKey]);
|
||||
Assert.Equal(HttpStatusCode.OK, currentResponse.StatusCode);
|
||||
|
||||
var currentContent = currentResponse.Content;
|
||||
Assert.NotNull(currentContent);
|
||||
Assert.NotEmpty(currentContent);
|
||||
|
||||
var currentContentValue = currentContent.FirstOrDefault()?.Value?.ToString();
|
||||
Assert.NotNull(currentContentValue);
|
||||
on.nemtina
commented
Assert.Equal(expected, actual) Assert.Equal(expected, actual)
|
||||
Assert.NotEmpty(currentContentValue);
|
||||
|
||||
var testObjectValue = JsonSerializer.Deserialize<TestObject>(currentContentValue);
|
||||
Assert.NotNull(testObjectValue);
|
||||
Assert.Equal(setpointValue.value1, testObjectValue.value1);
|
||||
Assert.Equal(setpointValue.value2, testObjectValue.value2);
|
||||
|
||||
//history
|
||||
var historyMoment = DateTimeOffset.Now.ToUniversalTime();
|
||||
var historyResponse = await client.GetHistory([setpointKey], historyMoment);
|
||||
Assert.Equal(HttpStatusCode.OK, historyResponse.StatusCode);
|
||||
Assert.NotNull(historyResponse.Content);
|
||||
Assert.NotEmpty(historyResponse.Content);
|
||||
|
||||
//log
|
||||
var logResponse = await client.GetLog([setpointKey]);
|
||||
Assert.Equal(HttpStatusCode.OK, logResponse.StatusCode);
|
||||
Assert.NotNull(logResponse.Content);
|
||||
Assert.NotEmpty(logResponse.Content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,18 @@ namespace Persistence.Repository.Repositories
|
||||
|
||||
protected virtual IQueryable<Setpoint> GetQueryReadOnly() => db.Set<Setpoint>();
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetHistoryAsync(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => setpointKeys.Contains(e.Key))
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities.Select(e => e.Adapt<SetpointValueDto>());
|
||||
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
@ -27,7 +38,7 @@ namespace Persistence.Repository.Repositories
|
||||
return dtos;
|
||||
on.nemtina
commented
Здесь нужно еще просортировать, чтобы гарантированно взять нужную близлежайшую к historyMoment уставку Здесь нужно еще просортировать, чтобы гарантированно взять нужную близлежайшую к historyMoment уставку
|
||||
}
|
||||
|
||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLogAsync(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
@ -43,7 +54,7 @@ namespace Persistence.Repository.Repositories
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<int> SaveAsync(Guid setpointKey, object newValue, CancellationToken token)
|
||||
public async Task<int> Save(Guid setpointKey, object newValue, int idUser, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -51,7 +62,7 @@ namespace Persistence.Repository.Repositories
|
||||
{
|
||||
Key = setpointKey,
|
||||
Value = newValue,
|
||||
IdUser = 0, // ToDo: откуда тянуть?
|
||||
IdUser = idUser,
|
||||
Created = DateTimeOffset.Now.ToUniversalTime()
|
||||
on.nemtina
commented
Можно так: Created = DateTimeOffset.UtcNow Можно так: Created = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@ public interface ISetpointApi
|
||||
/// <param name="setpoitKeys">ключи уставок</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrentAsync(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||
Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
@ -23,7 +23,7 @@ public interface ISetpointApi
|
||||
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistoryAsync(IEnumerable<Guid> setpoitKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory(IEnumerable<Guid> setpoitKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
@ -31,7 +31,7 @@ public interface ISetpointApi
|
||||
/// <param name="setpoitKeys">ключи уставок</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLogAsync(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||
Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Метод сохранения уставки
|
||||
@ -40,5 +40,5 @@ public interface ISetpointApi
|
||||
/// <param name="newValue">значение</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<ActionResult<int>> SaveAsync(Guid setpointKey, object newValue, CancellationToken token);
|
||||
Task<ActionResult<int>> Save(Guid setpointKey, object newValue, CancellationToken token);
|
||||
on.nemtina
commented
Решили, что метод Save не должен ничего возвращать Решили, что метод Save не должен ничего возвращать
|
||||
}
|
||||
|
@ -7,6 +7,13 @@ namespace Persistence.Repositories;
|
||||
/// </summary>
|
||||
public interface ISetpointRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить значения уставок по набору ключей
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
@ -15,7 +22,7 @@ public interface ISetpointRepository
|
||||
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetHistoryAsync(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить историю изменений значений уставок
|
||||
@ -23,7 +30,7 @@ public interface ISetpointRepository
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLogAsync(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Метод сохранения уставки
|
||||
@ -35,5 +42,5 @@ public interface ISetpointRepository
|
||||
/// <returns></returns>
|
||||
/// to do
|
||||
/// id User учесть в соответствующем методе репозитория
|
||||
Task<int> SaveAsync(Guid setpointKey, object newValue, CancellationToken token);
|
||||
Task<int> Save(Guid setpointKey, object newValue, int idUser, CancellationToken token);
|
||||
}
|
||||
|
Здесь метод [HttpGet]