Skip to content

Commit d7bed9d

Browse files
authored
feat: B/P Detailed Errors, race condition fixes, and preliminary support for the Customer Account API (#177)
1 parent 4ce5b1c commit d7bed9d

47 files changed

Lines changed: 1155 additions & 993 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/openactive-test-suite.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
connection_string: ${{ secrets.CONFORMANCE_CERTIFICATE_BLOB_STORAGE_CONNECTION_STRING }}
8484
sync: false
8585
framework:
86-
runs-on: windows-latest
86+
runs-on: windows-2019
8787
strategy:
8888
fail-fast: false
8989
matrix:

Examples/BookingSystem.AspNetCore/BookingSystem.AspNetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<Publish Condition="'%(PackageReference.Version)' == ''">true</Publish>
1212
</PackageReference>
1313
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.2" />
14-
<PackageReference Include="OpenActive.NET" Version="15.2.6" />
14+
<PackageReference Include="OpenActive.NET" Version="15.2.11" />
1515
</ItemGroup>
1616

1717
<ItemGroup>

Examples/BookingSystem.AspNetCore/Controllers/OpenBookingController.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task<ContentResult> OrderQuoteCreationC1([FromServices] IBookingEng
3333
{
3434
try
3535
{
36-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
36+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
3737
return (await bookingEngine.ProcessCheckpoint1(clientId, sellerId, uuid, orderQuote)).GetContentResult();
3838
}
3939
catch (OpenBookingException obe)
@@ -52,7 +52,7 @@ public async Task<ContentResult> OrderQuoteCreationC2([FromServices] IBookingEng
5252
{
5353
try
5454
{
55-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
55+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
5656
return (await bookingEngine.ProcessCheckpoint2(clientId, sellerId, uuid, orderQuote)).GetContentResult();
5757
}
5858
catch (OpenBookingException obe)
@@ -71,7 +71,7 @@ public async Task<ContentResult> OrderProposalCreationP([FromServices] IBookingE
7171
{
7272
try
7373
{
74-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
74+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
7575
return (await bookingEngine.ProcessOrderProposalCreationP(clientId, sellerId, uuid, orderProposal)).GetContentResult();
7676
}
7777
catch (OpenBookingException obe)
@@ -90,7 +90,7 @@ public async Task<IActionResult> OrderQuoteDeletion([FromServices] IBookingEngin
9090
{
9191
try
9292
{
93-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
93+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
9494
return (await bookingEngine.DeleteOrderQuote(clientId, sellerId, uuid)).GetContentResult();
9595
}
9696
catch (OpenBookingException obe)
@@ -109,7 +109,7 @@ public async Task<ContentResult> OrderCreationB([FromServices] IBookingEngine bo
109109
{
110110
try
111111
{
112-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
112+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
113113
return (await bookingEngine.ProcessOrderCreationB(clientId, sellerId, uuid, order)).GetContentResult();
114114
}
115115
catch (OpenBookingException obe)
@@ -128,7 +128,7 @@ public async Task<IActionResult> OrderDeletion([FromServices] IBookingEngine boo
128128
{
129129
try
130130
{
131-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
131+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
132132
return (await bookingEngine.DeleteOrder(clientId, sellerId, uuid)).GetContentResult();
133133
}
134134
catch (OpenBookingException obe)
@@ -147,7 +147,7 @@ public async Task<IActionResult> OrderUpdate([FromServices] IBookingEngine booki
147147
{
148148
try
149149
{
150-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
150+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
151151
return (await bookingEngine.ProcessOrderUpdate(clientId, sellerId, uuid, order)).GetContentResult();
152152
}
153153
catch (OpenBookingException obe)
@@ -167,7 +167,7 @@ public async Task<IActionResult> OrderProposalUpdate([FromServices] IBookingEngi
167167
{
168168
try
169169
{
170-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
170+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
171171
return (await bookingEngine.ProcessOrderProposalUpdate(clientId, sellerId, uuid, order)).GetContentResult();
172172
}
173173
catch (OpenBookingException obe)
@@ -183,7 +183,7 @@ public async Task<IActionResult> GetOrderStatus([FromServices] IBookingEngine bo
183183
{
184184
try
185185
{
186-
(string clientId, Uri sellerId) = User.GetAccessTokenOpenBookingClaims();
186+
(string clientId, Uri sellerId, _) = User.GetAccessTokenOpenBookingClaims();
187187
return (await bookingEngine.GetOrderStatus(clientId, sellerId, uuid)).GetContentResult();
188188
}
189189
catch (OpenBookingException obe)

Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ protected override async Task<List<RpdeItem<FacilityUse>>> GetRpdeItems(long? af
7272
IsOpenBookingAllowed = true,
7373
} : new Organization
7474
{
75-
Id = RenderSellerId(new SellerIdComponents { SellerIdLong = result.Item2.Id }),
75+
Id = RenderSellerId(new SimpleIdComponents { IdLong = result.Item2.Id }),
7676
Name = result.Item2.Name,
7777
TaxMode = result.Item2.IsTaxGross ? TaxMode.TaxGross : TaxMode.TaxNet,
7878
TermsOfService = new List<Terms>

Examples/BookingSystem.AspNetCore/Feeds/SessionsFeeds.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,13 @@ protected override async Task<List<RpdeItem<SessionSeries>>> GetRpdeItems(long?
123123
IsOpenBookingAllowed = true,
124124
} : result.Item2.IsIndividual ? (ILegalEntity)new Person
125125
{
126-
Id = RenderSellerId(new SellerIdComponents { SellerIdLong = result.Item2.Id }),
126+
Id = RenderSellerId(new SimpleIdComponents { IdLong = result.Item2.Id }),
127127
Name = result.Item2.Name,
128128
TaxMode = result.Item2.IsTaxGross ? TaxMode.TaxGross : TaxMode.TaxNet,
129129
IsOpenBookingAllowed = true,
130130
} : (ILegalEntity)new Organization
131131
{
132-
Id = RenderSellerId(new SellerIdComponents { SellerIdLong = result.Item2.Id }),
132+
Id = RenderSellerId(new SimpleIdComponents { IdLong = result.Item2.Id }),
133133
Name = result.Item2.Name,
134134
TaxMode = result.Item2.IsTaxGross ? TaxMode.TaxGross : TaxMode.TaxNet,
135135
TermsOfService = new List<Terms>

Examples/BookingSystem.AspNetCore/Settings/EngineConfig.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,15 @@ public static StoreBookingEngine CreateStoreBookingEngine(AppSettings appSetting
111111
/*
112112
// Multiple Seller Mode
113113
SellerStore = new AcmeSellerStore(),
114-
SellerIdTemplate = new SingleIdTemplate<SellerIdComponents>(
115-
"{+BaseUrl}/sellers/{SellerIdLong}"
114+
SellerIdTemplate = new SingleIdTemplate<SimpleIdComponents>(
115+
"{+BaseUrl}/sellers/{IdLong}"
116116
),
117117
*/
118118

119119
/*
120120
// Single Seller Mode
121121
SellerStore = new AcmeSellerStore(),
122-
SellerIdTemplate = new SingleIdTemplate<SellerIdComponents>(
122+
SellerIdTemplate = new SingleIdTemplate<SimpleIdComponents>(
123123
"{+BaseUrl}/seller"
124124
),
125125
HasSingleSeller = true,
@@ -128,11 +128,11 @@ public static StoreBookingEngine CreateStoreBookingEngine(AppSettings appSetting
128128
// Reference implementation is configurable to allow both modes to be tested
129129
SellerStore = new AcmeSellerStore(appSettings.FeatureFlags.SingleSeller),
130130
SellerIdTemplate = appSettings.FeatureFlags.SingleSeller ?
131-
new SingleIdTemplate<SellerIdComponents>(
131+
new SingleIdTemplate<SimpleIdComponents>(
132132
"{+BaseUrl}/seller"
133133
) :
134-
new SingleIdTemplate<SellerIdComponents>(
135-
"{+BaseUrl}/sellers/{SellerIdLong}"
134+
new SingleIdTemplate<SimpleIdComponents>(
135+
"{+BaseUrl}/sellers/{IdLong}"
136136
),
137137
HasSingleSeller = appSettings.FeatureFlags.SingleSeller,
138138

Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ protected override async Task<FacilityOpportunity> CreateOpportunityWithinTestDa
2828
OpportunityType opportunityType,
2929
TestOpportunityCriteriaEnumeration criteria,
3030
TestOpenBookingFlowEnumeration openBookingFlow,
31-
SellerIdComponents seller)
31+
SimpleIdComponents seller)
3232
{
33-
if (!_appSettings.FeatureFlags.SingleSeller && !seller.SellerIdLong.HasValue)
33+
if (!_appSettings.FeatureFlags.SingleSeller && !seller.IdLong.HasValue)
3434
throw new OpenBookingException(new OpenBookingError(), "Seller must have an ID in Multiple Seller Mode");
3535

36-
long? sellerId = _appSettings.FeatureFlags.SingleSeller ? null : seller.SellerIdLong;
36+
long? sellerId = _appSettings.FeatureFlags.SingleSeller ? null : seller.IdLong;
3737
var requiresApproval = openBookingFlow == TestOpenBookingFlowEnumeration.OpenBookingApprovalFlow;
3838

3939
switch (opportunityType)
@@ -286,7 +286,7 @@ protected override async Task TriggerTestAction(OpenBookingSimulateAction simula
286286
// Similar to the RPDE logic, this needs to render and return an new hypothetical OrderItem from the database based on the supplied opportunity IDs
287287
protected override async Task GetOrderItems(List<OrderItemContext<FacilityOpportunity>> orderItemContexts, StoreBookingFlowContext flowContext, OrderStateContext stateContext)
288288
{
289-
// Note the implementation of this method must also check that this OrderItem is from the Seller specified by context.SellerIdComponents (this is not required if using a Single Seller)
289+
// Note the implementation of this method must also check that this OrderItem is from the Seller specified by context.SellerId (this is not required if using a Single Seller)
290290

291291
// Additionally this method must check that there are enough spaces in each entry
292292

@@ -377,7 +377,7 @@ protected override async Task GetOrderItems(List<OrderItemContext<FacilityOpport
377377
: null,
378378
OrderItemIntakeFormResponse = orderItemContext.RequestOrderItem.OrderItemIntakeFormResponse,
379379
},
380-
SellerId = _appSettings.FeatureFlags.SingleSeller ? new SellerIdComponents() : new SellerIdComponents { SellerIdLong = facility.SellerId },
380+
SellerId = _appSettings.FeatureFlags.SingleSeller ? new SimpleIdComponents() : new SimpleIdComponents { IdLong = facility.SellerId },
381381
slot.RequiresApproval,
382382
BookedOrderItemInfo = bookedOrderItemInfo,
383383
slot.RemainingUses
@@ -433,7 +433,7 @@ protected override async ValueTask LeaseOrderItems(Lease lease, List<OrderItemCo
433433
else
434434
{
435435
// Attempt to lease for those with the same IDs, which is atomic
436-
var (result, capacityErrors, capacityLeaseErrors) = await FakeDatabase.LeaseOrderItemsForFacilitySlot(databaseTransaction.FakeDatabaseTransaction, flowContext.OrderId.ClientId, flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */, flowContext.OrderId.uuid, ctxGroup.Key.SlotId.Value, ctxGroup.Count());
436+
var (result, capacityErrors, capacityLeaseErrors) = await FakeDatabase.LeaseOrderItemsForFacilitySlot(databaseTransaction.FakeDatabaseTransaction, flowContext.OrderId.ClientId, flowContext.SellerId.IdLong ?? null /* Hack to allow this to work in Single Seller mode too */, flowContext.OrderId.uuid, ctxGroup.Key.SlotId.Value, ctxGroup.Count());
437437

438438
switch (result)
439439
{
@@ -504,13 +504,25 @@ protected override async ValueTask BookOrderItems(List<OrderItemContext<Facility
504504
var (result, bookedOrderItemInfos) = await FakeDatabase.BookOrderItemsForFacilitySlot(
505505
databaseTransaction.FakeDatabaseTransaction,
506506
flowContext.OrderId.ClientId,
507-
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
507+
flowContext.SellerId.IdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
508508
flowContext.OrderId.uuid,
509509
ctxGroup.Key.SlotId.Value,
510510
RenderOpportunityId(ctxGroup.Key),
511511
RenderOfferId(ctxGroup.Key),
512512
ctxGroup.Count(),
513-
false
513+
false,
514+
ctxGroup
515+
.Select(x =>
516+
x.RequestOrderItem.Attendee == null
517+
? null
518+
: OpenActiveSerializer.Serialize(x.RequestOrderItem.Attendee))
519+
.ToList(),
520+
ctxGroup
521+
.Select(x =>
522+
x.RequestOrderItem.OrderItemIntakeFormResponse == null
523+
? null
524+
: OpenActiveSerializer.SerializeList(x.RequestOrderItem.OrderItemIntakeFormResponse))
525+
.ToList()
514526
);
515527

516528
switch (result)
@@ -555,13 +567,25 @@ protected override async ValueTask ProposeOrderItems(List<OrderItemContext<Facil
555567
var (result, bookedOrderItemInfos) = await FakeDatabase.BookOrderItemsForFacilitySlot(
556568
databaseTransaction.FakeDatabaseTransaction,
557569
flowContext.OrderId.ClientId,
558-
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
570+
flowContext.SellerId.IdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
559571
flowContext.OrderId.uuid,
560572
ctxGroup.Key.SlotId.Value,
561573
RenderOpportunityId(ctxGroup.Key),
562574
RenderOfferId(ctxGroup.Key),
563575
ctxGroup.Count(),
564-
true
576+
true,
577+
ctxGroup
578+
.Select(x =>
579+
x.RequestOrderItem.Attendee == null
580+
? null
581+
: OpenActiveSerializer.Serialize(x.RequestOrderItem.Attendee))
582+
.ToList(),
583+
ctxGroup
584+
.Select(x =>
585+
x.RequestOrderItem.OrderItemIntakeFormResponse == null
586+
? null
587+
: OpenActiveSerializer.SerializeList(x.RequestOrderItem.OrderItemIntakeFormResponse))
588+
.ToList()
565589
);
566590

567591
switch (result)

0 commit comments

Comments
 (0)