Skip to content

Commit d643a02

Browse files
authored
feat: Add IFU CI support (#204)
1 parent 92bcb97 commit d643a02

24 files changed

Lines changed: 850 additions & 596 deletions

File tree

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
fail-fast: false
4444
matrix:
4545
mode: ['random', 'controlled']
46-
profile: ['all-features', 'single-seller', 'no-payment-reconciliation', 'no-auth', 'no-tax-calculation', 'prepayment-always-required']
46+
profile: ['all-features', 'single-seller', 'no-payment-reconciliation', 'no-auth', 'no-tax-calculation', 'prepayment-always-required', 'facilityuse-has-slots']
4747
steps:
4848
- name: Checkout OpenActive.Server.NET
4949
uses: actions/checkout@v2
@@ -177,7 +177,6 @@ jobs:
177177
if: ${{ github.ref == 'refs/heads/master' }}
178178
needs:
179179
- core
180-
- framework
181180
runs-on: ubuntu-latest
182181
steps:
183182
# Checkout the repo

Examples/BookingSystem.AspNetCore.IdentityServer/Custom/Settings/AppSettings.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,14 @@
33
public class AppSettings
44
{
55
public string JsonLdIdBaseUrl { get; set; }
6+
public FeatureSettings FeatureFlags { get; set; }
7+
}
8+
9+
/**
10+
* Note feature defaults are set here, and are used for the .NET Framework reference implementation
11+
*/
12+
public class FeatureSettings
13+
{
14+
public bool FacilityUseHasSlots { get; set; } = false;
615
}
716
}

Examples/BookingSystem.AspNetCore.IdentityServer/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public Startup(IWebHostEnvironment environment, IConfiguration configuration)
2727
public void ConfigureServices(IServiceCollection services)
2828
{
2929
services.AddTransient<IClientStore, ClientStore>();
30-
services.AddSingleton<FakeBookingSystem>();
30+
services.AddSingleton(x => new FakeBookingSystem(AppSettings.FeatureFlags.FacilityUseHasSlots));
3131

3232
var builder = services.AddIdentityServer(options =>
3333
{
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"FeatureFlags": {
3+
"FacilityUseHasSlots": true
4+
}
5+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{
22
"Urls": "https://localhost:5003;http://localhost:5002",
3-
"JsonLdIdBaseUrl": "https://localhost:5001"
3+
"JsonLdIdBaseUrl": "https://localhost:5001",
4+
"FeatureFlags": {
5+
"FacilityUseHasSlots": false
6+
}
47
}

Examples/BookingSystem.AspNetCore/Feeds/FacilitiesFeeds.cs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,17 @@ protected override async Task<List<RpdeItem<FacilityUse>>> GetRpdeItems(long? af
100100
PrefLabel = facilityTypePrefLabel,
101101
InScheme = new Uri("https://openactive.io/facility-types")
102102
}
103-
}
103+
},
104+
IndividualFacilityUse = result.Item1.IndividualFacilityUses != null ? result.Item1.IndividualFacilityUses.Select(ifu => new OpenActive.NET.IndividualFacilityUse
105+
{
106+
Id = RenderOpportunityId(new FacilityOpportunity
107+
{
108+
OpportunityType = OpportunityType.IndividualFacilityUse,
109+
IndividualFacilityUseId = ifu.Id,
110+
FacilityUseId = result.Item1.Id
111+
}),
112+
Name = ifu.Name
113+
}).ToList() : null,
104114
}
105115
});
106116

