hitting the performer
This commit is contained in:
parent
fbc72f0c85
commit
341b49cbfa
27 changed files with 1603 additions and 35 deletions
|
|
@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Microsoft.IdentityModel.Tokens;
|
||||
using Yavsc.Controllers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.Models.Workflow;
|
||||
using Yavsc.Tests.Shared;
|
||||
|
|
@ -212,6 +213,114 @@ public sealed class ApiWebServerFixture : WebHostFixture
|
|||
db.SaveChanges();
|
||||
}
|
||||
|
||||
public void ResetAndSeedHaircutGraph()
|
||||
{
|
||||
ResetAndSeedActivityGraph();
|
||||
|
||||
using var scope = Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
|
||||
var location = db.Locations.Single(l => l.Address == "1 rue du Test");
|
||||
|
||||
if (!db.Activities.Any(a => a.Code == "brush"))
|
||||
{
|
||||
db.Activities.Add(new Activity
|
||||
{
|
||||
Code = "brush",
|
||||
Name = "Brush",
|
||||
Hidden = false,
|
||||
DateCreated = DateTime.UtcNow,
|
||||
DateModified = DateTime.UtcNow,
|
||||
});
|
||||
}
|
||||
|
||||
if (!db.Activities.Any(a => a.Code == "mbrush"))
|
||||
{
|
||||
db.Activities.Add(new Activity
|
||||
{
|
||||
Code = "mbrush",
|
||||
Name = "MBrush",
|
||||
Hidden = false,
|
||||
DateCreated = DateTime.UtcNow,
|
||||
DateModified = DateTime.UtcNow,
|
||||
});
|
||||
}
|
||||
|
||||
if (!db.BrusherProfile.Any(p => p.UserId == "alice"))
|
||||
{
|
||||
db.BrusherProfile.Add(new BrusherProfile
|
||||
{
|
||||
UserId = "alice",
|
||||
ActionDistance = 25,
|
||||
WomenLongCutPrice = 50m,
|
||||
WomenHalfCutPrice = 40m,
|
||||
WomenShortCutPrice = 30m,
|
||||
ManCutPrice = 20m,
|
||||
KidCutPrice = 15m,
|
||||
ShampooPrice = 5m,
|
||||
});
|
||||
}
|
||||
|
||||
var prestation1 = new HairPrestation
|
||||
{
|
||||
Gender = HairCutGenders.Women,
|
||||
Length = HairLength.HalfLong,
|
||||
Cut = true,
|
||||
Shampoo = true,
|
||||
Dressing = HairDressings.Brushing,
|
||||
Tech = HairTechnos.NoTech,
|
||||
Cares = false,
|
||||
Taints = new List<HairTaintInstance>(),
|
||||
};
|
||||
var prestation2 = new HairPrestation
|
||||
{
|
||||
Gender = HairCutGenders.Man,
|
||||
Length = HairLength.Short,
|
||||
Cut = true,
|
||||
Shampoo = false,
|
||||
Dressing = HairDressings.Brushing,
|
||||
Tech = HairTechnos.NoTech,
|
||||
Cares = false,
|
||||
Taints = new List<HairTaintInstance>(),
|
||||
};
|
||||
|
||||
db.HairPrestation.AddRange(prestation1, prestation2);
|
||||
db.SaveChanges();
|
||||
|
||||
db.HairCutQueries.Add(new HairCutQuery
|
||||
{
|
||||
ActivityCode = "brush",
|
||||
ClientId = "alice",
|
||||
PerformerId = "alice",
|
||||
Consent = true,
|
||||
EventDate = DateTime.UtcNow.AddDays(3),
|
||||
Location = location,
|
||||
PrestationId = prestation1.Id,
|
||||
Prestation = prestation1,
|
||||
AdditionalInfo = "Coupe test",
|
||||
Status = Yavsc.QueryStatus.Inserted,
|
||||
Description = "Haircut seed",
|
||||
});
|
||||
|
||||
db.HairMultiCutQueries.Add(new HairMultiCutQuery
|
||||
{
|
||||
ActivityCode = "mbrush",
|
||||
ClientId = "alice",
|
||||
PerformerId = "alice",
|
||||
Consent = true,
|
||||
EventDate = DateTime.UtcNow.AddDays(4),
|
||||
Location = location,
|
||||
Prestations = new List<HairPrestationCollectionItem>
|
||||
{
|
||||
new() { PrestationId = prestation1.Id, Prestation = prestation1 },
|
||||
new() { PrestationId = prestation2.Id, Prestation = prestation2 },
|
||||
},
|
||||
Status = Yavsc.QueryStatus.Inserted,
|
||||
});
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
try
|
||||
|
|
|
|||
120
src/Yavsc.Api.Test/HairCutQueryApiControllerTests.cs
Normal file
120
src/Yavsc.Api.Test/HairCutQueryApiControllerTests.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Api.Test.Fixtures;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.Tests.Shared;
|
||||
|
||||
namespace Yavsc.Api.Test;
|
||||
|
||||
[Collection("Yavsc Api")]
|
||||
public sealed class HairCutQueryApiControllerTests : IClassFixture<ApiWebServerFixture>
|
||||
{
|
||||
private readonly ApiWebServerFixture _fixture;
|
||||
|
||||
public HairCutQueryApiControllerTests(ApiWebServerFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
private HttpClient NewClient(string subject = "alice", string scope = "api")
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||
};
|
||||
|
||||
var http = new HttpClient(handler)
|
||||
{
|
||||
BaseAddress = new Uri(_fixture.BaseAddress)
|
||||
};
|
||||
http.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", TestTokenIssuer.Issue(subject, scope));
|
||||
return http;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Billing_brush_route_supports_crud()
|
||||
{
|
||||
_fixture.ResetAndSeedHaircutGraph();
|
||||
using var http = NewClient();
|
||||
|
||||
var prestationId = await GetPrestationIdAsync();
|
||||
|
||||
var createPayload = new HairCutQuery
|
||||
{
|
||||
ActivityCode = "brush",
|
||||
PerformerId = "alice",
|
||||
Consent = true,
|
||||
EventDate = DateTime.UtcNow.AddDays(5),
|
||||
Location = new Location
|
||||
{
|
||||
Address = "2 rue de la Coupe",
|
||||
Latitude = 48.8570,
|
||||
Longitude = 2.3525,
|
||||
},
|
||||
PrestationId = prestationId,
|
||||
AdditionalInfo = "Brushing test",
|
||||
Status = QueryStatus.Inserted,
|
||||
Description = "Haircut create",
|
||||
};
|
||||
|
||||
var createResponse = await http.PostAsJsonAsync("/api/v1/billing/Brush", createPayload, TestContext.Current.CancellationToken);
|
||||
if (createResponse.StatusCode != HttpStatusCode.Created)
|
||||
{
|
||||
var body = await createResponse.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
Assert.Fail($"Unexpected status {createResponse.StatusCode}: {body}");
|
||||
}
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<HairCutQuery>(TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(created);
|
||||
Assert.NotEqual(0, created!.Id);
|
||||
Assert.Equal("alice", created.ClientId);
|
||||
|
||||
var getResponse = await http.GetAsync($"/api/v1/billing/Brush/{created.Id}", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode);
|
||||
|
||||
var fetched = await getResponse.Content.ReadFromJsonAsync<HairCutQuery>(TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(fetched);
|
||||
Assert.Equal(created.Id, fetched!.Id);
|
||||
Assert.Equal("Brushing test", fetched.AdditionalInfo);
|
||||
|
||||
fetched.AdditionalInfo = "Brushing modifié";
|
||||
var putResponse = await http.PutAsJsonAsync($"/api/v1/billing/Brush/{fetched.Id}", fetched, TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.NoContent, putResponse.StatusCode);
|
||||
|
||||
var deleteResponse = await http.DeleteAsync($"/api/v1/billing/Brush/{fetched.Id}", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.OK, deleteResponse.StatusCode);
|
||||
|
||||
var missingResponse = await http.GetAsync($"/api/v1/billing/Brush/{fetched.Id}", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.NotFound, missingResponse.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Billing_brush_route_exposes_prestation_catalog()
|
||||
{
|
||||
_fixture.ResetAndSeedHaircutGraph();
|
||||
using var http = NewClient();
|
||||
|
||||
var response = await http.GetAsync("/api/v1/billing/Brush/prestations", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var catalog = await response.Content.ReadFromJsonAsync<List<HairPrestationDto>>(TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(catalog);
|
||||
Assert.NotEmpty(catalog!);
|
||||
Assert.All(catalog!, item => Assert.False(string.IsNullOrWhiteSpace(item.Title)));
|
||||
Assert.Contains(catalog!, item => item.Title == "Femme · Cheveux mi-longs"
|
||||
&& item.Details == "Coupe · Brushing · Aucune technique spécifique · Shampoing · Sans soins");
|
||||
}
|
||||
|
||||
private async Task<long> GetPrestationIdAsync()
|
||||
{
|
||||
using var scope = _fixture.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
return await db.HairPrestation.Select(p => p.Id).FirstAsync(TestContext.Current.CancellationToken);
|
||||
}
|
||||
}
|
||||
123
src/Yavsc.Api.Test/HairMultiCutQueryApiControllerTests.cs
Normal file
123
src/Yavsc.Api.Test/HairMultiCutQueryApiControllerTests.cs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Yavsc.Api.Test.Fixtures;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.Tests.Shared;
|
||||
|
||||
namespace Yavsc.Api.Test;
|
||||
|
||||
[Collection("Yavsc Api")]
|
||||
public sealed class HairMultiCutQueryApiControllerTests : IClassFixture<ApiWebServerFixture>
|
||||
{
|
||||
private readonly ApiWebServerFixture _fixture;
|
||||
|
||||
public HairMultiCutQueryApiControllerTests(ApiWebServerFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
}
|
||||
|
||||
private HttpClient NewClient(string subject = "alice", string scope = "api")
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||
};
|
||||
|
||||
var http = new HttpClient(handler)
|
||||
{
|
||||
BaseAddress = new Uri(_fixture.BaseAddress)
|
||||
};
|
||||
http.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", TestTokenIssuer.Issue(subject, scope));
|
||||
return http;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Billing_mbrush_route_supports_crud()
|
||||
{
|
||||
_fixture.ResetAndSeedHaircutGraph();
|
||||
using var http = NewClient();
|
||||
|
||||
var prestationIds = await GetPrestationIdsAsync();
|
||||
|
||||
var createPayload = new HairMultiCutQuery
|
||||
{
|
||||
ActivityCode = "mbrush",
|
||||
PerformerId = "alice",
|
||||
Consent = true,
|
||||
EventDate = DateTime.UtcNow.AddDays(6),
|
||||
Location = new Location
|
||||
{
|
||||
Address = "3 rue du Groupe",
|
||||
Latitude = 48.8580,
|
||||
Longitude = 2.3530,
|
||||
},
|
||||
Prestations = prestationIds.Select(id => new HairPrestationCollectionItem { PrestationId = id }).ToList(),
|
||||
Status = QueryStatus.Inserted,
|
||||
};
|
||||
|
||||
var createResponse = await http.PostAsJsonAsync("/api/v1/billing/MBrush", createPayload, TestContext.Current.CancellationToken);
|
||||
if (createResponse.StatusCode != HttpStatusCode.Created)
|
||||
{
|
||||
var body = await createResponse.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
Assert.Fail($"Unexpected status {createResponse.StatusCode}: {body}");
|
||||
}
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<HairMultiCutQuery>(TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(created);
|
||||
Assert.NotEqual(0, created!.Id);
|
||||
Assert.Equal("alice", created.ClientId);
|
||||
Assert.Equal(2, created.Prestations.Count);
|
||||
|
||||
var getResponse = await http.GetAsync($"/api/v1/billing/MBrush/{created.Id}", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode);
|
||||
|
||||
var fetched = await getResponse.Content.ReadFromJsonAsync<HairMultiCutQuery>(TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(fetched);
|
||||
Assert.Equal(created.Id, fetched!.Id);
|
||||
Assert.Equal(2, fetched.Prestations.Count);
|
||||
|
||||
fetched.Status = QueryStatus.Accepted;
|
||||
var putResponse = await http.PutAsJsonAsync($"/api/v1/billing/MBrush/{fetched.Id}", fetched, TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.NoContent, putResponse.StatusCode);
|
||||
|
||||
var deleteResponse = await http.DeleteAsync($"/api/v1/billing/MBrush/{fetched.Id}", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.OK, deleteResponse.StatusCode);
|
||||
|
||||
var missingResponse = await http.GetAsync($"/api/v1/billing/MBrush/{fetched.Id}", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.NotFound, missingResponse.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Billing_mbrush_route_exposes_prestation_catalog()
|
||||
{
|
||||
_fixture.ResetAndSeedHaircutGraph();
|
||||
using var http = NewClient();
|
||||
|
||||
var response = await http.GetAsync("/api/v1/billing/MBrush/prestations", TestContext.Current.CancellationToken);
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var catalog = await response.Content.ReadFromJsonAsync<List<HairPrestationDto>>(TestContext.Current.CancellationToken);
|
||||
Assert.NotNull(catalog);
|
||||
Assert.NotEmpty(catalog!);
|
||||
Assert.All(catalog!, item => Assert.False(string.IsNullOrWhiteSpace(item.Details)));
|
||||
Assert.Contains(catalog!, item => item.Title == "Femme · Cheveux mi-longs"
|
||||
&& item.Details == "Coupe · Brushing · Aucune technique spécifique · Shampoing · Sans soins");
|
||||
}
|
||||
|
||||
private async Task<List<long>> GetPrestationIdsAsync()
|
||||
{
|
||||
using var scope = _fixture.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
return await db.HairPrestation
|
||||
.OrderBy(p => p.Id)
|
||||
.Select(p => p.Id)
|
||||
.Take(2)
|
||||
.ToListAsync(TestContext.Current.CancellationToken);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue