diff --git a/packages/openactive-integration-tests/test/features/README.md b/packages/openactive-integration-tests/test/features/README.md
index f70c85f0ec..0f17792a14 100644
--- a/packages/openactive-integration-tests/test/features/README.md
+++ b/packages/openactive-integration-tests/test/features/README.md
@@ -47,8 +47,8 @@ The tests for these features cover all known edge cases, including both happy an
| notifications | Change of logistics notifications ([change-of-logistics-notifications](./notifications/change-of-logistics-notifications/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#change-of-logistics-notifications) | Notifications for when an opportunity's name, location, or start/end date/time are updated | [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x12 |
| notifications | Customer notice notifications ([customer-notice-notifications](./notifications/customer-notice-notifications/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#customer-notice-notifications) | Text notifications broadcast to all registered attendees of an opportunity | [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x4 |
| notifications | Opportunity attendance updates ([opportunity-attendance-updates](./notifications/opportunity-attendance-updates/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#opportunity-attendance-updates) | Allowing the broker to recieve updates for when an attendee attends an event | [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x8 |
-| payment | Free opportunities ([free-opportunities](./payment/free-opportunities/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#free-opportunities) | The most simple form of booking, for free opportunities. Does not check for leases. | [TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x10 |
-| payment | Opportunities with a non-zero price ([non-free-opportunities](./payment/non-free-opportunities/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#step-by-step-process-description) | The most simple form of booking with payment. Does not check for leases. | [TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x6, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x2 |
+| payment | Free opportunities ([free-opportunities](./payment/free-opportunities/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#free-opportunities) | The most simple form of booking, for free opportunities. Does not check for leases. | [TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x14 |
+| payment | Opportunities with a non-zero price ([non-free-opportunities](./payment/non-free-opportunities/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#step-by-step-process-description) | The most simple form of booking with payment. Does not check for leases. | [TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x9, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x3 |
| payment | Payment reconciliation detail validation ([payment-reconciliation-detail-validation](./payment/payment-reconciliation-detail-validation/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#payment-reconciliation-detail-validation) | Booking with valid, invalid, and missing Payment details | [TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x12, [TestOpportunityBookableUsingPayment](https://openactive.io/test-interface#TestOpportunityBookableUsingPayment) x15, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x5 |
| payment | prepayment optional ([prepayment-optional](./payment/prepayment-optional/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#booking-without-payment) | Support for booking with optional payment | [TestOpportunityBookableNonFreePrepaymentOptional](https://openactive.io/test-interface#TestOpportunityBookableNonFreePrepaymentOptional) x8 |
| payment | prepayment required ([prepayment-required](./payment/prepayment-required/README.md)) | Optional
[View Spec](https://www.openactive.io/open-booking-api/EditorsDraft/#booking-without-payment) | Support for booking with required payment | [TestOpportunityBookableNonFreePrepaymentRequired](https://openactive.io/test-interface#TestOpportunityBookableNonFreePrepaymentRequired) x8 |
diff --git a/packages/openactive-integration-tests/test/features/criteria-requirements.json b/packages/openactive-integration-tests/test/features/criteria-requirements.json
index db704d5d7b..dbd7fb0534 100644
--- a/packages/openactive-integration-tests/test/features/criteria-requirements.json
+++ b/packages/openactive-integration-tests/test/features/criteria-requirements.json
@@ -194,13 +194,13 @@
},
"free-opportunities": {
"primary": {
- "TestOpportunityBookableFree": 10
+ "TestOpportunityBookableFree": 14
}
},
"non-free-opportunities": {
"primary": {
- "TestOpportunityBookableNonFree": 6,
- "TestOpportunityBookable": 2
+ "TestOpportunityBookableNonFree": 9,
+ "TestOpportunityBookable": 3
}
},
"payment-reconciliation-detail-validation": {
diff --git a/packages/openactive-integration-tests/test/features/payment/free-opportunities/README.md b/packages/openactive-integration-tests/test/features/payment/free-opportunities/README.md
index 8ba9ed0c87..cd263923cd 100644
--- a/packages/openactive-integration-tests/test/features/payment/free-opportunities/README.md
+++ b/packages/openactive-integration-tests/test/features/payment/free-opportunities/README.md
@@ -12,7 +12,7 @@ See also: [.NET Tutorial](https://tutorials.openactive.io/open-booking-sdk/quick
### Test prerequisites
Opportunities that match the following criteria must exist in the booking system (for each configured `bookableOpportunityTypesInScope`) for the configured primary Seller in order to use `useRandomOpportunities: true`. Alternatively the following `testOpportunityCriteria` values must be supported by the [test interface](https://openactive.io/test-interface/) of the booking system for `useRandomOpportunities: false`.
-[TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x10
+[TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x14
### Running tests for only this feature
@@ -37,6 +37,7 @@ Update `default.json` within `packages/openactive-integration-tests/config/` as
| Identifier | Name | Description | Prerequisites per Opportunity Type |
|------------|------|-------------|---------------|
+| [opportunity-free-idempotency](./implemented/opportunity-free-idempotency-test.js) | Successful booking of free opportunity with idempotency | Testing idempotency of the B call for free opportunities | [TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x4 |
| [opportunity-free-must-not-include-prepayment](./implemented/opportunity-free-must-not-include-prepayment-test.js) | Free opportunities must have either a `openBookingPrepayment` value of Unspecified, or have no `openBookingPrepayment` specified | Assert that no opportunities that match criteria 'TestOpportunityBookableFreePrepaymentOptional' or 'TestOpportunityBookableFreePrepaymentRequired' are available in the opportunity feeds. | |
| [opportunity-free](./implemented/opportunity-free-test.js) | Successful booking without payment property | A successful end to end booking without the `payment` property included. | [TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x2 |
| [opportunity-free-unnecessary-payment-error](./implemented/opportunity-free-unnecessary-payment-error-test.js) | Fail free bookings which include erroneous payment property | C1, C2 and B with payment property: payment property is provided but not expected in the request, so an UnnecessaryPaymentDetailsError must be returned. | [TestOpportunityBookableFree](https://openactive.io/test-interface#TestOpportunityBookableFree) x2 |
diff --git a/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-idempotency-test.js b/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-idempotency-test.js
new file mode 100644
index 0000000000..169bf688ae
--- /dev/null
+++ b/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-idempotency-test.js
@@ -0,0 +1,25 @@
+const { FeatureHelper } = require('../../../../helpers/feature-helper');
+const { FlowStageRecipes, FlowStageUtils } = require('../../../../helpers/flow-stages');
+
+FeatureHelper.describeFeature(module, {
+ testCategory: 'payment',
+ testFeature: 'free-opportunities',
+ testFeatureImplemented: true,
+ testIdentifier: 'opportunity-free-idempotency',
+ testName: 'Successful booking of free opportunity with idempotency',
+ testDescription: 'Testing idempotency of the B call for free opportunities',
+ testOpportunityCriteria: 'TestOpportunityBookableFree',
+ // This must also be TestOpportunityBookableFree as the entire Order must be free.
+ controlOpportunityCriteria: 'TestOpportunityBookableFree',
+}, (configuration, orderItemCriteriaList, featureIsImplemented, logger, opportunityType, bookingFlow) => {
+ const { fetchOpportunities, bookRecipe, defaultFlowStageParams, bookRecipeGetFirstStageInput, bookRecipeGetAssertOpportunityCapacityInput } = FlowStageRecipes.initialiseSimpleC1C2BookFlow(orderItemCriteriaList, logger);
+ const idempotentRepeatB = FlowStageRecipes.idempotentRepeatBAfterBook(orderItemCriteriaList, bookRecipe, defaultFlowStageParams, {
+ getFirstStageInput: bookRecipeGetFirstStageInput,
+ getAssertOpportunityCapacityInput: bookRecipeGetAssertOpportunityCapacityInput,
+ });
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(fetchOpportunities);
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(bookRecipe);
+ describe('idempotent repeat B', () => {
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(idempotentRepeatB);
+ });
+});
diff --git a/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-without-checkpoints-test.js b/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-without-checkpoints-test.js
index 0128e79922..ffa61d153f 100644
--- a/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-without-checkpoints-test.js
+++ b/packages/openactive-integration-tests/test/features/payment/free-opportunities/implemented/opportunity-free-without-checkpoints-test.js
@@ -20,10 +20,7 @@ FeatureHelper.describeFeature(module, {
});
FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(fetchOpportunities);
FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(bookRecipe);
- // Remove this condition once https://github.com/openactive/OpenActive.Server.NET/issues/100 is fixed.
- if (bookingFlow === 'OpenBookingApprovalFlow') {
- describe('idempotent repeat B', () => {
- FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(idempotentRepeatB);
- });
- }
+ describe('idempotent repeat B', () => {
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(idempotentRepeatB);
+ });
});
diff --git a/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/README.md b/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/README.md
index d8333661d5..82623512c3 100644
--- a/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/README.md
+++ b/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/README.md
@@ -12,7 +12,7 @@ See also: [.NET Tutorial](https://tutorials.openactive.io/open-booking-sdk/quick
### Test prerequisites
Opportunities that match the following criteria must exist in the booking system (for each configured `bookableOpportunityTypesInScope`) for the configured primary Seller in order to use `useRandomOpportunities: true`. Alternatively the following `testOpportunityCriteria` values must be supported by the [test interface](https://openactive.io/test-interface/) of the booking system for `useRandomOpportunities: false`.
-[TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x6, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x2
+[TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x9, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x3
### Running tests for only this feature
@@ -37,6 +37,7 @@ Update `default.json` within `packages/openactive-integration-tests/config/` as
| Identifier | Name | Description | Prerequisites per Opportunity Type |
|------------|------|-------------|---------------|
+| [opportunity-paid-idempotency](./implemented/opportunity-paid-idempotency-test.js) | Successful booking of paid opportunity with idempotency | Testing idempotency of the B call for paid opportunities | [TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x3, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x1 |
| [opportunity-paid](./implemented/opportunity-paid-test.js) | Successful booking with payment property | A successful end to end booking of a non-free opportunity with the `payment` property included if required. | [TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x3, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x1 |
| [opportunity-paid-without-checkpoints](./implemented/opportunity-paid-without-checkpoints-test.js) | Successful booking without Checkpoints | Paid Opportunities should be bookable without using Checkpoints C1 & C2 if 1). tax calculations are not performed by the Booking System and 2). they do not require additional details | [TestOpportunityBookableNonFree](https://openactive.io/test-interface#TestOpportunityBookableNonFree) x3, [TestOpportunityBookable](https://openactive.io/test-interface#TestOpportunityBookable) x1 |
diff --git a/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/implemented/opportunity-paid-idempotency-test.js b/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/implemented/opportunity-paid-idempotency-test.js
new file mode 100644
index 0000000000..4c51bdc9d2
--- /dev/null
+++ b/packages/openactive-integration-tests/test/features/payment/non-free-opportunities/implemented/opportunity-paid-idempotency-test.js
@@ -0,0 +1,28 @@
+const { FeatureHelper } = require('../../../../helpers/feature-helper');
+const { FlowStageRecipes, FlowStageUtils } = require('../../../../helpers/flow-stages');
+
+FeatureHelper.describeFeature(module, {
+ testCategory: 'payment',
+ testFeature: 'non-free-opportunities',
+ testFeatureImplemented: true,
+ testIdentifier: 'opportunity-paid-idempotency',
+ testName: 'Successful booking of paid opportunity with idempotency',
+ testDescription: 'Testing idempotency of the B call for paid opportunities',
+ testOpportunityCriteria: 'TestOpportunityBookableNonFree',
+ controlOpportunityCriteria: 'TestOpportunityBookable',
+},
+(configuration, orderItemCriteriaList, featureIsImplemented, logger, opportunityType, bookingFlow) => {
+ // Initiate Flow Stages
+ const { fetchOpportunities, bookRecipe, defaultFlowStageParams, bookRecipeGetFirstStageInput, bookRecipeGetAssertOpportunityCapacityInput } = FlowStageRecipes.initialiseSimpleC1C2BookFlow(orderItemCriteriaList, logger);
+ const idempotentRepeatB = FlowStageRecipes.idempotentRepeatBAfterBook(orderItemCriteriaList, bookRecipe, defaultFlowStageParams, {
+ getFirstStageInput: bookRecipeGetFirstStageInput,
+ getAssertOpportunityCapacityInput: bookRecipeGetAssertOpportunityCapacityInput,
+ });
+
+ // Set up tests
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(fetchOpportunities);
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(bookRecipe);
+ describe('idempotent repeat B', () => {
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(idempotentRepeatB);
+ });
+});
diff --git a/packages/openactive-integration-tests/test/features/tax/business-to-consumer-tax-calculation-gross/implemented/business-to-consumer-tax-calculation-gross-without-checkpoints-test.js b/packages/openactive-integration-tests/test/features/tax/business-to-consumer-tax-calculation-gross/implemented/business-to-consumer-tax-calculation-gross-without-checkpoints-test.js
index 1b17f439de..6fe27a2099 100644
--- a/packages/openactive-integration-tests/test/features/tax/business-to-consumer-tax-calculation-gross/implemented/business-to-consumer-tax-calculation-gross-without-checkpoints-test.js
+++ b/packages/openactive-integration-tests/test/features/tax/business-to-consumer-tax-calculation-gross/implemented/business-to-consumer-tax-calculation-gross-without-checkpoints-test.js
@@ -21,10 +21,7 @@ FeatureHelper.describeFeature(module, {
});
FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(fetchOpportunities);
FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(bookRecipe);
- // Remove this condition once https://github.com/openactive/OpenActive.Server.NET/issues/100 is fixed.
- if (bookingFlow === 'OpenBookingApprovalFlow') {
- describe('idempotent repeat B', () => {
- FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(idempotentRepeatB);
- });
- }
+ describe('idempotent repeat B', () => {
+ FlowStageUtils.describeRunAndCheckIsSuccessfulAndValid(idempotentRepeatB);
+ });
});