Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: change requests to accept IdReferences #113

Merged
merged 8 commits into from
Apr 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/openactive-test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ jobs:

- name: Deploy conformance certificate to Azure Blob Storage (master branch for 'all-features' profile in controlled mode only)
uses: bacongobbler/[email protected]
# if: ${{ github.ref == 'refs/heads/master' && matrix.profile == 'all-features' && matrix.mode == 'controlled' }}
if: ${{ github.ref == 'refs/heads/master' }}
with:
source_dir: ./tests/conformance/
container_name: '$web'
Expand Down Expand Up @@ -155,10 +155,11 @@ jobs:
env:
FORCE_COLOR: 1
NODE_CONFIG: |
{"broker": {"outputPath": "../../output/", "datasetSiteUrl": "http://localhost:5000/openactive"}, "integrationTests": {"outputPath": "../../output/", "useRandomOpportunities": ${{ matrix.mode == 'random' }}, "conformanceCertificateId": "https://openactive.io/OpenActive.Server.NET/certification/"}, "sellers": { "primary": {"@id": "http://localhost:5000/api/identifiers/sellers/1", "authentication": { "loginCredentials": null, "requestHeaders": { "X-OpenActive-Test-Client-Id": "test", "X-OpenActive-Test-Seller-Id": "http://localhost:5000/api/identifiers/sellers/1" } } }, "secondary": { "@id": "http://localhost:5000/api/identifiers/sellers/2", "authentication": { "loginCredentials": null, "requestHeaders": { "X-OpenActive-Test-Client-Id": "test", "X-OpenActive-Test-Seller-Id": "http://localhost:5000/api/identifiers/sellers/2" } } } }}
{"broker": {"outputPath": "../../output/"}, "integrationTests": {"outputPath": "../../output/", "useRandomOpportunities": ${{ matrix.mode == 'random' }}, "conformanceCertificateId": "https://openactive.io/OpenActive.Server.NET/certification/"}}
NODE_ENV: .example.${{ matrix.profile }}
NODE_APP_INSTANCE: ci
NODE_APP_INSTANCE: framework
working-directory: tests

- name: Upload test output for ${{ matrix.mode }} mode as artifact
uses: actions/upload-artifact@v2
if: ${{ success() || failure() }}
Expand Down
4 changes: 2 additions & 2 deletions Examples/BookingSystem.AspNetCore/Feeds/OrdersFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ protected async override Task<List<RpdeItem>> GetRPDEItems(string clientId, long
Id = result.OrderTable.OrderMode == OrderMode.Booking ? RenderOrderItemId(OrderType.Order, result.OrderTable.OrderId, orderItem.Id) : null,
AcceptedOffer = new Offer
{
Id = new Uri(orderItem.OfferJsonLdId),
Id = orderItem.OfferJsonLdId,
Price = orderItem.Price,
PriceCurrency = "GBP"
},
OrderedItem = RenderOpportunityWithOnlyId(orderItem.OpportunityJsonLdType, new Uri(orderItem.OpportunityJsonLdId)),
OrderedItem = orderItem.OpportunityJsonLdId,
AccessChannel = orderItem.MeetingUrl != null ? new VirtualLocation()
{
Name = "Zoom Video Chat",
Expand Down
10 changes: 4 additions & 6 deletions Examples/BookingSystem.AspNetCore/Stores/FacilityStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,8 @@ protected async override ValueTask BookOrderItems(List<OrderItemContext<Facility
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.SlotId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
false
);
Expand Down Expand Up @@ -545,9 +544,8 @@ protected async override ValueTask ProposeOrderItems(List<OrderItemContext<Facil
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.SlotId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
true
);
Expand Down
7 changes: 2 additions & 5 deletions Examples/BookingSystem.AspNetCore/Stores/OrderStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,8 @@ public async override Task<Order> GetOrderStatus(OrderIdComponents orderId, Sell
var orderItems = dbOrderItems.Select((orderItem) => new OrderItem
{
Id = dbOrder.OrderMode == OrderMode.Booking ? RenderOrderItemId(OrderType.Order, dbOrder.OrderId, orderItem.Id) : null,
AcceptedOffer = new Offer
{
Id = new Uri(orderItem.OfferJsonLdId),
},
OrderedItem = RenderOpportunityWithOnlyId(orderItem.OpportunityJsonLdType, new Uri(orderItem.OpportunityJsonLdId)),
AcceptedOffer = orderItem.OfferJsonLdId,
OrderedItem = orderItem.OpportunityJsonLdId,
OrderItemStatus =
orderItem.Status == BookingStatus.Confirmed ? OrderItemStatus.OrderItemConfirmed :
orderItem.Status == BookingStatus.CustomerCancelled ? OrderItemStatus.CustomerCancelled :
Expand Down
10 changes: 4 additions & 6 deletions Examples/BookingSystem.AspNetCore/Stores/SessionStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,8 @@ protected async override ValueTask BookOrderItems(List<OrderItemContext<SessionO
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.ScheduledSessionId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
false
);
Expand Down Expand Up @@ -595,9 +594,8 @@ protected async override ValueTask ProposeOrderItems(List<OrderItemContext<Sessi
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.ScheduledSessionId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
true
);
Expand Down
4 changes: 2 additions & 2 deletions Examples/BookingSystem.AspNetFramework/Feeds/OrdersFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ protected async override Task<List<RpdeItem>> GetRPDEItems(string clientId, long
Id = result.OrderTable.OrderMode == OrderMode.Booking ? RenderOrderItemId(OrderType.Order, result.OrderTable.OrderId, orderItem.Id) : null,
AcceptedOffer = new Offer
{
Id = new Uri(orderItem.OfferJsonLdId),
Id = orderItem.OfferJsonLdId,
Price = orderItem.Price,
PriceCurrency = "GBP"
},
OrderedItem = RenderOpportunityWithOnlyId(orderItem.OpportunityJsonLdType, new Uri(orderItem.OpportunityJsonLdId)),
OrderedItem = orderItem.OpportunityJsonLdId,
AccessChannel = orderItem.MeetingUrl != null ? new VirtualLocation()
{
Name = "Zoom Video Chat",
Expand Down
10 changes: 4 additions & 6 deletions Examples/BookingSystem.AspNetFramework/Stores/FacilityStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,8 @@ protected async override ValueTask BookOrderItems(List<OrderItemContext<Facility
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.SlotId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
false
);
Expand Down Expand Up @@ -545,9 +544,8 @@ protected async override ValueTask ProposeOrderItems(List<OrderItemContext<Facil
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.SlotId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
true
);
Expand Down
7 changes: 2 additions & 5 deletions Examples/BookingSystem.AspNetFramework/Stores/OrderStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,8 @@ public async override Task<Order> GetOrderStatus(OrderIdComponents orderId, Sell
var orderItems = dbOrderItems.Select((orderItem) => new OrderItem
{
Id = dbOrder.OrderMode == OrderMode.Booking ? RenderOrderItemId(OrderType.Order, dbOrder.OrderId, orderItem.Id) : null,
AcceptedOffer = new Offer
{
Id = new Uri(orderItem.OfferJsonLdId),
},
OrderedItem = RenderOpportunityWithOnlyId(orderItem.OpportunityJsonLdType, new Uri(orderItem.OpportunityJsonLdId)),
AcceptedOffer = orderItem.OfferJsonLdId,
OrderedItem = orderItem.OpportunityJsonLdId,
OrderItemStatus =
orderItem.Status == BookingStatus.Confirmed ? OrderItemStatus.OrderItemConfirmed :
orderItem.Status == BookingStatus.CustomerCancelled ? OrderItemStatus.CustomerCancelled :
Expand Down
10 changes: 4 additions & 6 deletions Examples/BookingSystem.AspNetFramework/Stores/SessionStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,8 @@ protected async override ValueTask BookOrderItems(List<OrderItemContext<SessionO
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.ScheduledSessionId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
false
);
Expand Down Expand Up @@ -595,9 +594,8 @@ protected async override ValueTask ProposeOrderItems(List<OrderItemContext<Sessi
flowContext.SellerId.SellerIdLong ?? null /* Hack to allow this to work in Single Seller mode too */,
flowContext.OrderId.uuid,
ctxGroup.Key.ScheduledSessionId.Value,
RenderOpportunityJsonLdType(ctxGroup.Key),
RenderOpportunityId(ctxGroup.Key).ToString(),
RenderOfferId(ctxGroup.Key).ToString(),
RenderOpportunityId(ctxGroup.Key),
RenderOfferId(ctxGroup.Key),
ctxGroup.Count(),
true
);
Expand Down
5 changes: 2 additions & 3 deletions Fakes/OpenActive.FakeDatabase.NET/DatabaseTables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ public class OccurrenceTable : Table
public class OrderItemsTable : Table
{
public string ClientId { get; internal set; }
public string OpportunityJsonLdType { get; set; }
public string OpportunityJsonLdId { get; set; }
public string OfferJsonLdId { get; set; }
public Uri OpportunityJsonLdId { get; set; }
public Uri OfferJsonLdId { get; set; }
[Reference]
public OrderTable OrderTable { get; set; }
[ForeignKey(typeof(OrderTable), OnDelete = "CASCADE")]
Expand Down
26 changes: 11 additions & 15 deletions Fakes/OpenActive.FakeDatabase.NET/FakeBookingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -731,9 +731,8 @@ public static (ReserveOrderItemsResult, List<BookedOrderItemInfo>) BookOrderItem
long? sellerId,
string uuid,
long occurrenceId,
string opportunityJsonLdType,
string opportunityJsonLdId,
string offerJsonLdId,
Uri opportunityJsonLdId,
Uri offerJsonLdId,
long numberOfSpaces,
bool proposal
)
Expand Down Expand Up @@ -770,7 +769,6 @@ bool proposal
OrderId = uuid,
Status = proposal ? BookingStatus.Proposed : BookingStatus.Confirmed,
OccurrenceId = occurrenceId,
OpportunityJsonLdType = opportunityJsonLdType,
OpportunityJsonLdId = opportunityJsonLdId,
OfferJsonLdId = offerJsonLdId,
// Include the price locked into the OrderItem as the opportunity price may change
Expand Down Expand Up @@ -806,9 +804,8 @@ public static (ReserveOrderItemsResult, List<BookedOrderItemInfo>) BookOrderItem
long? sellerId,
string uuid,
long slotId,
string opportunityJsonLdType,
string opportunityJsonLdId,
string offerJsonLdId,
Uri opportunityJsonLdId,
Uri offerJsonLdId,
long numberOfSpaces,
bool proposal
)
Expand Down Expand Up @@ -845,7 +842,6 @@ bool proposal
OrderId = uuid,
Status = proposal ? BookingStatus.Proposed : BookingStatus.Confirmed,
SlotId = slotId,
OpportunityJsonLdType = opportunityJsonLdType,
OpportunityJsonLdId = opportunityJsonLdId,
OfferJsonLdId = offerJsonLdId,
// Include the price locked into the OrderItem as the opportunity price may change
Expand Down Expand Up @@ -1015,10 +1011,10 @@ public bool ReplaceOrderOpportunity(string uuid)
var slot = db.Select(slotQuery).Single();

// Hack to replace JSON LD Ids
orderItem.OpportunityJsonLdId = orderItem.OpportunityJsonLdId.Replace($"facility-uses/{oldSlot.FacilityUseId}", $"facility-uses/{slot.FacilityUseId}");
orderItem.OpportunityJsonLdId = orderItem.OpportunityJsonLdId.Replace($"facility-use-slots/{oldSlot.Id}", $"facility-use-slots/{slot.Id}");
orderItem.OfferJsonLdId = orderItem.OfferJsonLdId.Replace($"facility-uses/{oldSlot.FacilityUseId}", $"facility-uses/{slot.FacilityUseId}");
orderItem.OfferJsonLdId = orderItem.OfferJsonLdId.Replace($"facility-uses-slots/{oldSlot.Id}", $"facility-uses-slots/{slot.Id}");
orderItem.OpportunityJsonLdId = new Uri(orderItem.OpportunityJsonLdId.ToString().Replace($"facility-uses/{oldSlot.FacilityUseId}", $"facility-uses/{slot.FacilityUseId}"));
orderItem.OpportunityJsonLdId = new Uri(orderItem.OpportunityJsonLdId.ToString().Replace($"facility-use-slots/{oldSlot.Id}", $"facility-use-slots/{slot.Id}"));
orderItem.OfferJsonLdId = new Uri(orderItem.OfferJsonLdId.ToString().Replace($"facility-uses/{oldSlot.FacilityUseId}", $"facility-uses/{slot.FacilityUseId}"));
orderItem.OfferJsonLdId = new Uri(orderItem.OfferJsonLdId.ToString().Replace($"facility-uses-slots/{oldSlot.Id}", $"facility-uses-slots/{slot.Id}"));

orderItem.SlotId = slot.Id;
}
Expand All @@ -1036,9 +1032,9 @@ public bool ReplaceOrderOpportunity(string uuid)
.Take(1);
var occurrence = db.Select(occurrenceQuery).Single();
// Hack to replace JSON LD Ids
orderItem.OpportunityJsonLdId = orderItem.OpportunityJsonLdId.Replace($"scheduled-sessions/{oldOccurrence.ClassId}", $"scheduled-sessions/{occurrence.ClassId}");
orderItem.OpportunityJsonLdId = orderItem.OpportunityJsonLdId.Replace($"events/{orderItem.OccurrenceId}", $"events/{occurrence.Id}");
orderItem.OfferJsonLdId = orderItem.OfferJsonLdId.Replace($"session-series/{oldOccurrence.ClassId}", $"session-series/{occurrence.ClassId}");
orderItem.OpportunityJsonLdId = new Uri(orderItem.OpportunityJsonLdId.ToString().Replace($"scheduled-sessions/{oldOccurrence.ClassId}", $"scheduled-sessions/{occurrence.ClassId}"));
orderItem.OpportunityJsonLdId = new Uri(orderItem.OpportunityJsonLdId.ToString().Replace($"events/{orderItem.OccurrenceId}", $"events/{occurrence.Id}"));
orderItem.OfferJsonLdId = new Uri(orderItem.OfferJsonLdId.ToString().Replace($"session-series/{oldOccurrence.ClassId}", $"session-series/{occurrence.ClassId}"));

orderItem.OccurrenceId = occurrence.Id;
}
Expand Down
13 changes: 5 additions & 8 deletions OpenActive.Server.NET/CustomBookingEngine/CustomBookingEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,25 +298,22 @@ protected bool IsOpportunityTypeRecognised(string opportunityTypeString)
}

// Note this is not a helper as it relies on engine settings state
protected IBookableIdComponents ResolveOpportunityID(string opportunityTypeString, Uri opportunityId, Uri offerId)
protected IBookableIdComponents ResolveOpportunityID(Uri opportunityId, Uri offerId)
{
// Return the first matching ID combination for the opportunityId and offerId provided.
// TODO: Make this more efficient?
return this.idConfigurationLookup[opportunityTypeString]
return this.idConfigurationLookup
.SelectMany(x => x.Value)
.Select(x => x.GetOpportunityReference(opportunityId, offerId))
.Where(x => x != null)
.FirstOrDefault();
.FirstOrDefault(x => x != null);
}

// Note this is not a helper as it relies on engine settings state
protected IBookableIdComponents ResolveOpportunityID(string opportunityTypeString, Uri opportunityId)
{
// Return the first matching ID combination for the opportunityId and offerId provided.
// TODO: Make this more efficient?
return this.idConfigurationLookup[opportunityTypeString]
.Select(x => x.GetOpportunityBookableIdComponents(opportunityId))
.Where(x => x != null)
.FirstOrDefault();
.FirstOrDefault(x => x != null);
}

public async Task<ResponseContent> ProcessCheckpoint1(string clientId, Uri sellerId, string uuid, string orderQuoteJson)
Expand Down
10 changes: 0 additions & 10 deletions OpenActive.Server.NET/OpenBookingHelper/IdTransforms/IdTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,16 +322,6 @@ public Uri RenderOpportunityId(OpportunityType opportunityType, TBookableIdCompo
throw new ArgumentOutOfRangeException(nameof(opportunityType), "OpportunityType was not found within this template. Please check it is appropriate for this feed or OrderItem.");
}

public string RenderOpportunityJsonLdType(TBookableIdComponents components)
{
if (components == null || !components.OpportunityType.HasValue)
{
throw new ArgumentNullException("OpportunityType must be set on IBookableIdComponents");
}
// TODO: Create an extra prop in DatasetSite lib so that we don't need to parse the URL here
return OpportunityTypes.Configurations[components.OpportunityType.Value].SameAs.AbsolutePath.Trim('/');
}

public Uri RenderOfferId(TBookableIdComponents components)
{
// If inheritance is available on the IdComponent, ensure that it is respected (i.e. the correct offer is rendered, even if on the parent)
Expand Down
Loading