@@ -136,7 +146,7 @@ protected override async Task<List<RpdeItem<Slot>>> GetRpdeItems(long? afterTime
136146
.Take(RpdePageSize)
137147
.Select(x => new RpdeItem<Slot>
138148
{
139-
Kind = RpdeKind.FacilityUseSlot,
149+
Kind = _appSettings.FeatureFlags.FacilityUseHasSlots ? RpdeKind.FacilityUseSlot : RpdeKind.IndividualFacilityUseSlot,
140150
Id = x.Id,
141151
Modified = x.Modified,
142152
State = x.Deleted ? RpdeState.Deleted : RpdeState.Updated,
@@ -147,14 +157,22 @@ protected override async Task<List<RpdeItem<Slot>>> GetRpdeItems(long? afterTime
147157
// constant as power of configuration through underlying class grows (i.e. as new properties are added)
148158
Id = RenderOpportunityId(new FacilityOpportunity
149159
{
150-
OpportunityType = OpportunityType.FacilityUseSlot,
160+
OpportunityType = _appSettings.FeatureFlags.FacilityUseHasSlots ? OpportunityType.FacilityUseSlot : OpportunityType.IndividualFacilityUseSlot,
151161
FacilityUseId = x.FacilityUseId,
152-
SlotId = x.Id
162+
SlotId = x.Id,
163+
IndividualFacilityUseId = !_appSettings.FeatureFlags.FacilityUseHasSlots ? x.IndividualFacilityUseId : null,
153164
}),
154-
FacilityUse = RenderOpportunityId(new FacilityOpportunity
165+
FacilityUse = _appSettings.FeatureFlags.FacilityUseHasSlots ?
166+
RenderOpportunityId(new FacilityOpportunity
155167
{
156168
OpportunityType = OpportunityType.FacilityUse,
157169
FacilityUseId = x.FacilityUseId
170+
})
171+
: RenderOpportunityId(new FacilityOpportunity
172+
{
173+
OpportunityType = OpportunityType.IndividualFacilityUse,
174+
IndividualFacilityUseId = x.IndividualFacilityUseId,
175+
FacilityUseId = x.FacilityUseId,
158176
}),
159177
Identifier = x.Id,
160178
StartDate = (DateTimeOffset)x.Start,
@@ -167,9 +185,10 @@ protected override async Task<List<RpdeItem<Slot>>> GetRpdeItems(long? afterTime
167185
Id = RenderOfferId(new FacilityOpportunity
168186
{
169187
OfferId = 0,
170-
OpportunityType = OpportunityType.FacilityUseSlot,
188+
OpportunityType = _appSettings.FeatureFlags.FacilityUseHasSlots ? OpportunityType.FacilityUseSlot : OpportunityType.IndividualFacilityUseSlot,
171189
FacilityUseId = x.FacilityUseId,
172-
SlotId = x.Id
190+
SlotId = x.Id,
191+
IndividualFacilityUseId = !_appSettings.FeatureFlags.FacilityUseHasSlots ? x.IndividualFacilityUseId : null,
173192
}),
174193
Price = x.Price,
175194
PriceCurrency = "GBP",

Examples/BookingSystem.AspNetCore/IdComponents/FacilityOpportunity.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class FacilityOpportunity : IBookableIdComponents
1717
public long? FacilityUseId { get; set; }
1818
public long? SlotId { get; set; }
1919
public long? OfferId { get; set; }
20+
public long? IndividualFacilityUseId { get; set; }
2021

2122
public override bool Equals(object obj)
2223
{
@@ -27,7 +28,8 @@ public override bool Equals(object obj)
2728
return OpportunityType == other.OpportunityType &&
2829
FacilityUseId == other.FacilityUseId &&
2930
SlotId == other.SlotId &&
30-
OfferId == other.OfferId;
31+
OfferId == other.OfferId &&
32+
IndividualFacilityUseId == other.IndividualFacilityUseId;
3133
}
3234

3335
public override int GetHashCode()
@@ -39,6 +41,7 @@ public override int GetHashCode()
3941
hashCode = (hashCode * 397) ^ FacilityUseId.GetHashCode();
4042
hashCode = (hashCode * 397) ^ SlotId.GetHashCode();
4143
hashCode = (hashCode * 397) ^ OfferId.GetHashCode();
44+
hashCode = (hashCode * 397) ^ IndividualFacilityUseId.GetHashCode();
4245
// ReSharper enable NonReadonlyMemberInGetHashCode
4346
return hashCode;
4447
}

Examples/BookingSystem.AspNetCore/Settings/AppSettings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class FeatureSettings
1919
public bool PaymentReconciliationDetailValidation { get; set; } = true;
2020
public bool OnlyFreeOpportunities { get; set; } = false;
2121
public bool PrepaymentAlwaysRequired { get; set; } = false;
22+
public bool FacilityUseHasSlots { get; set; } = false;
2223
}
2324

2425
public class PaymentSettings

Examples/BookingSystem.AspNetCore/Settings/EngineConfig.cs

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,51 @@ public static class EngineConfig
1212
{
1313
public static StoreBookingEngine CreateStoreBookingEngine(AppSettings appSettings, FakeBookingSystem fakeBookingSystem)
1414
{
15+
var facilityBookablePaidIdTemplate = appSettings.FeatureFlags.FacilityUseHasSlots ?
16+
new BookablePairIdTemplate<FacilityOpportunity>(
17+
// Opportunity
18+
new OpportunityIdConfiguration
19+
{
20+
OpportunityType = OpportunityType.FacilityUseSlot,
21+
AssignedFeed = OpportunityType.FacilityUseSlot,
22+
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/slots/{SlotId}",
23+
OfferIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/slots/{SlotId}#/offers/{OfferId}",
24+
Bookable = true
25+
},
26+
// Parent
27+
new OpportunityIdConfiguration
28+
{
29+
OpportunityType = OpportunityType.FacilityUse,
30+
AssignedFeed = OpportunityType.FacilityUse,
31+
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}"
32+
})
33+
:
34+
new BookablePairIdTemplate<FacilityOpportunity>(
35+
// Opportunity
36+
new OpportunityIdConfiguration
37+
{
38+
OpportunityType = OpportunityType.IndividualFacilityUseSlot,
39+
AssignedFeed = OpportunityType.IndividualFacilityUseSlot,
40+
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/individual-facility-uses/{IndividualFacilityUseId}/slots/{SlotId}",
41+
OfferIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/individual-facility-uses/{IndividualFacilityUseId}/slots/{SlotId}#/offers/{OfferId}",
42+
Bookable = true
43+
},
44+
// Parent
45+
new OpportunityIdConfiguration
46+
{
47+
OpportunityType = OpportunityType.IndividualFacilityUse,
48+
AssignedFeed = OpportunityType.FacilityUse,
49+
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/individual-facility-uses/{IndividualFacilityUseId}"
50+
},
51+
// Grandparent
52+
new OpportunityIdConfiguration
53+
{
54+
OpportunityType = OpportunityType.FacilityUse,
55+
AssignedFeed = OpportunityType.FacilityUse,
56+
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}"
57+
})
58+
;
59+
1560
return new StoreBookingEngine(
1661
new BookingEngineSettings
1762
{
@@ -38,24 +83,8 @@ public static StoreBookingEngine CreateStoreBookingEngine(AppSettings appSetting
3883
Bookable = false
3984
}),
4085

41-
new BookablePairIdTemplate<FacilityOpportunity> (
42-
// Opportunity
43-
new OpportunityIdConfiguration
44-
{
45-
OpportunityType = OpportunityType.FacilityUseSlot,
46-
AssignedFeed = OpportunityType.FacilityUseSlot,
47-
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/facility-use-slots/{SlotId}",
48-
OfferIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}/facility-use-slots/{SlotId}#/offers/{OfferId}",
49-
Bookable = true
50-
},
51-
// Parent
52-
new OpportunityIdConfiguration
53-
{
54-
OpportunityType = OpportunityType.FacilityUse,
55-
AssignedFeed = OpportunityType.FacilityUse,
56-
OpportunityIdTemplate = "{+BaseUrl}/facility-uses/{FacilityUseId}"
57-
})/*,
58-
86+
facilityBookablePaidIdTemplate,
87+
/*
5988
new BookablePairIdTemplate<ScheduledSessionOpportunity>(
6089
// Opportunity
6190
new OpportunityIdConfiguration
@@ -148,7 +177,7 @@ public static StoreBookingEngine CreateStoreBookingEngine(AppSettings appSetting
148177
OpportunityType.FacilityUse, new AcmeFacilityUseRpdeGenerator(appSettings, fakeBookingSystem)
149178
},
150179
{
151-
OpportunityType.FacilityUseSlot, new AcmeFacilityUseSlotRpdeGenerator(appSettings,fakeBookingSystem)
180+
appSettings.FeatureFlags.FacilityUseHasSlots ? OpportunityType.FacilityUseSlot : OpportunityType.IndividualFacilityUseSlot, new AcmeFacilityUseSlotRpdeGenerator(appSettings,fakeBookingSystem)
152181
}
153182
},
154183

@@ -253,7 +282,7 @@ public static StoreBookingEngine CreateStoreBookingEngine(AppSettings appSetting
253282
new SessionStore(appSettings, fakeBookingSystem), new List<OpportunityType> { OpportunityType.ScheduledSession }
254283
},
255284
{
256-
new FacilityStore(appSettings, fakeBookingSystem), new List<OpportunityType> { OpportunityType.FacilityUseSlot }
285+
new FacilityStore(appSettings, fakeBookingSystem), new List<OpportunityType> { appSettings.FeatureFlags.FacilityUseHasSlots ? OpportunityType.FacilityUseSlot : OpportunityType.IndividualFacilityUseSlot }
257286
}
258287
},
259288
OrderStore = new AcmeOrderStore(appSettings, fakeBookingSystem),

Examples/BookingSystem.AspNetCore/Startup.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void ConfigureServices(IServiceCollection services)
7474
.AddControllers()
7575
.AddMvcOptions(options => options.InputFormatters.Insert(0, new OpenBookingInputFormatter()));
7676

77-
services.AddSingleton<IBookingEngine>(sp => EngineConfig.CreateStoreBookingEngine(AppSettings, new FakeBookingSystem()));
77+
services.AddSingleton<IBookingEngine>(sp => EngineConfig.CreateStoreBookingEngine(AppSettings, new FakeBookingSystem(AppSettings.FeatureFlags.FacilityUseHasSlots)));
7878
}
7979

8080
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

0 commit comments

Comments
 (0)