Finished api
This commit is contained in:
1 parent
3cf5a889a7
commit
7ff304dadf
9 files changed
+217
-8
No files matched your search
@@ -132,3 +132,4 @@ $RECYCLE.BIN/
|
|||||||
|
|
||||||
_NCrunch*
|
_NCrunch*
|
||||||
|
|
||||||
|
.vscode
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace RobotsWantedLeague.Test.Services;
|
||||||
|
using RobotsWantedLeague.Models;
|
||||||
|
using RobotsWantedLeague.Services;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class NotEmptyRobotsServiceTest
|
||||||
|
{
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestHappyPath()
|
||||||
|
{
|
||||||
|
IRobotsService service = new NotEmptyRobotsService();
|
||||||
|
Assert.AreEqual(3, service.Robots.Count);
|
||||||
|
Robot robot = service.CreateRobot("paul", 2, 3, "canada");
|
||||||
|
Assert.AreEqual(robot.Name, "paul");
|
||||||
|
Assert.AreEqual(robot.Weight, 2);
|
||||||
|
|
||||||
|
Assert.AreEqual(4, service.Robots.Count);
|
||||||
|
|
||||||
|
service.DeleteRobotById(robot.Id);
|
||||||
|
Assert.AreEqual(3, service.Robots.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,6 +5,14 @@ using RobotsWantedLeague.Services;
|
|||||||
|
|
||||||
namespace RobotsWantedLeague.Controllers;
|
namespace RobotsWantedLeague.Controllers;
|
||||||
|
|
||||||
|
public class RobotRequest{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
public int Weight { get; set; }
|
||||||
|
|
||||||
|
public string Country { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class RobotsController : Controller
|
public class RobotsController : Controller
|
||||||
{
|
{
|
||||||
private readonly ILogger<RobotsController> _logger;
|
private readonly ILogger<RobotsController> _logger;
|
||||||
@@ -22,14 +30,26 @@ public class RobotsController : Controller
|
|||||||
return View(robotsService.Robots);
|
return View(robotsService.Robots);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Privacy()
|
public IActionResult Robot(int id){
|
||||||
{
|
Robot robot = robotsService.GetRobotById(id);
|
||||||
|
return View(robot);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult CreateRobot(){
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
[HttpPost]
|
||||||
public IActionResult Error()
|
public IActionResult CreateRobot([FromBody] RobotRequest robot)
|
||||||
{
|
{
|
||||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
Robot r = robotsService.CreateRobot(robot.Name,
|
||||||
|
robot.Weight,
|
||||||
|
robot.Height,
|
||||||
|
robot.Country);
|
||||||
|
string htmxRedirectHeaderName = "HX-Redirect";
|
||||||
|
string redirectURL = "/robots/robot?id=" + r.Id;
|
||||||
|
Response.Headers.Add(htmxRedirectHeaderName, redirectURL);
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddControllersWithViews();
|
builder.Services.AddControllersWithViews();
|
||||||
builder.Services.AddSingleton<IRobotsService, RobotsService>();
|
builder.Services.AddSingleton<IRobotsService, NotEmptyRobotsService>();
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
namespace RobotsWantedLeague.Services;
|
||||||
|
|
||||||
|
using RobotsWantedLeague.Models;
|
||||||
|
|
||||||
|
public class NotEmptyRobotsService: IRobotsService
|
||||||
|
{
|
||||||
|
private readonly IRobotsService underlyingRobotsService;
|
||||||
|
public List<Robot> Robots { get => underlyingRobotsService.Robots; }
|
||||||
|
|
||||||
|
public NotEmptyRobotsService()
|
||||||
|
{
|
||||||
|
this.underlyingRobotsService = new RobotsService();
|
||||||
|
this.underlyingRobotsService.CreateRobot("Alice", 1050, 2, "Bhutan");
|
||||||
|
this.underlyingRobotsService.CreateRobot("Bob", 5001, 5, "Vanuatu");
|
||||||
|
this.underlyingRobotsService.CreateRobot("Xu", 890, 1, "Taiwan");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Robot CreateRobot(string name,
|
||||||
|
int weight,
|
||||||
|
int height,
|
||||||
|
string country)
|
||||||
|
{
|
||||||
|
return underlyingRobotsService.CreateRobot(name, weight, height, country);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Robot? GetRobotById(int id){
|
||||||
|
return underlyingRobotsService.GetRobotById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DeleteRobotById(int id){
|
||||||
|
return underlyingRobotsService.DeleteRobotById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
<form hx-post="/robots/createRobot"
|
||||||
|
hx-ext="json-enc"
|
||||||
|
hx-trigger="submit">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">Le nom du robot</label>
|
||||||
|
<input type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="name"
|
||||||
|
name="name"
|
||||||
|
placeholder="Le Géant Ferré">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="weight">Poids (kg)</label>
|
||||||
|
<input type="number"
|
||||||
|
class="form-control"
|
||||||
|
id="weight"
|
||||||
|
name="weight"
|
||||||
|
min="0"
|
||||||
|
placeholder="87">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="height">Taille (m)</label>
|
||||||
|
<input type="number"
|
||||||
|
class="form-control"
|
||||||
|
id="height"
|
||||||
|
name="height"
|
||||||
|
min="0"
|
||||||
|
placeholder="2">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="country">Pays</label>
|
||||||
|
<input type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="country"
|
||||||
|
name="country"
|
||||||
|
placeholder="Suriname">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary mt-3">Submit</button>
|
||||||
|
</form>
|
||||||
@@ -10,4 +10,7 @@
|
|||||||
<a href="robots/robot?id=@robot.Id">@robot.Name</a>
|
<a href="robots/robot?id=@robot.Id">@robot.Name</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<a class="btn btn-primary mt-2" href="/robots/createRobot"> Ajouter un robot</a>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
@model Robot
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div class="card" style="width: 10rem;">
|
||||||
|
<img class="card-img-top"
|
||||||
|
src="https://robohash.org/aligator@Model.Id?set=set2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Nom</th><td>@Model.Name</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>Poids</th><td>@Model.Weight (kg)</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>Taille</th><td>@Model.Height (m)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Pays</th><td>@Model.Country</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
@@ -7,12 +7,65 @@
|
|||||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="~/RobotsWantedLeague.styles.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/RobotsWantedLeague.styles.css" asp-append-version="true" />
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.5"`
|
||||||
|
integrity="sha384-xcuj3WpfgjlKF+FXhSQFQ0ZNr39ln+hwjN3npfM9VBnUskLolQAcN80McRIVOPuO"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
function _isNumeric(str) {
|
||||||
|
if (typeof str != "string") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !isNaN(str) && !isNaN(parseFloat(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
function _cast(str) {
|
||||||
|
return _isNumeric(str) ? parseFloat(str) : str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _addAssocToDict(obj, key, value) {
|
||||||
|
let splittedKey = Array.isArray(key) ? key : key.split(".");
|
||||||
|
const keyToAdd = splittedKey.shift();
|
||||||
|
const isTerminal = splittedKey.length === 0;
|
||||||
|
if (isTerminal) {
|
||||||
|
obj[keyToAdd] = _cast(value);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
if (!(keyToAdd in obj)) {
|
||||||
|
obj[keyToAdd] = {};
|
||||||
|
}
|
||||||
|
return _addAssocToDict(obj[keyToAdd], splittedKey, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _createPayload(params) {
|
||||||
|
let ret = {};
|
||||||
|
for (let key of Object.keys(params)) {
|
||||||
|
_addAssocToDict(ret, key, params[key]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
htmx.defineExtension('json-enc', {
|
||||||
|
onEvent: function (name, evt) {
|
||||||
|
if (name === "htmx:configRequest") {
|
||||||
|
evt.detail.headers['Content-Type'] = "application/json";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
encodeParameters: function (xhr, parameters, elt) {
|
||||||
|
xhr.overrideMimeType('text/json');
|
||||||
|
return (JSON.stringify(_createPayload(parameters)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">RobotsWantedLeague</a>
|
<a class="navbar-brand" href="/">RobotsWantedLeague</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||||
aria-expanded="false" aria-label="Toggle navigation">
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
|||||||
Reference in new issue
Block a user