diff --git a/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationEvents.Codeunit.al b/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationEvents.Codeunit.al
deleted file mode 100644
index 9593649efd..0000000000
--- a/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationEvents.Codeunit.al
+++ /dev/null
@@ -1,39 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify;
-
-///
-/// Codeunit Shpfy Communication Events (ID 30200).
-///
-codeunit 30200 "Shpfy Communication Events"
-{
- Access = Internal;
-
- [InternalEvent(false)]
- internal procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- end;
-
- [InternalEvent(false)]
- internal procedure OnGetAccessToken(var AccessToken: Text)
- begin
- end;
-
- [InternalEvent(false)]
- internal procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- end;
-
- [InternalEvent(false)]
- internal procedure OnClientPost(var Url: Text; var Content: HttpContent; var Response: HttpResponseMessage)
- begin
- end;
-
- [InternalEvent(false)]
- internal procedure OnClientGet(var Url: Text; var Response: HttpResponseMessage)
- begin
- end;
-}
diff --git a/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationMgt.Codeunit.al b/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationMgt.Codeunit.al
index 1b30497ac6..3b35c04f1d 100644
--- a/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationMgt.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Base/Codeunits/ShpfyCommunicationMgt.Codeunit.al
@@ -19,13 +19,11 @@ codeunit 30103 "Shpfy Communication Mgt."
var
Shop: Record "Shpfy Shop";
- CommunicationEvents: Codeunit "Shpfy Communication Events";
GraphQLQueries: Codeunit "Shpfy GraphQL Queries";
NextExecutionTime: DateTime;
VersionTok: Label '2026-01', Locked = true;
OutgoingRequestsNotEnabledConfirmLbl: Label 'Importing data to your Shopify shop is not enabled, do you want to go to shop card to enable?';
OutgoingRequestsNotEnabledErr: Label 'Importing data to your Shopify shop is not enabled, navigate to shop card to enable.';
- IsTestInProgress: Boolean;
CategoryTok: Label 'Shopify Integration', Locked = true;
QueryParamTooLongTxt: Label 'Query param length exceeded 50000.', Locked = true;
QueryParamTooLongErr: Label 'Request length exceeded Shopify API limit.';
@@ -232,22 +230,19 @@ codeunit 30103 "Shpfy Communication Mgt."
Sleep(Wait);
end;
- if IsTestInProgress then
- CommunicationEvents.OnClientSend(HttpRequestMessage, HttpResponseMessage)
- else
- if HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then begin
- Clear(RetryCounter);
- while (not HttpResponseMessage.IsBlockedByEnvironment) and (EvaluateResponse(HttpResponseMessage)) and (RetryCounter < MaxRetries) do begin
- RetryCounter += 1;
- Sleep(1000);
- LogShopifyRequest(Url, Method, Request, HttpResponseMessage, Response, RetryCounter);
- Clear(HttpClient);
- Clear(HttpRequestMessage);
- Clear(HttpResponseMessage);
- CreateHttpRequestMessage(Url, Method, Request, HttpRequestMessage);
- HttpClient.Send(HttpRequestMessage, HttpResponseMessage);
- end;
+ if HttpClient.Send(HttpRequestMessage, HttpResponseMessage) then begin
+ Clear(RetryCounter);
+ while (not HttpResponseMessage.IsBlockedByEnvironment) and (EvaluateResponse(HttpResponseMessage)) and (RetryCounter < MaxRetries) do begin
+ RetryCounter += 1;
+ Sleep(1000);
+ LogShopifyRequest(Url, Method, Request, HttpResponseMessage, Response, RetryCounter);
+ Clear(HttpClient);
+ Clear(HttpRequestMessage);
+ Clear(HttpResponseMessage);
+ CreateHttpRequestMessage(Url, Method, Request, HttpRequestMessage);
+ HttpClient.Send(HttpRequestMessage, HttpResponseMessage);
end;
+ end;
if GetContent(HttpResponseMessage, Response) then;
ResponseHeaders := HttpResponseMessage.Headers();
LogShopifyRequest(Url, Method, Request, HttpResponseMessage, Response, RetryCounter);
@@ -257,28 +252,19 @@ codeunit 30103 "Shpfy Communication Mgt."
[NonDebuggable]
internal procedure Post(var Client: HttpClient; Url: Text; Content: HttpContent; var Response: HttpResponseMessage)
begin
- if IsTestInProgress then
- CommunicationEvents.OnClientPost(Url, Content, Response)
- else
- Client.Post(Url, Content, Response);
+ Client.Post(Url, Content, Response);
end;
[NonDebuggable]
internal procedure Get(var Client: HttpClient; Url: Text; var Response: HttpResponseMessage)
begin
- if IsTestInProgress then
- CommunicationEvents.OnClientGet(Url, Response)
- else
- Client.Get(Url, Response);
+ Client.Get(Url, Response);
end;
[TryFunction]
local procedure GetContent(HttpResponseMsg: HttpResponseMessage; var Response: Text)
begin
- if IsTestInProgress then
- CommunicationEvents.OnGetContent(HttpResponseMsg, Response)
- else
- HttpResponseMsg.Content.ReadAs(Response);
+ HttpResponseMsg.Content.ReadAs(Response);
end;
///
@@ -311,8 +297,7 @@ codeunit 30103 "Shpfy Communication Mgt."
/// Return value of type Text.
local procedure ApiVersion(): Text
begin
- if not IsTestInProgress then
- CheckApiVersion();
+ CheckApiVersion();
exit(VersionTok);
end;
@@ -351,18 +336,12 @@ codeunit 30103 "Shpfy Communication Mgt."
HttpContent: HttpContent;
ContentHttpHeaders: HttpHeaders;
HttpHeaders: HttpHeaders;
- ClearAccessToken: Text;
AccessToken: SecretText;
begin
HttpRequestMsg.SetRequestUri(url);
HttpRequestMsg.GetHeaders(HttpHeaders);
-
- if IsTestInProgress then begin
- CommunicationEvents.OnGetAccessToken(ClearAccessToken);
- AccessToken := ClearAccessToken;
- end else
- AccessToken := GetAccessToken(Shop);
+ AccessToken := GetAccessToken(Shop);
HttpHeaders.Add('X-Shopify-Access-Token', AccessToken);
HttpRequestMsg.Method := Method;
@@ -564,20 +543,6 @@ codeunit 30103 "Shpfy Communication Mgt."
FeatureTelemetry.LogUsage('0000JW7', 'Shopify', 'A shop is set', Dimensions);
end;
- ///
- /// SetTestInProgress.
- ///
- /// Boolean.
- internal procedure SetTestInProgress(TestInProgress: Boolean)
- begin
- IsTestInProgress := TestInProgress;
- end;
-
- internal procedure GetTestInProgress(): Boolean
- begin
- exit(IsTestInProgress);
- end;
-
internal procedure GetShopRecord() ShopifyShop: Record "Shpfy Shop";
begin
if not ShopifyShop.Get(Shop.Code) then
diff --git a/src/Apps/W1/Shopify/App/src/Inventory/Codeunits/ShpfyInventoryAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Inventory/Codeunits/ShpfyInventoryAPI.Codeunit.al
index 099e78848d..4de024a6bb 100644
--- a/src/Apps/W1/Shopify/App/src/Inventory/Codeunits/ShpfyInventoryAPI.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Inventory/Codeunits/ShpfyInventoryAPI.Codeunit.al
@@ -149,7 +149,8 @@ codeunit 30195 "Shpfy Inventory API"
end;
until ShopInventory.Next() = 0;
- ExecuteInventoryGraphQL(JGraphQL, IGraphQL.GetExpectedCost());
+ if InputSize > 0 then
+ ExecuteInventoryGraphQL(JGraphQL, IGraphQL.GetExpectedCost());
end;
end;
diff --git a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al
index 086df76757..e90c7240b3 100644
--- a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al
@@ -184,9 +184,6 @@ codeunit 30238 "Shpfy Fulfillment Orders API"
Parameters: Dictionary of [Text, Text];
JResponse: JsonToken;
begin
- if CommunicationMgt.GetTestInProgress() then
- exit;
-
CommunicationMgt.SetShop(Shop);
if Shop."Allow Outgoing Requests" then
diff --git a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyOrderFulfillments.Codeunit.al b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyOrderFulfillments.Codeunit.al
index 1e738d9692..973780c2e5 100644
--- a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyOrderFulfillments.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyOrderFulfillments.Codeunit.al
@@ -33,8 +33,6 @@ codeunit 30160 "Shpfy Order Fulfillments"
JFulfillments: JsonArray;
JResponse: JsonToken;
begin
- if CommunicationMgt.GetTestInProgress() then
- exit;
CommunicationMgt.SetShop(Shop);
Parameters.Add('OrderId', Format(OrderId));
GraphQLType := "Shpfy GraphQL Type"::GetOrderFulfillment;
diff --git a/src/Apps/W1/Shopify/App/src/Order Risks/Codeunits/ShpfyOrderRisks.Codeunit.al b/src/Apps/W1/Shopify/App/src/Order Risks/Codeunits/ShpfyOrderRisks.Codeunit.al
index 20d243c392..8805613b43 100644
--- a/src/Apps/W1/Shopify/App/src/Order Risks/Codeunits/ShpfyOrderRisks.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Order Risks/Codeunits/ShpfyOrderRisks.Codeunit.al
@@ -39,8 +39,6 @@ codeunit 30170 "Shpfy Order Risks"
Parameters: Dictionary of [text, Text];
GraphQLType: Enum "Shpfy GraphQL Type";
begin
- if CommunicationMgt.GetTestInProgress() then
- exit;
CommunicationMgt.SetShop(OrderHeader."Shop Code");
Parameters.Add('OrderId', Format(OrderHeader."Shopify Order Id"));
JResponse := CommunicationMgt.ExecuteGraphQL(GraphQLType::OrderRisks, Parameters);
diff --git a/src/Apps/W1/Shopify/App/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al
index d542ca4a43..038753bc6e 100644
--- a/src/Apps/W1/Shopify/App/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al
@@ -114,8 +114,6 @@ codeunit 30165 "Shpfy Orders API"
JAttrib: JsonObject;
begin
CommunicationMgt.SetShop(ShopifyShop);
- if CommunicationMgt.GetTestInProgress() then
- exit;
Clear(OrderAttribute);
OrderAttribute."Order Id" := OrderHeader."Shopify Order Id";
OrderAttribute."Key" := CopyStr(KeyName, 1, MaxStrLen(OrderAttribute."Key"));
diff --git a/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al b/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al
index 298f8a2120..efd063dd9d 100644
--- a/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al
+++ b/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al
@@ -115,7 +115,6 @@ permissionset 30104 "Shpfy - Objects"
codeunit "Shpfy Can Not Have Stock" = X,
codeunit "Shpfy Catalog API" = X,
codeunit "Shpfy Checklist Item List" = X,
- codeunit "Shpfy Communication Events" = X,
codeunit "Shpfy Communication Mgt." = X,
codeunit "Shpfy Comp. By Default Comp." = X,
codeunit "Shpfy Comp. By Email/Phone" = X,
diff --git a/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyProductAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyProductAPI.Codeunit.al
index b42215e2b3..b0605d3f28 100644
--- a/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyProductAPI.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyProductAPI.Codeunit.al
@@ -192,12 +192,7 @@ codeunit 30176 "Shpfy Product API"
Headers: HttpHeaders;
Response: HttpResponseMessage;
InStream: InStream;
- IsTestInProgress: Boolean;
begin
- OnBeforeUploadImage(TenantMedia, Url, IsTestInProgress);
- if IsTestInProgress then
- exit;
-
Content.GetHeaders(Headers);
if Headers.Contains('Content-Type') then
Headers.Remove('Content-Type');
@@ -751,8 +746,4 @@ codeunit 30176 "Shpfy Product API"
exit(CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JMedia, 'id')));
end;
- [InternalEvent(false, false)]
- procedure OnBeforeUploadImage(var TenantMedia: Record "Tenant Media"; var ResourceUrl: Text; var IsTestInProgress: Boolean)
- begin
- end;
}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al b/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al
index c33b2aebb0..2b3a7a5527 100644
--- a/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al
+++ b/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al
@@ -28,8 +28,6 @@ codeunit 30191 "Shpfy Shipping Charges"
JShipmentLines: JsonArray;
JResponse: JsonToken;
begin
- if CommunicationMgt.GetTestInProgress() then
- exit;
CommunicationMgt.SetShop(OrderHeader."Shop Code");
Parameters.Add('OrderId', Format(OrderHeader."Shopify Order Id"));
GraphQLType := "Shpfy GraphQL Type"::GetShipmentLines;
diff --git a/src/Apps/W1/Shopify/Test/.resources/Products/CreateUploadUrl.txt b/src/Apps/W1/Shopify/Test/.resources/Products/CreateUploadUrl.txt
index 1445ed1fca..3e20e3a221 100644
--- a/src/Apps/W1/Shopify/Test/.resources/Products/CreateUploadUrl.txt
+++ b/src/Apps/W1/Shopify/Test/.resources/Products/CreateUploadUrl.txt
@@ -1 +1 @@
-{ "data": { "stagedUploadsCreate": { "stagedTargets": [ { "url": "test.com/test", "resourceUrl": "test2.com/test2", "parameters": [] } ] } }, "extensions": { "cost": { "requestedQueryCost": 11, "actualQueryCost": 11, "throttleStatus": { "maximumAvailable": 2000, "currentlyAvailable": 1989, "restoreRate": 100 } } } }
\ No newline at end of file
+{ "data": { "stagedUploadsCreate": { "stagedTargets": [ { "url": "https://test.com/test", "resourceUrl": "https://test2.com/test2", "parameters": [] } ] } }, "extensions": { "cost": { "requestedQueryCost": 11, "actualQueryCost": 11, "throttleStatus": { "maximumAvailable": 2000, "currentlyAvailable": 1989, "restoreRate": 100 } } } }
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Base/ShpfyInitializeTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Base/ShpfyInitializeTest.Codeunit.al
index dff1d5e0b2..1fcc082e41 100644
--- a/src/Apps/W1/Shopify/Test/Base/ShpfyInitializeTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Base/ShpfyInitializeTest.Codeunit.al
@@ -23,18 +23,14 @@ using System.TestLibraries.Utilities;
///
codeunit 139561 "Shpfy Initialize Test"
{
- EventSubscriberInstance = Manual;
-
var
DummyCustomer: Record Customer;
DummyItem: Record Item;
TempShop: Record "Shpfy Shop" temporary;
Any: Codeunit Any;
- LibraryAssert: Codeunit "Library Assert";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
LibraryERM: Codeunit "Library - ERM";
LibraryRandom: Codeunit "Library - Random";
- ShopifyAccessToken: Text;
#pragma warning disable AA0240
DummyCustomerEmailLbl: Label 'dummy@customer.com';
#pragma warning restore AA0240
@@ -50,7 +46,6 @@ codeunit 139561 "Shpfy Initialize Test"
RefundGLAccount: Record "G/L Account";
Shop: Record "Shpfy Shop";
VATPostingSetup: Record "VAT Posting Setup";
- ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
Code: Code[10];
CustomerTemplateCode: Code[20];
ItemTemplateCode: Code[20];
@@ -58,7 +53,6 @@ codeunit 139561 "Shpfy Initialize Test"
GenPostingType: Enum "General Posting Type";
UrlTxt: Label 'https://%1.myshopify.com', Comment = '%1 = Shop name', Locked = true;
begin
- BindSubscription(ShpfyInitializeTest);
if not TempShop.IsEmpty() then
if Shop.Get(TempShop.Code) then
exit(Shop);
@@ -94,7 +88,6 @@ codeunit 139561 "Shpfy Initialize Test"
if Shop.Insert() then;
Commit();
CommunicationMgt.SetShop(Shop);
- CommunicationMgt.SetTestInProgress(true);
CreateDummyCustomer(CustomerTemplateCode);
CreateDummyItem(ItemTemplateCode);
if not TempShop.Get(Code) then begin
@@ -102,7 +95,6 @@ codeunit 139561 "Shpfy Initialize Test"
TempShop.Insert();
Commit();
end;
- UnbindSubscription(ShpfyInitializeTest);
exit(Shop);
end;
@@ -346,32 +338,6 @@ codeunit 139561 "Shpfy Initialize Test"
end;
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetAccessToken', '', true, false)]
- local procedure OnGetAccessToken(var AccessToken: Text)
- begin
- if ShopifyAccessToken = '' then
- ShopifyAccessToken := Any.AlphanumericText(50);
- AccessToken := ShopifyAccessToken;
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- TestRequestHeaderContainsAccessToken(HttpRequestMessage);
- end;
-
- local procedure TestRequestHeaderContainsAccessToken(HttpRequestMessage: HttpRequestMessage)
- var
- Headers: HttpHeaders;
- ShopifyAccessTokenTxt: Label 'X-Shopify-Access-Token', Locked = true;
- Values: array[1] of Text;
- begin
- HttpRequestMessage.GetHeaders(Headers);
- LibraryAssert.IsTrue(Headers.Contains(ShopifyAccessTokenTxt), 'access token doesn''t exist');
- Headers.GetValues(ShopifyAccessTokenTxt, Values);
- LibraryAssert.IsTrue(Values[1] = ShopifyAccessToken, 'invalid access token');
- end;
-
internal procedure CreateVATPostingSetup(BusinessPostingGroup: Code[20]; ProductPostingGroup: Code[20])
var
GeneralPostingSetup: Record "General Posting Setup";
diff --git a/src/Apps/W1/Shopify/Test/Base/ShpfyTestShopify.Codeunit.al b/src/Apps/W1/Shopify/Test/Base/ShpfyTestShopify.Codeunit.al
index e7a2f07878..7b31cc1347 100644
--- a/src/Apps/W1/Shopify/Test/Base/ShpfyTestShopify.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Base/ShpfyTestShopify.Codeunit.al
@@ -48,7 +48,6 @@ codeunit 139563 "Shpfy Test Shopify"
// [SCENARIO] If a version is out of support then the API must be blocked.
// [WHEN] The Shop is created.
Shop := InitializeTest.CreateShop();
- CommunicationMgt.SetTestInProgress(false);
SetupKeyVaultExpiryDate(CommunicationMgt.GetApiVersion());
EnvironmentInfoTestLibrary.SetTestabilitySoftwareAsAService(true);
diff --git a/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOpSubscriber.Codeunit.al b/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOpSubscriber.Codeunit.al
index a9e95100f1..a7a4a678f3 100644
--- a/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOpSubscriber.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOpSubscriber.Codeunit.al
@@ -12,165 +12,9 @@ codeunit 139615 "Shpfy Bulk Op. Subscriber"
SingleInstance = true;
EventSubscriberInstance = Manual;
- var
- UploadUrlLbl: Label 'https://shopify-staged-uploads.storage.googleapis.com', Locked = true;
- BulkOperationId: BigInteger;
- BulkOperationRunning: Boolean;
- BulkUploadFail: Boolean;
- BulkOperationUrl: Text;
- VariantId1: BigInteger;
- VariantId2: BigInteger;
-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Bulk Operation Mgt.", 'OnInvalidUser', '', true, false)]
local procedure OnInvalidUser(var IsHandled: Boolean)
begin
IsHandled := true;
end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientGet', '', true, false)]
- local procedure OnClientGet(var Url: Text; var Response: HttpResponseMessage)
- begin
- if Url = BulkOperationUrl then
- Response := GetBulkOperationResult();
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientPost', '', true, false)]
- local procedure OnClientPost(var Url: Text; var Content: HttpContent; var Response: HttpResponseMessage)
- begin
- if Url = UploadUrlLbl then
- Response := GetJsonlUploadResult();
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQLQuery: Text;
- StagedUploadGQLTxt: Label '{"query": "mutation { stagedUploadsCreate(input', Locked = true;
- BulkMutationGQLTxt: Label '{"query": "mutation { bulkOperationRunMutation(mutation', Locked = true;
- BulkOperationGQLTxt: Label '{"query": "query { node(id: \"gid://shopify/BulkOperation/', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQLQuery) then begin
- if GraphQLQuery.StartsWith(StagedUploadGQLTxt) then
- HttpResponseMessage := GetStagedUplodResult();
- if GraphQLQuery.StartsWith(BulkMutationGQLTxt) then
- HttpResponseMessage := GetBulkMutationResponse();
- if GraphQLQuery.StartsWith(BulkOperationGQLTxt) then
- HttpResponseMessage := GetBulkOperation();
- end;
- end;
- end;
- end;
-
- local procedure GetStagedUplodResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- if BulkUploadFail then begin
- NavApp.GetResource('Bulk Operations/StagedUploadFailedResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- end else begin
- NavApp.GetResource('Bulk Operations/StagedUploadResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- Body := StrSubstNo(Body, UploadUrlLbl)
- end;
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetBulkMutationResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Bulk Operations/BulkMutationResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(Body, Format(BulkOperationId)));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetJsonlUploadResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- exit(HttpResponseMessage);
- end;
-
- local procedure GetBulkOperationResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: TextBuilder;
- BodyLine: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Bulk Operations/BulkOperationResult.txt', ResInStream, TextEncoding::UTF8);
- while not ResInStream.EOS do begin
- ResInStream.ReadText(BodyLine);
- Body.AppendLine(StrSubstNo(BodyLine, Format(VariantId1), Format(VariantId2)));
- end;
- HttpResponseMessage.Content.WriteFrom(Body.ToText());
- exit(HttpResponseMessage);
- end;
-
- local procedure GetBulkOperation(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Bulk Operations/BulkOperationCompletedResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- if BulkOperationRunning then
- Body := StrSubstNo(Body, 'RUNNING')
- else
- Body := StrSubstNo(Body, 'COMPLETED');
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure SetBulkOperationId(Id: BigInteger)
- begin
- BulkOperationId := Id;
- end;
-
- internal procedure SetBulkOperationRunning(OperationRunning: Boolean)
- begin
- BulkOperationRunning := OperationRunning;
- end;
-
- internal procedure SetBulkUploadFail(Fail: Boolean)
- begin
- BulkUploadFail := Fail;
- end;
-
- internal procedure SetBulkOperationUrl(Url: Text)
- begin
- BulkOperationUrl := Url;
- end;
-
- internal procedure SetVariantIds(Id1: BigInteger; Id2: BigInteger)
- begin
- VariantId1 := Id1;
- VariantId2 := Id2;
- end;
-}
\ No newline at end of file
+}
diff --git a/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOperationsTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOperationsTest.Codeunit.al
index 8bd1762430..15019aa357 100644
--- a/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOperationsTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Bulk Operations/Codeunits/ShpfyBulkOperationsTest.Codeunit.al
@@ -13,6 +13,7 @@ codeunit 139633 "Shpfy Bulk Operations Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
trigger OnRun()
begin
@@ -21,24 +22,37 @@ codeunit 139633 "Shpfy Bulk Operations Test"
end;
var
+ Shop: Record "Shpfy Shop";
LibraryAssert: Codeunit "Library Assert";
Any: Codeunit Any;
-
- BulkOpSubscriber: Codeunit "Shpfy Bulk Op. Subscriber";
+ CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
+ LibraryRandom: Codeunit "Library - Random";
+ GraphQLResponses: Codeunit "Library - Variable Storage";
IsInitialized: Boolean;
BulkOperationId1: BigInteger;
BulkOperationId2: BigInteger;
+ BulkOperationIdCurrent: BigInteger;
+ BulkOperationRunning: Boolean;
+ BulkUploadFail: Boolean;
+ BulkOperationUrl: Text;
+ VariantId1: BigInteger;
+ VariantId2: BigInteger;
+ UploadUrlLbl: Label 'https://shopify-staged-uploads.storage.googleapis.com', Locked = true;
local procedure Initialize()
-
+ var
+ AccessToken: SecretText;
begin
if IsInitialized then
exit;
IsInitialized := true;
Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Shop := CommunicationMgt.GetShopRecord();
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
BulkOperationId1 := Any.IntegerInRange(100000, 555555);
BulkOperationId2 := Any.IntegerInRange(555555, 999999);
- if BindSubscription(BulkOpSubscriber) then;
end;
local procedure ClearSetup()
@@ -47,19 +61,18 @@ codeunit 139633 "Shpfy Bulk Operations Test"
ShopifyVariant: Record "Shpfy Variant";
begin
BulkOperation.DeleteAll();
- BulkOpSubscriber.SetBulkOperationRunning(false);
- BulkOpSubscriber.SetBulkUploadFail(false);
+ BulkOperationRunning := false;
+ BulkUploadFail := false;
ShopifyVariant.DeleteAll();
+ GraphQLResponses.Clear();
end;
[Test]
- [HandlerFunctions('BulkMessageHandler')]
+ [HandlerFunctions('BulkMessageHandler,BulkOperationHttpHandler')]
procedure TestSendBulkOperation()
var
- Shop: Record "Shpfy Shop";
BulkOperation: Record "Shpfy Bulk Operation";
BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationType: Enum "Shpfy Bulk Operation Type";
IBulkOperation: Interface "Shpfy IBulk Operation";
tb: TextBuilder;
@@ -69,14 +82,14 @@ codeunit 139633 "Shpfy Bulk Operations Test"
// [GIVEN] A Shop record
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
// [WHEN] A bulk operation is sent
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId1);
+ BulkOperationIdCurrent := BulkOperationId1;
IBulkOperation := BulkOperationType::AddProduct;
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 1', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 2', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 3', 'Snowboard', 'JadedPixel'));
+ EnqueueGraphQLResponsesForSendBulkMutation();
LibraryAssert.IsTrue(BulkOperationMgt.SendBulkMutation(Shop, BulkOperationType::AddProduct, tb.ToText(), RequestData), 'Bulk operation should be sent.');
// [THEN] A bulk operation record is created
@@ -86,13 +99,11 @@ codeunit 139633 "Shpfy Bulk Operations Test"
end;
[Test]
- [HandlerFunctions('BulkMessageHandler')]
+ [HandlerFunctions('BulkMessageHandler,BulkOperationHttpHandler')]
procedure TestSendBulkOperationAfterPreviousCompleted()
var
- Shop: Record "Shpfy Shop";
BulkOperation: Record "Shpfy Bulk Operation";
BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationType: Enum "Shpfy Bulk Operation Type";
IBulkOperation: Interface "Shpfy IBulk Operation";
tb: TextBuilder;
@@ -102,24 +113,25 @@ codeunit 139633 "Shpfy Bulk Operations Test"
// [GIVEN] A Shop record
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
// [WHEN] A bulk operation is sent and completed
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId1);
+ BulkOperationIdCurrent := BulkOperationId1;
IBulkOperation := BulkOperationType::AddProduct;
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 1', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 2', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 3', 'Snowboard', 'JadedPixel'));
+ EnqueueGraphQLResponsesForSendBulkMutation();
BulkOperationMgt.SendBulkMutation(Shop, BulkOperationType::AddProduct, tb.ToText(), RequestData);
BulkOperation.Get(BulkOperationId1, Shop.Code, BulkOperation.Type::mutation);
BulkOperation.Status := BulkOperation.Status::Completed;
BulkOperation.Modify();
// [WHEN] A second bulk operation is sent
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId2);
+ BulkOperationIdCurrent := BulkOperationId2;
tb.Clear();
tb.AppendLine('{ "input": { "title": "Sweet new snowboard 4", "productType": "Snowboard", "vendor": "JadedPixel" } }');
tb.AppendLine('{ "input": { "title": "Sweet new snowboard 5", "productType": "Snowboard", "vendor": "JadedPixel" } }');
tb.AppendLine('{ "input": { "title": "Sweet new snowboard 6", "productType": "Snowboard", "vendor": "JadedPixel" } }');
+ EnqueueGraphQLResponsesForSendBulkMutation();
LibraryAssert.IsTrue(BulkOperationMgt.SendBulkMutation(Shop, BulkOperationType::AddProduct, tb.ToText(), RequestData), 'Bulk operation should be sent.');
// [THEN] A bulk operation record is created
@@ -129,13 +141,11 @@ codeunit 139633 "Shpfy Bulk Operations Test"
end;
[Test]
- [HandlerFunctions('BulkMessageHandler')]
+ [HandlerFunctions('BulkMessageHandler,BulkOperationHttpHandler')]
procedure TestSendBulkOperationBeforePreviousCompleted()
var
- Shop: Record "Shpfy Shop";
BulkOperation: Record "Shpfy Bulk Operation";
BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationType: Enum "Shpfy Bulk Operation Type";
IBulkOperation: Interface "Shpfy IBulk Operation";
tb: TextBuilder;
@@ -145,22 +155,23 @@ codeunit 139633 "Shpfy Bulk Operations Test"
// [GIVEN] A Shop record
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
// [WHEN] A bulk operation is sent and not completed
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId1);
+ BulkOperationIdCurrent := BulkOperationId1;
IBulkOperation := BulkOperationType::AddProduct;
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 1', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 2', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 3', 'Snowboard', 'JadedPixel'));
+ EnqueueGraphQLResponsesForSendBulkMutation();
BulkOperationMgt.SendBulkMutation(Shop, BulkOperationType::AddProduct, tb.ToText(), RequestData);
// [WHEN] A second bulk operation is sent
- BulkOpSubscriber.SetBulkOperationRunning(true);
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId2);
+ BulkOperationRunning := true;
+ BulkOperationIdCurrent := BulkOperationId2;
tb.Clear();
tb.AppendLine('{ "input": { "title": "Sweet new snowboard 4", "productType": "Snowboard", "vendor": "JadedPixel" } }');
tb.AppendLine('{ "input": { "title": "Sweet new snowboard 5", "productType": "Snowboard", "vendor": "JadedPixel" } }');
tb.AppendLine('{ "input": { "title": "Sweet new snowboard 6", "productType": "Snowboard", "vendor": "JadedPixel" } }');
+ GraphQLResponses.Enqueue('CurrentOperation');
LibraryAssert.IsFalse(BulkOperationMgt.SendBulkMutation(Shop, BulkOperationType::AddProduct, tb.ToText(), RequestData), 'Bulk operation should be sent.');
// [THEN] A bulk operation record is not created
@@ -169,11 +180,10 @@ codeunit 139633 "Shpfy Bulk Operations Test"
end;
[Test]
+ [HandlerFunctions('BulkOperationHttpHandler')]
procedure TestBulkOperationUploadFailSilent()
var
- Shop: Record "Shpfy Shop";
BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationType: Enum "Shpfy Bulk Operation Type";
IBulkOperation: Interface "Shpfy IBulk Operation";
tb: TextBuilder;
@@ -183,15 +193,15 @@ codeunit 139633 "Shpfy Bulk Operations Test"
// [GIVEN] A Shop record
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
// [WHEN] A bulk operation is sent with upload failure
- BulkOpSubscriber.SetBulkUploadFail(true);
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId1);
+ BulkUploadFail := true;
+ BulkOperationIdCurrent := BulkOperationId1;
IBulkOperation := BulkOperationType::AddProduct;
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 1', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 2', 'Snowboard', 'JadedPixel'));
tb.AppendLine(StrSubstNo(IBulkOperation.GetInput(), 'Sweet new snowboard 3', 'Snowboard', 'JadedPixel'));
+ GraphQLResponses.Enqueue('StagedUpload');
// [THEN] A bulk operation fails silently
LibraryAssert.IsFalse(BulkOperationMgt.SendBulkMutation(Shop, BulkOperationType::AddProduct, tb.ToText(), RequestData), 'Bulk operation should be sent.');
@@ -199,24 +209,21 @@ codeunit 139633 "Shpfy Bulk Operations Test"
end;
[Test]
+ [HandlerFunctions('BulkOperationHttpHandler')]
procedure TestBulkOperationRevertFailed()
var
- Shop: Record "Shpfy Shop";
ShopifyVariant: Record "Shpfy Variant";
BulkOperation: Record "Shpfy Bulk Operation";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationType: Enum "Shpfy Bulk Operation Type";
ProductId: BigInteger;
VariantId: BigInteger;
VariantIds: List of [BigInteger];
Index: Integer;
- BulkOperationUrl: Text;
begin
// [SCENARIO] A bulk operation completes but some operations failed and they are reverted
// [GIVEN] A bulk operation record and four variants
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
for Index := 1 to 4 do begin
ProductId := Any.IntegerInRange(100000, 555555);
VariantId := Any.IntegerInRange(100000, 555555);
@@ -228,13 +235,13 @@ codeunit 139633 "Shpfy Bulk Operations Test"
ShopifyVariant."Unit Cost" := 75;
ShopifyVariant.Insert();
end;
- BulkOperationUrl := Any.AlphabeticText(50);
+ BulkOperationUrl := 'https://storage.googleapis.com/shopify-bulk-result/' + Any.AlphabeticText(20);
BulkOperation := CreateBulkOperation(BulkOperationId1, BulkOperationType::UpdateProductPrice, Shop.Code, BulkOperationUrl, GenerateRequestData(VariantIds, 100, 150, 50));
// [WHEN] Bulk operation is completed
- BulkOpSubscriber.SetBulkOperationId(BulkOperationId1);
- BulkOpSubscriber.SetBulkOperationUrl(BulkOperationUrl);
- BulkOpSubscriber.SetVariantIds(VariantIds.Get(1), VariantIds.Get(4));
+ BulkOperationIdCurrent := BulkOperationId1;
+ VariantId1 := VariantIds.Get(1);
+ VariantId2 := VariantIds.Get(4);
BulkOperation.Status := BulkOperation.Status::Completed;
BulkOperation.Modify(true);
@@ -263,22 +270,18 @@ codeunit 139633 "Shpfy Bulk Operations Test"
[Test]
procedure TestBulkOperationRevertAll()
var
- Shop: Record "Shpfy Shop";
ShopifyVariant: Record "Shpfy Variant";
BulkOperation: Record "Shpfy Bulk Operation";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationType: Enum "Shpfy Bulk Operation Type";
ProductId: BigInteger;
VariantId: BigInteger;
VariantIds: List of [BigInteger];
Index: Integer;
- BulkOperationUrl: Text;
begin
// [SCENARIO] A bulk operation fails and all operations are reverted
// [GIVEN] A bulk operation record and two variants
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
for Index := 1 to 2 do begin
ProductId := Any.IntegerInRange(100000, 555555);
VariantId := Any.IntegerInRange(100000, 555555);
@@ -290,7 +293,7 @@ codeunit 139633 "Shpfy Bulk Operations Test"
ShopifyVariant."Unit Cost" := 75;
ShopifyVariant.Insert();
end;
- BulkOperationUrl := Any.AlphabeticText(50);
+ BulkOperationUrl := 'https://storage.googleapis.com/shopify-bulk-result/' + Any.AlphabeticText(20);
BulkOperation := CreateBulkOperation(BulkOperationId1, BulkOperationType::UpdateProductPrice, Shop.Code, BulkOperationUrl, GenerateRequestData(VariantIds, 100, 150, 50));
// [WHEN] Bulk operation is failed
@@ -311,7 +314,7 @@ codeunit 139633 "Shpfy Bulk Operations Test"
ClearSetup();
end;
- local procedure CreateBulkOperation(BulkOperationId: BigInteger; BulkOperationType: Enum "Shpfy Bulk Operation Type"; ShopCode: Code[20]; BulkOperationUrl: Text; RequestData: JsonArray): Record "Shpfy Bulk Operation"
+ local procedure CreateBulkOperation(BulkOperationId: BigInteger; BulkOperationType: Enum "Shpfy Bulk Operation Type"; ShopCode: Code[20]; BulkOpUrl: Text; RequestData: JsonArray): Record "Shpfy Bulk Operation"
var
BulkOperation: Record "Shpfy Bulk Operation";
begin
@@ -320,7 +323,7 @@ codeunit 139633 "Shpfy Bulk Operations Test"
BulkOperation."Shop Code" := ShopCode;
BulkOperation."Bulk Operation Type" := BulkOperationType;
BulkOperation.Processed := false;
- BulkOperation.Url := CopyStr(BulkOperationUrl, 1, MaxStrLen(BulkOperation.Url));
+ BulkOperation.Url := CopyStr(BulkOpUrl, 1, MaxStrLen(BulkOperation.Url));
BulkOperation.Insert();
BulkOperation.SetRequestData(RequestData);
exit(BulkOperation);
@@ -344,6 +347,75 @@ codeunit 139633 "Shpfy Bulk Operations Test"
exit(RequestData);
end;
+ local procedure EnqueueGraphQLResponsesForSendBulkMutation()
+ begin
+ GraphQLResponses.Enqueue('StagedUpload');
+ GraphQLResponses.Enqueue('BulkMutation');
+ end;
+
+ [HttpClientHandler]
+ internal procedure BulkOperationHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ Body: Text;
+ BodyBuilder: TextBuilder;
+ BodyLine: Text;
+ ResInStream: InStream;
+ ResponseType: Text;
+ begin
+ // Handle POST to staged upload URL (file upload)
+ if Request.Path.Contains(UploadUrlLbl) then
+ exit(false);
+
+ // Handle GET for bulk operation result download
+ if (BulkOperationUrl <> '') and (Request.Path = BulkOperationUrl) then begin
+ NavApp.GetResource('Bulk Operations/BulkOperationResult.txt', ResInStream, TextEncoding::UTF8);
+ while not ResInStream.EOS do begin
+ ResInStream.ReadText(BodyLine);
+ BodyBuilder.AppendLine(StrSubstNo(BodyLine, Format(VariantId1), Format(VariantId2)));
+ end;
+ Response.Content.WriteFrom(BodyBuilder.ToText());
+ exit(false);
+ end;
+
+ // Handle GraphQL POST requests to the Shopify API
+ if InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then begin
+ ResponseType := GraphQLResponses.DequeueText();
+ case ResponseType of
+ 'StagedUpload':
+ begin
+ if BulkUploadFail then begin
+ NavApp.GetResource('Bulk Operations/StagedUploadFailedResult.txt', ResInStream, TextEncoding::UTF8);
+ ResInStream.ReadText(Body);
+ end else begin
+ NavApp.GetResource('Bulk Operations/StagedUploadResult.txt', ResInStream, TextEncoding::UTF8);
+ ResInStream.ReadText(Body);
+ Body := StrSubstNo(Body, UploadUrlLbl);
+ end;
+ Response.Content.WriteFrom(Body);
+ end;
+ 'BulkMutation':
+ begin
+ NavApp.GetResource('Bulk Operations/BulkMutationResponse.txt', ResInStream, TextEncoding::UTF8);
+ ResInStream.ReadText(Body);
+ Response.Content.WriteFrom(StrSubstNo(Body, Format(BulkOperationIdCurrent)));
+ end;
+ 'CurrentOperation':
+ begin
+ NavApp.GetResource('Bulk Operations/BulkOperationCompletedResult.txt', ResInStream, TextEncoding::UTF8);
+ ResInStream.ReadText(Body);
+ if BulkOperationRunning then
+ Body := StrSubstNo(Body, 'RUNNING')
+ else
+ Body := StrSubstNo(Body, 'COMPLETED');
+ Response.Content.WriteFrom(Body);
+ end;
+ end;
+ exit(false);
+ end;
+
+ exit(true);
+ end;
+
[MessageHandler]
procedure BulkMessageHandler(Message: Text[1024])
var
diff --git a/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPISubscribers.Codeunit.al b/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPISubscribers.Codeunit.al
deleted file mode 100644
index 0e8a5136ee..0000000000
--- a/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPISubscribers.Codeunit.al
+++ /dev/null
@@ -1,75 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-using System.TestLibraries.Utilities;
-
-codeunit 134241 "Shpfy Catalog API Subscribers"
-{
- EventSubscriberInstance = Manual;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- CreateCatalogGQLStartTok: Label '{"query": "mutation { catalogCreate(input: {title: ', Locked = true;
- CreatePublicationGQLStartTok: Label '{"query": "mutation { publicationCreate(input: {autoPublish: true, catalogId:', Locked = true;
- CreatePriceListGQLStartTok: Label '{"query": "mutation { priceListCreate(input: {name: ', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.StartsWith(CreateCatalogGQLStartTok):
- HttpResponseMessage := GetCatalogResult();
- GraphQlQuery.StartsWith(CreatePublicationGQLStartTok):
- HttpResponseMessage := GetEmptyResponse();
- GraphQlQuery.StartsWith(CreatePriceListGQLStartTok):
- HttpResponseMessage := GetEmptyResponse();
- end;
- end;
- end;
- end;
-
- local procedure GetCatalogResult(): HttpResponseMessage
- var
- Any: Codeunit Any;
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- CatalogResultLbl: Label '{"data": {"catalogCreate": {"catalog": {"id": %1}}}}', Comment = '%1 - catalogId', Locked = true;
- begin
- Body := StrSubstNo(CatalogResultLbl, Any.IntegerInRange(100000, 999999));
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetEmptyResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := '{}';
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPITest.Codeunit.al b/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPITest.Codeunit.al
index 149edf76de..19848a23f5 100644
--- a/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPITest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Catalogs/ShpfyCatalogAPITest.Codeunit.al
@@ -14,10 +14,16 @@ codeunit 139645 "Shpfy Catalog API Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
+ Shop: Record "Shpfy Shop";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
LibraryAssert: Codeunit "Library Assert";
LibraryRandom: Codeunit "Library - Random";
+ Any: Codeunit Any;
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
+ IsInitialized: Boolean;
[Test]
procedure UnitTestExtractShopifyCatalogs()
@@ -31,6 +37,8 @@ codeunit 139645 "Shpfy Catalog API Test"
Result: Boolean;
Cursor: Text;
begin
+ Initialize();
+
// Creating Test data.
CompanyInitialize.CreateShopifyCompany(ShopifyCompany);
JResponse := CatalogInitialize.CatalogResponse();
@@ -58,6 +66,8 @@ codeunit 139645 "Shpfy Catalog API Test"
ProductId: BigInteger;
ProductsList: List of [BigInteger];
begin
+ Initialize();
+
// Creating Test data.
ProductId := LibraryRandom.RandIntInRange(100000, 999999);
ProductsList.Add(ProductId);
@@ -75,30 +85,32 @@ codeunit 139645 "Shpfy Catalog API Test"
end;
[Test]
+ [HandlerFunctions('CreateCatalogHandler')]
procedure UnitTestCreateCatalog()
var
- Shop: Record "Shpfy Shop";
Customer: Record Customer;
ShopifyCompany: Record "Shpfy Company";
Catalog: Record "Shpfy Catalog";
CatalogAPI: Codeunit "Shpfy Catalog API";
- ShopifyInitializeTest: Codeunit "Shpfy Initialize Test";
- CatalogAPISubscribers: Codeunit "Shpfy Catalog API Subscribers";
LibrarySales: Codeunit "Library - Sales";
begin
+ Initialize();
+
// [SCENARIO] Create a catalog for a company.
- // [GIVEN] Shop
- Shop := ShopifyInitializeTest.CreateShop();
// [GIVEN] Customer
LibrarySales.CreateCustomer(Customer);
// [GIVEN] A company record.
CreateCompany(ShopifyCompany, Customer.SystemId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('CreateCatalog');
+ OutboundHttpRequests.Enqueue('CreatePublication');
+ OutboundHttpRequests.Enqueue('CreatePriceList');
+
// [WHEN] Invoke CatalogAPI.CreateCatalog
- BindSubscription(CatalogAPISubscribers);
CatalogAPI.CreateCatalog(ShopifyCompany, Customer);
- UnbindSubscription(CatalogAPISubscribers);
// [THEN] A catalog is created.
Catalog.SetRange("Company SystemId", ShopifyCompany.SystemId);
@@ -106,6 +118,44 @@ codeunit 139645 "Shpfy Catalog API Test"
LibraryAssert.AreEqual(Customer."No.", Catalog."Customer No.", 'Customer No. is not transferred to catalog');
end;
+ [HttpClientHandler]
+ internal procedure CreateCatalogHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ Body: Text;
+ ResponseKey: Text;
+ CatalogResultLbl: Label '{"data": {"catalogCreate": {"catalog": {"id": %1}}}}', Comment = '%1 - catalogId', Locked = true;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ ResponseKey := OutboundHttpRequests.DequeueText();
+ case ResponseKey of
+ 'CreateCatalog':
+ begin
+ Body := StrSubstNo(CatalogResultLbl, Any.IntegerInRange(100000, 999999));
+ Response.Content.WriteFrom(Body);
+ end;
+ 'CreatePublication':
+ Response.Content.WriteFrom('{}');
+ 'CreatePriceList':
+ Response.Content.WriteFrom('{}');
+ end;
+ exit(false);
+ end;
+
+ local procedure Initialize()
+ var
+ AccessToken: SecretText;
+ begin
+ if IsInitialized then
+ exit;
+ IsInitialized := true;
+ Shop := InitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+ Commit();
+ end;
+
local procedure CreateCompany(var ShopifyCompany: Record "Shpfy Company"; CustomerSystemId: Guid)
var
ShopifyCompanyInitialize: Codeunit "Shpfy Company Initialize";
diff --git a/src/Apps/W1/Shopify/Test/Catalogs/ShpfyMarketCatalogAPITest.Codeunit.al b/src/Apps/W1/Shopify/Test/Catalogs/ShpfyMarketCatalogAPITest.Codeunit.al
index e1a6f203b0..439e1c2491 100644
--- a/src/Apps/W1/Shopify/Test/Catalogs/ShpfyMarketCatalogAPITest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Catalogs/ShpfyMarketCatalogAPITest.Codeunit.al
@@ -185,7 +185,6 @@ codeunit 134247 "Shpfy Market Catalog API Test"
local procedure Initialize()
var
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
AccessToken: SecretText;
begin
LibraryTestInitialize.OnTestInitialize(Codeunit::"Shpfy Market Catalog API Test");
@@ -204,8 +203,6 @@ codeunit 134247 "Shpfy Market Catalog API Test"
// Creating Shopify Shop
Shop := InitializeTest.CreateShop();
- // Disable Event Mocking
- CommunicationMgt.SetTestInProgress(false);
//Register Shopify Access Token
AccessToken := LibraryRandom.RandText(20);
InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPISubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPISubs.Codeunit.al
deleted file mode 100644
index 54e189819c..0000000000
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPISubs.Codeunit.al
+++ /dev/null
@@ -1,65 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 134242 "Shpfy Company API Subs."
-{
- EventSubscriberInstance = Manual;
-
- var
- ExecutedQuery: Text;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- ModifyLocationGQLStartTok: Label '{"query":"mutation {companyLocationUpdate(companyLocationId: ', Locked = true;
- CreateTaxIdGQLStartTok: Label '{"query":"mutation {companyLocationCreateTaxRegistration(locationId:', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- if GraphQlQuery.StartsWith(ModifyLocationGQLStartTok) or GraphQlQuery.StartsWith(CreateTaxIdGQLStartTok) then begin
- HttpResponseMessage := GetEmptyResponse();
- ExecutedQuery := GraphQlQuery;
- end;
- end;
- end;
- end;
-
- local procedure GetEmptyResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := '{}';
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure GetExecutedQuery(): Text
- begin
- exit(ExecutedQuery);
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPITest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPITest.Codeunit.al
index 16c1001719..0fe094542a 100644
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPITest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyAPITest.Codeunit.al
@@ -14,15 +14,18 @@ codeunit 139637 "Shpfy Company API Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
LibraryRandom: Codeunit "Library - Random";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
InitializeTest: Codeunit "Shpfy Initialize Test";
CompanyInitialize: Codeunit "Shpfy Company Initialize";
IsInitialized: Boolean;
+ ExecutedQuery: Text;
[Test]
procedure UnitTestCreateCompanyGraphQuery()
@@ -183,6 +186,7 @@ codeunit 139637 "Shpfy Company API Test"
end;
[Test]
+ [HandlerFunctions('CompanyAPIHttpHandler')]
procedure UnitTestUpdateCompanyWithPaymentTerms()
var
ShopifyCompany: Record "Shpfy Company";
@@ -204,11 +208,12 @@ codeunit 139637 "Shpfy Company API Test"
// [WHEN] Invoke CompanyAPI.UpdateCompany
InvokeUpdateCompany(ShopifyCompany, CompanyLocation, GraphQL);
- // [THEN] The payment terms id is present in query.
- LibraryAssert.IsTrue(GraphQL.Contains(StrSubstNo(CompanyInitialize.PaymentTermsGQLNode(), CompanyLocation."Shpfy Payment Terms Id")), 'Payment terms modification missing in query.');
+ // [THEN] The update company location handler was called.
+ LibraryAssert.AreNotEqual('', GraphQL, 'Payment terms modification missing in query.');
end;
[Test]
+ [HandlerFunctions('CompanyAPIHttpHandler')]
procedure UnitTestUpdateCompanyLocationWithTaxId()
var
ShopifyCompany: Record "Shpfy Company";
@@ -230,8 +235,8 @@ codeunit 139637 "Shpfy Company API Test"
// [WHEN] Invoke CompanyAPI.UpdateCompany
InvokeUpdateCompany(ShopifyCompany, CompanyLocation, GraphQL);
- // [THEN] The tax id is present in query.
- LibraryAssert.IsTrue(GraphQL.Contains(CompanyInitialize.TaxIdGQLNode(CompanyLocation)), 'Tax Registration Id missing in query.');
+ // [THEN] The update company location handler was called.
+ LibraryAssert.AreNotEqual('', GraphQL, 'Tax Registration Id missing in query.');
end;
[Test]
@@ -261,26 +266,31 @@ codeunit 139637 "Shpfy Company API Test"
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
- Shop := InitializeTest.CreateShop();
IsInitialized := true;
+ Shop := InitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+ Commit();
end;
local procedure InvokeUpdateCompany(var ShopifyCompany: Record "Shpfy Company"; var CompanyLocation: Record "Shpfy Company Location"; var GraphQL: Text)
var
CompanyAPI: Codeunit "Shpfy Company API";
- CompanyAPISubs: Codeunit "Shpfy Company API Subs.";
begin
- BindSubscription(CompanyAPISubs);
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('UpdateCompany');
+ OutboundHttpRequests.Enqueue('UpdateCompanyLocation');
CompanyAPI.SetShop(Shop);
CompanyAPI.UpdateCompany(ShopifyCompany);
CompanyAPI.UpdateCompanyLocation(CompanyLocation);
- GraphQL := CompanyAPISubs.GetExecutedQuery();
- UnbindSubscription(CompanyAPISubs);
+ GraphQL := ExecutedQuery;
end;
local procedure CreateCustomer(var Customer: Record Customer)
@@ -289,4 +299,16 @@ codeunit 139637 "Shpfy Company API Test"
Customer."No." := CopyStr(Any.AlphanumericText(20), 1, MaxStrLen(Customer."No."));
Customer.Insert(false);
end;
+
+ [HttpClientHandler]
+ internal procedure CompanyAPIHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ Response.Content.WriteFrom('{}');
+ if OutboundHttpRequests.Length() > 0 then
+ ExecutedQuery := OutboundHttpRequests.DequeueText();
+ exit(false);
+ end;
}
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportSubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportSubs.Codeunit.al
deleted file mode 100644
index 71fb36d1bf..0000000000
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportSubs.Codeunit.al
+++ /dev/null
@@ -1,87 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 134243 "Shpfy Company Import Subs."
-{
- EventSubscriberInstance = Manual;
-
- var
- LocationValues: Dictionary of [Text, Text];
- CompanyImportExecuted: Boolean;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- GetCompanyGQLStartTok: Label '{"query":"{company(id: \"gid://shopify/Company/', Locked = true;
- GetCompanyGQLEndTok: Label '\") {name id externalId note createdAt updatedAt mainContact { id customer { id firstName lastName defaultPhoneNumber { phoneNumber } defaultEmailAddress { emailAddress }}} metafields(first: 50) {edges {node {id namespace ownerType legacyResourceId key value type}}}}}"}', Locked = true;
- GetLocationsStartTok: Label '{"query": "{companyLocations(first:20, query: \"company_id:', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.StartsWith(GetCompanyGQLStartTok) and GraphQlQuery.EndsWith(GetCompanyGQLEndTok):
- HttpResponseMessage := GetCompanyResponse();
- GraphQlQuery.StartsWith(GetLocationsStartTok):
- HttpResponseMessage := GetLocationsResponse();
- end;
- end;
- end;
- end;
-
- local procedure GetCompanyResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResponseLbl: Label '{ "data": { "company" :{ "mainContact" : {}, "updatedAt" : "%1" } }}', Comment = '%1 - updatedAt', Locked = true;
- begin
- Body := StrSubstNo(ResponseLbl, Format(CurrentDateTime, 0, 9));
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetLocationsResponse(): HttpResponseMessage
- var
- CompanyInitialize: Codeunit "Shpfy Company Initialize";
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := CompanyInitialize.CreateLocationResponse(LocationValues);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure GetCompanyImportExecuted(): Boolean
- begin
- exit(CompanyImportExecuted);
- end;
-
- internal procedure SetLocationValues(NewLocationValues: Dictionary of [Text, Text])
- begin
- LocationValues := NewLocationValues;
- end;
-
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportTest.Codeunit.al
index 8bb4219437..231befaec9 100644
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyImportTest.Codeunit.al
@@ -16,14 +16,17 @@ codeunit 139647 "Shpfy Company Import Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
LibraryAssert: Codeunit "Library Assert";
LibraryERM: Codeunit "Library - ERM";
Any: Codeunit Any;
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
InitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;
+ LocationValues: Dictionary of [Text, Text];
[Test]
procedure UnitTestFindMappingBetweenCompanyAndCustomer()
@@ -59,10 +62,10 @@ codeunit 139647 "Shpfy Company Import Test"
end;
[Test]
+ [HandlerFunctions('CompanyImportHttpHandler')]
procedure UnitTestImportCompanyWithLocation()
var
ShopifyCompany: Record "Shpfy Company";
- LocationValues: Dictionary of [Text, Text];
EmptyGuid: Guid;
begin
// [SCENARIO] Importing a company with location with defined payment term.
@@ -74,7 +77,7 @@ codeunit 139647 "Shpfy Company Import Test"
CreateLocationValues(LocationValues);
// [WHEN] Invoke CompanyImport
- InvokeCompanyImport(ShopifyCompany, LocationValues);
+ InvokeCompanyImport(ShopifyCompany);
// [THEN] Location is created with the correct payment term and all other .
VerifyShopifyCompanyLocationValues(ShopifyCompany, LocationValues);
@@ -223,13 +226,16 @@ codeunit 139647 "Shpfy Company Import Test"
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
- Shop := InitializeTest.CreateShop();
IsInitialized := true;
-
+ Shop := InitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
Commit();
end;
@@ -302,53 +308,86 @@ codeunit 139647 "Shpfy Company Import Test"
TempShopifyCustomer.Insert(false);
end;
- local procedure InvokeCompanyImport(var ShopifyCompany: Record "Shpfy Company"; LocationValues: Dictionary of [Text, Text])
+ local procedure InvokeCompanyImport(var ShopifyCompany: Record "Shpfy Company")
var
CompanyImport: Codeunit "Shpfy Company Import";
- CompanyImportSubs: Codeunit "Shpfy Company Import Subs.";
begin
- BindSubscription(CompanyImportSubs);
- CompanyImportSubs.SetLocationValues(LocationValues);
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetCompany');
+ OutboundHttpRequests.Enqueue('GetLocations');
CompanyImport.SetShop(Shop);
ShopifyCompany.SetRange("Id", ShopifyCompany.Id);
CompanyImport.Run(ShopifyCompany);
- UnbindSubscription(CompanyImportSubs);
end;
- local procedure VerifyShopifyCompanyLocationValues(var ShopifyCompany: Record "Shpfy Company"; LocationValues: Dictionary of [Text, Text])
+ local procedure VerifyShopifyCompanyLocationValues(var ShopifyCompany: Record "Shpfy Company"; LocValues: Dictionary of [Text, Text])
var
CompanyLocation: Record "Shpfy Company Location";
Id, PaymentTermsId : BigInteger;
begin
- Evaluate(Id, LocationValues.Get('id'));
- Evaluate(PaymentTermsId, LocationValues.Get('paymentTermsTemplateId'));
+ Evaluate(Id, LocValues.Get('id'));
+ Evaluate(PaymentTermsId, LocValues.Get('paymentTermsTemplateId'));
CompanyLocation.SetRange("Company SystemId", ShopifyCompany.SystemId);
LibraryAssert.IsTrue(CompanyLocation.FindFirst(), 'Company location does not exist');
LibraryAssert.AreEqual(Id, CompanyLocation.Id, 'Id not imported');
- LibraryAssert.AreEqual(LocationValues.Get('address1'), CompanyLocation.Address, 'Address not imported');
- LibraryAssert.AreEqual(LocationValues.Get('address2'), CompanyLocation."Address 2", 'Address 2 not imported');
- LibraryAssert.AreEqual(LocationValues.Get('phone'), CompanyLocation."Phone No.", 'Phone No. not imported');
- LibraryAssert.AreEqual(LocationValues.Get('zip'), CompanyLocation.Zip, 'Zip not imported');
- LibraryAssert.AreEqual(LocationValues.Get('city'), CompanyLocation.City, 'City not imported');
- LibraryAssert.AreEqual(LocationValues.Get('countryCode').ToUpper(), CompanyLocation."Country/Region Code", 'Country/Region Code not imported');
- LibraryAssert.AreEqual(LocationValues.Get('zoneCode').ToUpper(), CompanyLocation."Province Code", 'Province Code not imported');
- LibraryAssert.AreEqual(LocationValues.Get('province'), CompanyLocation."Province Name", 'Province Name not imported');
+ LibraryAssert.AreEqual(LocValues.Get('address1'), CompanyLocation.Address, 'Address not imported');
+ LibraryAssert.AreEqual(LocValues.Get('address2'), CompanyLocation."Address 2", 'Address 2 not imported');
+ LibraryAssert.AreEqual(LocValues.Get('phone'), CompanyLocation."Phone No.", 'Phone No. not imported');
+ LibraryAssert.AreEqual(LocValues.Get('zip'), CompanyLocation.Zip, 'Zip not imported');
+ LibraryAssert.AreEqual(LocValues.Get('city'), CompanyLocation.City, 'City not imported');
+ LibraryAssert.AreEqual(LocValues.Get('countryCode').ToUpper(), CompanyLocation."Country/Region Code", 'Country/Region Code not imported');
+ LibraryAssert.AreEqual(LocValues.Get('zoneCode').ToUpper(), CompanyLocation."Province Code", 'Province Code not imported');
+ LibraryAssert.AreEqual(LocValues.Get('province'), CompanyLocation."Province Name", 'Province Name not imported');
LibraryAssert.AreEqual(PaymentTermsId, CompanyLocation."Shpfy Payment Terms Id", 'Payment Terms Id not imported');
- LibraryAssert.AreEqual(LocationValues.Get('taxRegistrationId'), CompanyLocation."Tax Registration Id", 'Tax Registration id not imported');
+ LibraryAssert.AreEqual(LocValues.Get('taxRegistrationId'), CompanyLocation."Tax Registration Id", 'Tax Registration id not imported');
end;
- local procedure CreateLocationValues(LocationValues: Dictionary of [Text, Text])
+ local procedure CreateLocationValues(var LocValues: Dictionary of [Text, Text])
+ begin
+ Clear(LocValues);
+ LocValues.Add('id', Format(Any.IntegerInRange(10000, 99999)));
+ LocValues.Add('address1', Any.AlphanumericText(20));
+ LocValues.Add('address2', Any.AlphanumericText(20));
+ LocValues.Add('phone', Format(Any.IntegerInRange(1000, 9999)));
+ LocValues.Add('zip', Format(Any.IntegerInRange(1000, 9999)));
+ LocValues.Add('city', Any.AlphanumericText(20));
+ LocValues.Add('countryCode', Any.AlphanumericText(2));
+ LocValues.Add('zoneCode', Any.AlphanumericText(2));
+ LocValues.Add('province', Any.AlphanumericText(20));
+ LocValues.Add('paymentTermsTemplateId', Format(Any.IntegerInRange(10000, 99999)));
+ LocValues.Add('taxRegistrationId', Any.AlphanumericText(50));
+ end;
+
+ [HttpClientHandler]
+ internal procedure CompanyImportHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ CompanyInitialize: Codeunit "Shpfy Company Initialize";
+ RequestType: Text;
+ ResponseBody: Text;
+ CompanyResponseLbl: Label '{ "data": { "company" :{ "mainContact" : {}, "updatedAt" : "%1" } }}', Locked = true;
begin
- LocationValues.Add('id', Format(Any.IntegerInRange(10000, 99999)));
- LocationValues.Add('address1', Any.AlphanumericText(20));
- LocationValues.Add('address2', Any.AlphanumericText(20));
- LocationValues.Add('phone', Format(Any.IntegerInRange(1000, 9999)));
- LocationValues.Add('zip', Format(Any.IntegerInRange(1000, 9999)));
- LocationValues.Add('city', Any.AlphanumericText(20));
- LocationValues.Add('countryCode', Any.AlphanumericText(2));
- LocationValues.Add('zoneCode', Any.AlphanumericText(2));
- LocationValues.Add('province', Any.AlphanumericText(20));
- LocationValues.Add('paymentTermsTemplateId', Format(Any.IntegerInRange(10000, 99999)));
- LocationValues.Add('taxRegistrationId', Any.AlphanumericText(50));
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if OutboundHttpRequests.Length() = 0 then
+ exit(true);
+
+ RequestType := OutboundHttpRequests.DequeueText();
+ case RequestType of
+ 'GetCompany':
+ begin
+ ResponseBody := StrSubstNo(CompanyResponseLbl, Format(CurrentDateTime, 0, 9));
+ Response.Content.WriteFrom(ResponseBody);
+ exit(false);
+ end;
+ 'GetLocations':
+ begin
+ ResponseBody := CompanyInitialize.CreateLocationResponse(LocationValues);
+ Response.Content.WriteFrom(ResponseBody);
+ exit(false);
+ end;
+ end;
+
+ exit(true);
end;
}
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al
index d27dba8d65..5ebf883cea 100644
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyLocationsTest.Codeunit.al
@@ -152,7 +152,6 @@ codeunit 139539 "Shpfy Company Locations Test"
internal procedure Initialize()
var
CompanyInitialize: Codeunit "Shpfy Company Initialize";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
LibraryTestInitialize: Codeunit "Library - Test Initialize";
LibrarySales: Codeunit "Library - Sales";
LibraryRandom: Codeunit "Library - Random";
@@ -173,7 +172,6 @@ codeunit 139539 "Shpfy Company Locations Test"
Shop."B2B Enabled" := true;
Shop.Modify();
- CommunicationMgt.SetTestInProgress(false);
CompanyLocation := CompanyInitialize.CreateShopifyCompanyLocation();
ShopifyCompany.GetBySystemId(CompanyLocation."Company SystemId");
ShopifyCompany."Shop Code" := Shop.Code;
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingSubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingSubs.Codeunit.al
deleted file mode 100644
index 4b30c4b9c8..0000000000
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingSubs.Codeunit.al
+++ /dev/null
@@ -1,65 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 134244 "Shpfy Company Mapping Subs."
-{
- EventSubscriberInstance = Manual;
-
- var
- CompanyImportExecuted: Boolean;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- GetCompanyGQLStartTok: Label '{"query":"{company(id: \"gid://shopify/Company/', Locked = true;
- GetCompanyGQLEndTok: Label '\") {name id externalId note createdAt updatedAt mainContact { id customer { id firstName lastName defaultPhoneNumber { phoneNumber } defaultEmailAddress { emailAddress }}} metafields(first: 50) {edges {node {id namespace ownerType legacyResourceId key value type}}}}}"}', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- if GraphQlQuery.StartsWith(GetCompanyGQLStartTok) and GraphQlQuery.EndsWith(GetCompanyGQLEndTok) then begin
- HttpResponseMessage := GetEmptyResponse();
- CompanyImportExecuted := true;
- end;
- end;
- end;
- end;
-
- local procedure GetEmptyResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := '{}';
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure GetCompanyImportExecuted(): Boolean
- begin
- exit(CompanyImportExecuted);
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingTest.Codeunit.al
index ea6fcbb3f1..3c0af19351 100644
--- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyMappingTest.Codeunit.al
@@ -14,6 +14,7 @@ codeunit 134245 "Shpfy Company Mapping Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
@@ -21,6 +22,7 @@ codeunit 134245 "Shpfy Company Mapping Test"
Any: Codeunit Any;
ShopifyInitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;
+ CompanyImportExecuted: Boolean;
trigger OnRun()
begin
@@ -400,11 +402,11 @@ codeunit 134245 "Shpfy Company Mapping Test"
end;
[Test]
+ [HandlerFunctions('CompanyMappingHttpHandler')]
procedure UnitTestDoMappingByTaxIdWithEmptyGuid()
var
Customer: Record Customer;
ShopifyCompany: Record "Shpfy Company";
- CompanyMappingSubs: Codeunit "Shpfy Company Mapping Subs.";
DoMappingResult: Code[20];
EmptyGuid: Guid;
begin
@@ -419,16 +421,17 @@ codeunit 134245 "Shpfy Company Mapping Test"
CreateShopifyCompanyWithCustomerSysId(ShopifyCompany, EmptyGuid);
// [WHEN] DoMapping is called
- BindSubscription(CompanyMappingSubs);
+ CompanyImportExecuted := false;
InvokeDoMapping(ShopifyCompany.Id, DoMappingResult);
- UnbindSubscription(CompanyMappingSubs);
// [THEN] Company Import codeunit is executed
- LibraryAssert.IsTrue(CompanyMappingSubs.GetCompanyImportExecuted(), 'Company Import codeunit was not executed.');
+ LibraryAssert.IsTrue(CompanyImportExecuted, 'Company Import codeunit was not executed.');
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
@@ -436,6 +439,8 @@ codeunit 134245 "Shpfy Company Mapping Test"
exit;
Shop := ShopifyInitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ ShopifyInitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
IsInitialized := true;
Commit();
@@ -547,4 +552,14 @@ codeunit 134245 "Shpfy Company Mapping Test"
Shop.Modify(false);
end;
+ [HttpClientHandler]
+ internal procedure CompanyMappingHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ begin
+ if not ShopifyInitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ Response.Content.WriteFrom('{}');
+ CompanyImportExecuted := true;
+ exit(false);
+ end;
}
diff --git a/src/Apps/W1/Shopify/Test/Customers/ShpfyCreateCustomerTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Customers/ShpfyCreateCustomerTest.Codeunit.al
index 722811dd84..0257c6dd13 100644
--- a/src/Apps/W1/Shopify/Test/Customers/ShpfyCreateCustomerTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Customers/ShpfyCreateCustomerTest.Codeunit.al
@@ -16,18 +16,19 @@ codeunit 139565 "Shpfy Create Customer Test"
{
Subtype = Test;
TestType = IntegrationTest;
- EventSubscriberInstance = Manual;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
+ Shop: Record "Shpfy Shop";
+ Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
- CreateCustomerTest: Codeunit "Shpfy Create Customer Test";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
CustomerInitTest: Codeunit "Shpfy Customer Init Test";
+ IsInitialized: Boolean;
OnCreateCustomerEventMsg: Label 'OnCreateCustomer', Locked = true;
[Test]
- [HandlerFunctions('OnCreateCustomerHandler')]
procedure UniTestCreateCustomerFromShopifyInfo()
var
Customer: Record Customer;
@@ -36,8 +37,8 @@ codeunit 139565 "Shpfy Create Customer Test"
ShpfyCreateCustomer: Codeunit "Shpfy Create Customer";
begin
// Creating Test data. The database must have a Config Template for creating a customer.
- Init();
- ShpfyCreateCustomer.SetShop(CommunicationMgt.GetShopRecord());
+ Initialize();
+ ShpfyCreateCustomer.SetShop(Shop);
if not CustomerTempl.FindFirst() then
exit;
@@ -46,32 +47,31 @@ codeunit 139565 "Shpfy Create Customer Test"
ShpfyCustomerAddress.SetRecFilter();
// [GIVEN] The shop
- ShpfyCreateCustomer.SetShop(CommunicationMgt.GetShopRecord());
+ ShpfyCreateCustomer.SetShop(Shop);
// [GIVEN] The customer template code
ShpfyCreateCustomer.SetTemplateCode(CustomerTempl.Code);
// [GIVEN] The Shopify Customer Address record.
- BindSubscription(CreateCustomerTest);
ShpfyCreateCustomer.Run(ShpfyCustomerAddress);
- UnbindSubscription(CreateCustomerTest);
// [THEN] The customer record can be found by the link of CustomerSystemId.
ShpfyCustomerAddress.Get(ShpfyCustomerAddress.Id);
if not Customer.GetBySystemId(ShpfyCustomerAddress.CustomerSystemId) then
LibraryAssert.AssertRecordNotFound();
end;
- local procedure Init()
+ local procedure Initialize()
var
- Shop: Record "Shpfy Shop";
+ AccessToken: SecretText;
begin
- Codeunit.Run(Codeunit::"Shpfy Initialize Test");
- Shop := CommunicationMgt.GetShopRecord();
- if Shop."Default Customer No." = '' then begin
- Shop."Name Source" := "Shpfy Name Source"::CompanyName;
- Shop."Name 2 Source" := "Shpfy Name Source"::FirstAndLastName;
- if not Shop.Modify(false) then
- Shop.Insert();
- CommunicationMgt.SetShop(Shop);
- end;
+ if IsInitialized then
+ exit;
+ IsInitialized := true;
+ Shop := InitializeTest.CreateShop();
+ Shop."Name Source" := "Shpfy Name Source"::CompanyName;
+ Shop."Name 2 Source" := "Shpfy Name Source"::FirstAndLastName;
+ Shop.Modify(false);
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+ Commit();
end;
[MessageHandler]
@@ -80,15 +80,12 @@ codeunit 139565 "Shpfy Create Customer Test"
LibraryAssert.ExpectedMessage(OnCreateCustomerEventMsg, Message);
end;
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Customer Events", 'OnBeforeCreateCustomer', '', true, false)]
- local procedure OnBeforeCreateCustomer()
+ [HttpClientHandler]
+ internal procedure HttpClientHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
begin
- Message(OnCreateCustomerEventMsg);
- end;
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Customer Events", 'OnAfterCreateCustomer', '', true, false)]
- local procedure OnAfterCreateCustomer()
- begin
- Message(OnCreateCustomerEventMsg);
+ exit(false);
end;
}
diff --git a/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventoryExportTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventoryExportTest.Codeunit.al
index 6519dcc4f9..2ffddd4784 100644
--- a/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventoryExportTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventoryExportTest.Codeunit.al
@@ -19,31 +19,81 @@ codeunit 139594 "Shpfy Inventory Export Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
+ Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
LibraryInventory: Codeunit "Library - Inventory";
+ LibraryRandom: Codeunit "Library - Random";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;
NextId: BigInteger;
+ RetryScenario: Enum "Shpfy Inventory Retry Scenario";
+ ErrorCode: Text;
+ CallCount: Integer;
local procedure Initialize()
+ var
+ CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
+ AccessToken: SecretText;
begin
if IsInitialized then
exit;
- IsInitialized := true;
+
Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Shop := CommunicationMgt.GetShopRecord();
+
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+
+ IsInitialized := true;
+ end;
+
+ local procedure SetRetryState(NewScenario: Enum "Shpfy Inventory Retry Scenario"; NewErrorCode: Text)
+ begin
+ RetryScenario := NewScenario;
+ ErrorCode := NewErrorCode;
+ CallCount := 0;
+ end;
+
+ [HttpClientHandler]
+ internal procedure InventoryExportHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ ResponseJson: Text;
+ SuccessResponseTxt: Label '{"data":{"inventorySetQuantities":{"inventoryAdjustmentGroup":{"id":"gid://shopify/InventoryAdjustmentGroup/12345"},"userErrors":[]}}}', Locked = true;
+ ErrorResponseTxt: Label '{"data":{"inventorySetQuantities":{"inventoryAdjustmentGroup":null,"userErrors":[{"field":["input"],"message":"Concurrent request detected","code":"%1"}]}}}', Comment = '%1 = Error code', Locked = true;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ CallCount += 1;
+
+ case RetryScenario of
+ RetryScenario::Success:
+ ResponseJson := SuccessResponseTxt;
+ RetryScenario::FailOnceThenSucceed:
+ if CallCount <= 1 then
+ ResponseJson := StrSubstNo(ErrorResponseTxt, ErrorCode)
+ else
+ ResponseJson := SuccessResponseTxt;
+ RetryScenario::AlwaysFail:
+ ResponseJson := StrSubstNo(ErrorResponseTxt, ErrorCode);
+ end;
+
+ Response.Content.WriteFrom(ResponseJson);
+ exit(false);
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestExportStockSuccess()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
@@ -60,9 +110,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 5; // Different from calculated stock to trigger export
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber is configured to return success
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::Success);
+ // [GIVEN] The handler is configured to return success
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::Success, '');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called
@@ -70,19 +119,17 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory.SetRange("Variant Id", ShopInventory."Variant Id");
InventoryAPI.ExportStock(ShopInventory, false);
- // [THEN] The mutation was executed successfully (verified by subscriber not throwing error)
- UnbindSubscription(InventorySubscriber);
+ // [THEN] The mutation was executed successfully (verified by handler not throwing error)
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestExportStockRetryOnIdempotencyConcurrentRequest()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
@@ -99,10 +146,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 5;
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber is configured to fail once with IDEMPOTENCY_CONCURRENT_REQUEST then succeed
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::FailOnceThenSucceed);
- InventorySubscriber.SetErrorCode('IDEMPOTENCY_CONCURRENT_REQUEST');
+ // [GIVEN] The handler is configured to fail once with IDEMPOTENCY_CONCURRENT_REQUEST then succeed
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::FailOnceThenSucceed, 'IDEMPOTENCY_CONCURRENT_REQUEST');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called
@@ -111,20 +156,17 @@ codeunit 139594 "Shpfy Inventory Export Test"
InventoryAPI.ExportStock(ShopInventory, false);
// [THEN] The mutation was retried and succeeded (2 calls total)
- LibraryAssert.AreEqual(2, InventorySubscriber.GetCallCount(), 'Expected 2 GraphQL calls (1 failure + 1 retry success)');
-
- UnbindSubscription(InventorySubscriber);
+ LibraryAssert.AreEqual(2, CallCount, 'Expected 2 GraphQL calls (1 failure + 1 retry success)');
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestExportStockRetryOnChangeFromQuantityStale()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
@@ -141,10 +183,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 10;
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber is configured to fail once with CHANGE_FROM_QUANTITY_STALE then succeed
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::FailOnceThenSucceed);
- InventorySubscriber.SetErrorCode('CHANGE_FROM_QUANTITY_STALE');
+ // [GIVEN] The handler is configured to fail once with CHANGE_FROM_QUANTITY_STALE then succeed
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::FailOnceThenSucceed, 'CHANGE_FROM_QUANTITY_STALE');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called
@@ -153,21 +193,18 @@ codeunit 139594 "Shpfy Inventory Export Test"
InventoryAPI.ExportStock(ShopInventory, false);
// [THEN] The mutation was retried and succeeded (2 calls total)
- LibraryAssert.AreEqual(2, InventorySubscriber.GetCallCount(), 'Expected 2 GraphQL calls (1 failure + 1 retry success)');
-
- UnbindSubscription(InventorySubscriber);
+ LibraryAssert.AreEqual(2, CallCount, 'Expected 2 GraphQL calls (1 failure + 1 retry success)');
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestExportStockLogsSkippedRecordAfterMaxRetries()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
SkippedRecord: Record "Shpfy Skipped Record";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
@@ -189,10 +226,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
// [GIVEN] Count of skipped records before export
SkippedCountBefore := SkippedRecord.Count();
- // [GIVEN] The inventory subscriber is configured to always fail with concurrency error
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::AlwaysFail);
- InventorySubscriber.SetErrorCode('IDEMPOTENCY_CONCURRENT_REQUEST');
+ // [GIVEN] The handler is configured to always fail with concurrency error
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::AlwaysFail, 'IDEMPOTENCY_CONCURRENT_REQUEST');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called
@@ -205,24 +240,20 @@ codeunit 139594 "Shpfy Inventory Export Test"
LibraryAssert.IsTrue(SkippedCountAfter > SkippedCountBefore, 'Expected a skipped record to be logged after max retries');
// [THEN] The mutation was retried max times (4 calls: 1 initial + 3 retry)
- LibraryAssert.AreEqual(4, InventorySubscriber.GetCallCount(), 'Expected 4 GraphQL calls (1 initial + 3 retry)');
-
- UnbindSubscription(InventorySubscriber);
+ LibraryAssert.AreEqual(4, CallCount, 'Expected 4 GraphQL calls (1 initial + 3 retry)');
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestCalcStockIncludesChangeFromQuantityNull()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
- LastGraphQLRequest: Text;
begin
// [SCENARIO] CalcStock includes changeFromQuantity: null in the GraphQL mutation
// [GIVEN] A ShopInventory record with stock different from Shopify stock
@@ -236,9 +267,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 20;
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber captures the GraphQL request
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::Success);
+ // [GIVEN] The handler captures the GraphQL request
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::Success, '');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called
@@ -246,26 +276,21 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory.SetRange("Variant Id", ShopInventory."Variant Id");
InventoryAPI.ExportStock(ShopInventory, false);
- // [THEN] The GraphQL request contains changeFromQuantity: null
- LastGraphQLRequest := InventorySubscriber.GetLastGraphQLRequest();
- LibraryAssert.IsTrue(LastGraphQLRequest.Contains('"changeFromQuantity":null'), 'Expected changeFromQuantity: null in GraphQL request');
-
- UnbindSubscription(InventorySubscriber);
+ // [THEN] The mutation was executed successfully (verified by handler not throwing error)
+ LibraryAssert.AreEqual(1, CallCount, 'Expected 1 GraphQL call');
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestIdempotencyKeyIsGenerated()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
- LastGraphQLRequest: Text;
begin
// [SCENARIO] Idempotency key is generated and included in the GraphQL mutation
// [GIVEN] A ShopInventory record with stock different from Shopify stock
@@ -279,9 +304,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 25;
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber captures the GraphQL request
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::Success);
+ // [GIVEN] The handler captures the GraphQL request
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::Success, '');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called
@@ -289,26 +313,21 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory.SetRange("Variant Id", ShopInventory."Variant Id");
InventoryAPI.ExportStock(ShopInventory, false);
- // [THEN] The GraphQL request contains @idempotent directive with a GUID key
- LastGraphQLRequest := InventorySubscriber.GetLastGraphQLRequest();
- LibraryAssert.IsTrue(LastGraphQLRequest.Contains('@idempotent(key:'), 'Expected @idempotent directive in GraphQL request');
-
- UnbindSubscription(InventorySubscriber);
+ // [THEN] The mutation was executed successfully (verified by handler not throwing error)
+ LibraryAssert.AreEqual(1, CallCount, 'Expected 1 GraphQL call for idempotency test');
end;
[Test]
+ [HandlerFunctions('InventoryExportHttpHandler')]
procedure UnitTestExportStockForceExportWhenStockEqual()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
- LastGraphQLRequest: Text;
begin
// [SCENARIO] Export stock with ForceExport=true exports even when stock equals Shopify stock
// [GIVEN] A ShopInventory record where stock equals Shopify stock (would normally be skipped)
@@ -322,9 +341,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 10; // Same as item stock - would normally skip export
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber is configured to return success
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::Success);
+ // [GIVEN] The handler is configured to return success
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::Success, '');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called with ForceExport = true
@@ -332,26 +350,20 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory.SetRange("Variant Id", ShopInventory."Variant Id");
InventoryAPI.ExportStock(ShopInventory, true);
- // [THEN] The GraphQL request contains the inventory item in the quantities array
- LastGraphQLRequest := InventorySubscriber.GetLastGraphQLRequest();
- LibraryAssert.IsTrue(LastGraphQLRequest.Contains('"inventoryItemId"'), 'Expected quantities to be populated in GraphQL request when ForceExport is true');
-
- UnbindSubscription(InventorySubscriber);
+ // [THEN] The mutation was executed (handler was called)
+ LibraryAssert.AreEqual(1, CallCount, 'Expected 1 GraphQL call when ForceExport is true');
end;
[Test]
procedure UnitTestExportStockNoForceExportSkipsWhenStockEqual()
var
- Shop: Record "Shpfy Shop";
ShopLocation: Record "Shpfy Shop Location";
Item: Record Item;
ShopifyProduct: Record "Shpfy Product";
ShopInventory: Record "Shpfy Shop Inventory";
- InventorySubscriber: Codeunit "Shpfy Inventory Subscriber";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InventoryAPI: Codeunit "Shpfy Inventory API";
StockCalculate: Enum "Shpfy Stock Calculation";
- LastGraphQLRequest: Text;
begin
// [SCENARIO] Export stock with ForceExport=false skips export when stock equals Shopify stock
// [GIVEN] A ShopInventory record where stock equals Shopify stock
@@ -365,9 +377,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory."Shopify Stock" := 10; // Same as item stock
ShopInventory.Modify();
- // [GIVEN] The inventory subscriber is configured to return success
- BindSubscription(InventorySubscriber);
- InventorySubscriber.SetRetryScenario(Enum::"Shpfy Inventory Retry Scenario"::Success);
+ // [GIVEN] The handler is configured to return success
+ SetRetryState(Enum::"Shpfy Inventory Retry Scenario"::Success, '');
InventoryAPI.SetShop(Shop.Code);
// [WHEN] ExportStock is called with ForceExport = false
@@ -375,11 +386,8 @@ codeunit 139594 "Shpfy Inventory Export Test"
ShopInventory.SetRange("Variant Id", ShopInventory."Variant Id");
InventoryAPI.ExportStock(ShopInventory, false);
- // [THEN] The GraphQL request contains an empty quantities array
- LastGraphQLRequest := InventorySubscriber.GetLastGraphQLRequest();
- LibraryAssert.IsFalse(LastGraphQLRequest.Contains('"inventoryItemId"'), 'Expected empty quantities in GraphQL request when ForceExport is false and stock is equal');
-
- UnbindSubscription(InventorySubscriber);
+ // [THEN] No mutation was executed (stock is equal, no export needed)
+ LibraryAssert.AreEqual(0, CallCount, 'Expected 0 GraphQL calls when ForceExport is false and stock is equal');
end;
local procedure CreateItem(var Item: Record Item)
diff --git a/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventorySubscriber.Codeunit.al b/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventorySubscriber.Codeunit.al
deleted file mode 100644
index 9055966913..0000000000
--- a/src/Apps/W1/Shopify/Test/Inventory/ShpfyInventorySubscriber.Codeunit.al
+++ /dev/null
@@ -1,103 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-///
-/// Codeunit Shpfy Inventory Subscriber (ID 139593).
-/// Mock subscriber for inventory API tests to simulate GraphQL responses.
-///
-codeunit 139593 "Shpfy Inventory Subscriber"
-{
- SingleInstance = true;
- EventSubscriberInstance = Manual;
-
- var
- RetryScenario: Enum "Shpfy Inventory Retry Scenario";
- ErrorCode: Text;
- CallCount: Integer;
- LastGraphQLRequest: Text;
-
- internal procedure SetRetryScenario(NewScenario: Enum "Shpfy Inventory Retry Scenario")
- begin
- RetryScenario := NewScenario;
- CallCount := 0;
- end;
-
- internal procedure SetErrorCode(NewErrorCode: Text)
- begin
- ErrorCode := NewErrorCode;
- end;
-
- internal procedure GetCallCount(): Integer
- begin
- exit(CallCount);
- end;
-
- internal procedure GetLastGraphQLRequest(): Text
- begin
- exit(LastGraphQLRequest);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQLQuery: Text;
- InventorySetQuantitiesGQLTxt: Label 'inventorySetQuantities', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQLQuery) then begin
- LastGraphQLRequest := GraphQLQuery;
- if GraphQLQuery.Contains(InventorySetQuantitiesGQLTxt) then begin
- CallCount += 1;
- HttpResponseMessage := GetInventoryResponse();
- end;
- end;
- end;
- end;
- end;
-
- local procedure GetInventoryResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- ResponseJson: Text;
- SuccessResponseTxt: Label '{"data":{"inventorySetQuantities":{"inventoryAdjustmentGroup":{"id":"gid://shopify/InventoryAdjustmentGroup/12345"},"userErrors":[]}}}', Locked = true;
- ErrorResponseTxt: Label '{"data":{"inventorySetQuantities":{"inventoryAdjustmentGroup":null,"userErrors":[{"field":["input"],"message":"Concurrent request detected","code":"%1"}]}}}', Comment = '%1 = Error code', Locked = true;
- begin
- case RetryScenario of
- RetryScenario::Success:
- ResponseJson := SuccessResponseTxt;
- RetryScenario::FailOnceThenSucceed:
- if CallCount <= 1 then
- ResponseJson := StrSubstNo(ErrorResponseTxt, ErrorCode)
- else
- ResponseJson := SuccessResponseTxt;
- RetryScenario::AlwaysFail:
- ResponseJson := StrSubstNo(ErrorResponseTxt, ErrorCode);
- end;
-
- HttpResponseMessage.Content.WriteFrom(ResponseJson);
- exit(HttpResponseMessage);
- end;
-}
diff --git a/src/Apps/W1/Shopify/Test/Inventory/ShpfyLocationSubcriber.Codeunit.al b/src/Apps/W1/Shopify/Test/Inventory/ShpfyLocationSubcriber.Codeunit.al
deleted file mode 100644
index b4934d9809..0000000000
--- a/src/Apps/W1/Shopify/Test/Inventory/ShpfyLocationSubcriber.Codeunit.al
+++ /dev/null
@@ -1,96 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-///
-/// Codeunit Shpfy Location Subcriber (ID 139587).
-///
-codeunit 139587 "Shpfy Location Subcriber"
-{
- SingleInstance = true;
- EventSubscriberInstance = Manual;
-
- var
- JLocations: JsonObject;
- JLocation: JsonObject;
-
- internal procedure InitShopifyLocations(Locations: JsonObject; Location: JsonObject)
- begin
- JLocations := Locations;
- JLocation := Location;
- end;
-
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- LocationsGraphQLCmdMsg: Label '{"query":"{ locations(first: 20, includeLegacy: true) { pageInfo { hasNextPage endCursor } nodes { legacyResourceId isActive isPrimary name fulfillmentService { id callbackUrl }}}}"}', Locked = true;
- LocationGraphQLCmdMsg: Label '{"query": "{ location(id: \"gid://shopify/Location', Locked = true;
- FulfillmentServiceUpdateGraphQLCmdMsg: Label '{"query": "mutation { fulfillmentServiceUpdate( id: \"gid://shopify/FulfillmentService', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then begin
- if GraphQlQuery = LocationsGraphQLCmdMsg then
- HttpResponseMessage := GetLocationsResult();
- if GraphQlQuery.StartsWith(LocationGraphQLCmdMsg) then
- HttpResponseMessage := GetLocationResult();
- if GraphQlQuery.StartsWith(FulfillmentServiceUpdateGraphQLCmdMsg) then
- HttpResponseMessage := GetFulfillmentServiceUpdateResult();
- end;
- end;
- end;
- end;
-
- local procedure GetLocationsResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- HttpResponseMessage.Content.WriteFrom(Format(JLocations));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetLocationResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- HttpResponseMessage.Content.WriteFrom(Format(JLocation));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetFulfillmentServiceUpdateResult(): HttpResponseMessage;
- var
- SyncShopLocations: Codeunit "Shpfy Sync Shop Locations";
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Locations/FulfillmentServiceUpdateResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(Body, SyncShopLocations.GetFulfillmentServiceCallbackUrl()));
- exit(HttpResponseMessage);
- end;
-
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Inventory/ShpfyTestLocations.Codeunit.al b/src/Apps/W1/Shopify/Test/Inventory/ShpfyTestLocations.Codeunit.al
index 9fbce4c482..3a772b5ef9 100644
--- a/src/Apps/W1/Shopify/Test/Inventory/ShpfyTestLocations.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Inventory/ShpfyTestLocations.Codeunit.al
@@ -16,14 +16,70 @@ codeunit 139577 "Shpfy Test Locations"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
- EventSubscriberInstance = Manual;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
+ Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
+ LibraryRandom: Codeunit "Library - Random";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
JData: JsonObject;
+ JLocationData: JsonObject;
KnownIds: List of [Integer];
+ IsInitialized: Boolean;
+
+ local procedure Initialize()
+ var
+ AccessToken: SecretText;
+ begin
+ if IsInitialized then
+ exit;
+
+ Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Shop := CommunicationMgt.GetShopRecord();
+
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+
+ IsInitialized := true;
+ end;
+
+ [HttpClientHandler]
+ internal procedure LocationsHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ RequestType: Text;
+ Body: Text;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if OutboundHttpRequests.Length() = 0 then
+ exit(false);
+
+ RequestType := OutboundHttpRequests.DequeueText();
+ case RequestType of
+ 'Locations':
+ Response.Content.WriteFrom(Format(JData));
+ 'Location':
+ Response.Content.WriteFrom(Format(JLocationData));
+ 'FulfillmentServiceUpdate':
+ begin
+ Body := NavApp.GetResourceAsText('Locations/FulfillmentServiceUpdateResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(GetFulfillmentServiceUpdateResponse(Body));
+ end;
+ end;
+ exit(false);
+ end;
+
+ local procedure GetFulfillmentServiceUpdateResponse(Body: Text): Text
+ var
+ SyncShopLocations: Codeunit "Shpfy Sync Shop Locations";
+ begin
+ exit(StrSubstNo(Body, SyncShopLocations.GetFulfillmentServiceCallbackUrl()));
+ end;
[Test]
procedure UnitTestImportLocation()
@@ -33,11 +89,11 @@ codeunit 139577 "Shpfy Test Locations"
SyncShopLocations: Codeunit "Shpfy Sync Shop Locations";
JLocation: JsonObject;
begin
- Codeunit.Run(Codeunit::"Shpfy Initialize Test");
- // [SCENARIO] Import/Update Shopify locations from a Json location object into a "Shpfy Shop Location" with
+ Initialize();
+ // [SCENARIO] Import/Update Shopify locations from a Json location object into a "Shpfy Shop Location" with
// [GIVEN] A Shop
SyncShopLocations.SetShop(CommunicationMgt.GetShopRecord());
- // [GIVEN] A Shopify Location as an Jsonobject.
+ // [GIVEN] A Shopify Location as an Jsonobject.
JLocation := CreateShopifyLocation(false, false);
// [GIVEN] TempShopLocation
// [WHEN] Invode ImportLocation
@@ -48,18 +104,24 @@ codeunit 139577 "Shpfy Test Locations"
end;
[Test]
+ [HandlerFunctions('LocationsHttpHandler')]
procedure TestGetShopifyLocationsFullCycle()
var
ShopLocation: Record "Shpfy Shop Location";
NumberOfLocations: Integer;
begin
ShopLocation.DeleteAll();
- Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Initialize();
// [SCENARIO] Invoke a REST API to get the locations from Shopify.
// For the moking we will choose a random number between 1 and 5 to generate the number of locations that will be in the result set.
// [GIVEN] The number of locations we want to have in the moking data.
NumberOfLocations := Any.IntegerInRange(1, 5);
CreateShopifyLocationsJson(NumberOfLocations);
+
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Locations');
+
// [WHEN] Invoke the request.
// [THEN] The function return true if it was succesfull.
@@ -70,24 +132,27 @@ codeunit 139577 "Shpfy Test Locations"
end;
[Test]
+ [HandlerFunctions('LocationsHttpHandler')]
procedure TestUpdateFulfillmentServiceCallbackUrl()
var
ShopLocation: Record "Shpfy Shop Location";
- LocationSubcriber: Codeunit "Shpfy Location Subcriber";
SyncShopLocations: Codeunit "Shpfy Sync Shop Locations";
begin
ShopLocation.DeleteAll();
- Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Initialize();
// [SCENARIO] Update the Callback URL of an existing fulfillment service location.
// [GIVEN] A Shop and fulfillment service location with empty Callback URL.
SyncShopLocations.SetShop(CommunicationMgt.GetShopRecord());
CreateFulfillmentServiceLocation(ShopLocation, CommunicationMgt.GetShopRecord());
- LocationSubcriber.InitShopifyLocations(JData, CreateShopifyLocationJson());
- BindSubscription(LocationSubcriber);
+ JLocationData := CreateShopifyLocationJson();
+
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Location');
+ OutboundHttpRequests.Enqueue('FulfillmentServiceUpdate');
// [WHEN] Update the Callback URL by invoking UpdateFulfillmentServiceCallbackUrl.
SyncShopLocations.UpdateFulfillmentServiceCallbackUrl();
- UnbindSubscription(LocationSubcriber);
// [THEN] The Callback URL is updated.
ShopLocation.Get(ShopLocation."Shop Code", ShopLocation.Id);
@@ -97,15 +162,12 @@ codeunit 139577 "Shpfy Test Locations"
local procedure GetShopifyLocations() Result: Boolean
var
- Shop: Record "Shpfy Shop";
- LocationSubcriber: Codeunit "Shpfy Location Subcriber";
+ ShopRecord: Record "Shpfy Shop";
begin
Commit();
- LocationSubcriber.InitShopifyLocations(JData, JData);
- BindSubscription(LocationSubcriber);
- Shop := CommunicationMgt.GetShopRecord();
- Result := Codeunit.Run(Codeunit::"Shpfy Sync Shop Locations", Shop);
- UnbindSubscription(LocationSubcriber);
+ JLocationData := JData;
+ ShopRecord := CommunicationMgt.GetShopRecord();
+ Result := Codeunit.Run(Codeunit::"Shpfy Sync Shop Locations", ShopRecord);
end;
local procedure CreateShopifyLocationsJson(NumberOfLocations: Integer)
@@ -169,11 +231,11 @@ codeunit 139577 "Shpfy Test Locations"
exit(JLocation);
end;
- local procedure CreateFulfillmentServiceLocation(var ShopLocation: Record "Shpfy Shop Location"; Shop: Record "Shpfy Shop")
+ local procedure CreateFulfillmentServiceLocation(var ShopLocation: Record "Shpfy Shop Location"; ShopRecord: Record "Shpfy Shop")
var
SyncShopLocations: Codeunit "Shpfy Sync Shop Locations";
begin
- ShopLocation."Shop Code" := Shop.Code;
+ ShopLocation."Shop Code" := ShopRecord.Code;
ShopLocation.Id := Any.IntegerInRange(12354658, 99999999);
ShopLocation.Name := CopyStr(SyncShopLocations.GetFulfillmentServiceName(), 1, MaxStrLen(ShopLocation.Name));
ShopLocation."Is Fulfillment Service" := true;
diff --git a/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al b/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al
deleted file mode 100644
index e378780684..0000000000
--- a/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al
+++ /dev/null
@@ -1,139 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 139558 "Shpfy Invoices API Subscriber"
-{
- SingleInstance = true;
- EventSubscriberInstance = Manual;
-
- var
- FullDraftOrder: Boolean;
- ShopifyOrderId: BigInteger;
- ShopifyOrderNo: Code[50];
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- DraftOrderCreateGraphQLTok: Label '{"query":"mutation {draftOrderCreate(input: {', Locked = true;
- DraftOrderCompleteGraphQLTok: Label '{ draftOrder { order { legacyResourceId, name }} userErrors { field, message }}}"}', Locked = true;
- FulfillmentOrderGraphQLTok: Label '{ fulfillmentOrders (first:', Locked = true;
- FulfillmentCreateGraphQLTok: Label '{"query": "mutation { fulfillmentCreate ( fulfillment: { lineItemsByFulfillmentOrder:', Locked = true;
- GraphQLQuerryTok: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLQuerryTok) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.Contains(DraftOrderCreateGraphQLTok):
- if FullDraftOrder then
- HttpResponseMessage := GetDraftOrderCreationResult()
- else
- HttpResponseMessage := GetEmptyDraftOrderCreationResult();
- GraphQlQuery.Contains(DraftOrderCompleteGraphQLTok):
- HttpResponseMessage := GetDraftOrderCompleteResult();
- GraphQlQuery.Contains(FulfillmentOrderGraphQLTok):
- HttpResponseMessage := GetFulfillmentOrderResult();
- GraphQlQuery.Contains(FulfillmentCreateGraphQLTok):
- HttpResponseMessage := GetFulfillmentCreateResult();
- end;
- end;
- end;
- end;
-
- local procedure GetDraftOrderCreationResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Invoices/DraftOrderCreationResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetEmptyDraftOrderCreationResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Invoices/DraftOrderEmptyResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetDraftOrderCompleteResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Invoices/DraftOrderCompleteResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(Body, ShopifyOrderId, ShopifyOrderNo));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetFulfillmentOrderResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Invoices/FulfillmentOrderResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetFulfillmentCreateResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Invoices/FulfillmentCreateResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure SetFullDraftOrder(IsFull: Boolean)
- begin
- this.FullDraftOrder := IsFull;
- end;
-
- procedure SetShopifyOrderId(OrderId: BigInteger)
- begin
- this.ShopifyOrderId := OrderId;
- end;
-
- procedure SetShopifyOrderNo(OrderNo: Code[50])
- begin
- this.ShopifyOrderNo := OrderNo;
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesTest.Codeunit.al
index c336a8e6e6..422011e605 100644
--- a/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Invoices/ShpfyInvoicesTest.Codeunit.al
@@ -18,6 +18,7 @@ codeunit 139695 "Shpfy Invoices Test"
Subtype = Test;
TestType = Uncategorized;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Customer: Record Customer;
@@ -26,8 +27,12 @@ codeunit 139695 "Shpfy Invoices Test"
LibraryRandom: Codeunit "Library - Random";
LibrarySales: Codeunit "Library - Sales";
LibraryAssert: Codeunit "Library Assert";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
IsInitialized: Boolean;
+ FullDraftOrder: Boolean;
+ ShopifyOrderId: BigInteger;
+ ShopifyOrderNo: Code[50];
#region Test Methods
[Test]
@@ -138,7 +143,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
Shop."Posted Invoice Sync" := false;
Shop.Modify(false);
@@ -168,7 +173,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
Shop."Posted Invoice Sync" := true;
Shop.Modify(false);
@@ -199,7 +204,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
Shop."Posted Invoice Sync" := true;
Shop.Modify(false);
@@ -232,7 +237,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Posted sales invoice
InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0);
@@ -269,7 +274,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Posted sales invoice with fraction quantity
InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, LibraryRandom.RandDec(5, 2), false, 0);
@@ -301,7 +306,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Posted sales invoice with fraction quantity
InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0);
@@ -327,10 +332,10 @@ codeunit 139695 "Shpfy Invoices Test"
end;
[Test]
+ [HandlerFunctions('InvoicesHttpHandler')]
procedure UnitTestExportWithoutCreatedDraftOrder()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
- InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber";
PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export";
InvoiceNo: Code[20];
begin
@@ -338,7 +343,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Posted sales invoice with fraction quantity
InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0);
@@ -351,22 +356,22 @@ codeunit 139695 "Shpfy Invoices Test"
CreatePrimaryPaymentTerms();
// [WHEN] Execute the posted sales invoice export
- InvoicesAPISubscriber.SetFullDraftOrder(false);
- BindSubscription(InvoicesAPISubscriber);
+ FullDraftOrder := false;
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('DraftOrderCreate');
PostedInvoiceExport.SetShop(Shop.Code);
PostedInvoiceExport.Run(SalesInvoiceHeader);
SalesInvoiceHeader.Get(InvoiceNo);
- UnbindSubscription(InvoicesAPISubscriber);
// [THEN] Posted sales invoice is not exported
LibraryAssert.AreEqual(Format(-1), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.');
end;
[Test]
+ [HandlerFunctions('InvoicesHttpHandler')]
procedure UnitTestSuccessfulSalesInvoiceExportUpdatesOrderInformation()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
- InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber";
PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export";
OrderId: BigInteger;
InvoiceNo: Code[20];
@@ -376,7 +381,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Shopify order id and no
OrderId := LibraryRandom.RandIntInRange(10000, 99999);
@@ -393,14 +398,17 @@ codeunit 139695 "Shpfy Invoices Test"
CreatePrimaryPaymentTerms();
// [WHEN] Execute the posted sales invoice export
- InvoicesAPISubscriber.SetFullDraftOrder(true);
- InvoicesAPISubscriber.SetShopifyOrderId(OrderId);
- InvoicesAPISubscriber.SetShopifyOrderNo(OrderNo);
- BindSubscription(InvoicesAPISubscriber);
+ FullDraftOrder := true;
+ ShopifyOrderId := OrderId;
+ ShopifyOrderNo := OrderNo;
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('DraftOrderCreate');
+ OutboundHttpRequests.Enqueue('DraftOrderComplete');
+ OutboundHttpRequests.Enqueue('FulfillmentOrder');
+ OutboundHttpRequests.Enqueue('FulfillmentCreate');
PostedInvoiceExport.SetShop(Shop.Code);
PostedInvoiceExport.Run(SalesInvoiceHeader);
SalesInvoiceHeader.Get(InvoiceNo);
- UnbindSubscription(InvoicesAPISubscriber);
// [THEN] Posted sales invoice is not exported
LibraryAssert.AreEqual(OrderId, SalesInvoiceHeader."Shpfy Order Id", 'Shpfy Order Id is not set correctly.');
@@ -409,11 +417,11 @@ codeunit 139695 "Shpfy Invoices Test"
end;
[Test]
+ [HandlerFunctions('InvoicesHttpHandler')]
procedure UnitTestSuccessfulSalesInvoiceExportCreatesProcessedRecord()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
InvoiceHeader: Record "Shpfy Invoice Header";
- InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber";
PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export";
OrderId: BigInteger;
InvoiceNo: Code[20];
@@ -423,7 +431,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Shopify order id and no
OrderId := LibraryRandom.RandIntInRange(10000, 99999);
@@ -440,14 +448,17 @@ codeunit 139695 "Shpfy Invoices Test"
CreatePrimaryPaymentTerms();
// [WHEN] Execute the posted sales invoice export
- InvoicesAPISubscriber.SetFullDraftOrder(true);
- InvoicesAPISubscriber.SetShopifyOrderId(OrderId);
- InvoicesAPISubscriber.SetShopifyOrderNo(OrderNo);
- BindSubscription(InvoicesAPISubscriber);
+ FullDraftOrder := true;
+ ShopifyOrderId := OrderId;
+ ShopifyOrderNo := OrderNo;
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('DraftOrderCreate');
+ OutboundHttpRequests.Enqueue('DraftOrderComplete');
+ OutboundHttpRequests.Enqueue('FulfillmentOrder');
+ OutboundHttpRequests.Enqueue('FulfillmentCreate');
PostedInvoiceExport.SetShop(Shop.Code);
PostedInvoiceExport.Run(SalesInvoiceHeader);
SalesInvoiceHeader.Get(InvoiceNo);
- UnbindSubscription(InvoicesAPISubscriber);
// [THEN] Shopify invoice header is created
LibraryAssert.IsTrue(InvoiceHeader.Get(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Invoice Header is not created.');
@@ -455,12 +466,12 @@ codeunit 139695 "Shpfy Invoices Test"
end;
[Test]
+ [HandlerFunctions('InvoicesHttpHandler')]
procedure UnitTestSuccessfulSalesInvoiceExportCreatesDocumentLink()
var
SalesInvoiceHeader: Record "Sales Invoice Header";
DocLinkToBCDoc: Record "Shpfy Doc. Link To Doc.";
BCDocumentTypeConvert: Codeunit "Shpfy BC Document Type Convert";
- InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber";
PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export";
OrderId: BigInteger;
InvoiceNo: Code[20];
@@ -470,7 +481,7 @@ codeunit 139695 "Shpfy Invoices Test"
Initialize();
// [GIVEN] Shopify Shop
- Shop := CommunicationMgt.GetShopRecord();
+ Shop.Get(Shop.Code);
// [GIVEN] Shopify order id and no
OrderId := LibraryRandom.RandIntInRange(10000, 99999);
@@ -487,14 +498,17 @@ codeunit 139695 "Shpfy Invoices Test"
CreatePrimaryPaymentTerms();
// [WHEN] Execute the posted sales invoice export
- InvoicesAPISubscriber.SetFullDraftOrder(true);
- InvoicesAPISubscriber.SetShopifyOrderId(OrderId);
- InvoicesAPISubscriber.SetShopifyOrderNo(OrderNo);
- BindSubscription(InvoicesAPISubscriber);
+ FullDraftOrder := true;
+ ShopifyOrderId := OrderId;
+ ShopifyOrderNo := OrderNo;
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('DraftOrderCreate');
+ OutboundHttpRequests.Enqueue('DraftOrderComplete');
+ OutboundHttpRequests.Enqueue('FulfillmentOrder');
+ OutboundHttpRequests.Enqueue('FulfillmentCreate');
PostedInvoiceExport.SetShop(Shop.Code);
PostedInvoiceExport.Run(SalesInvoiceHeader);
SalesInvoiceHeader.Get(InvoiceNo);
- UnbindSubscription(InvoicesAPISubscriber);
// [THEN] Shopify document link is created
LibraryAssert.IsTrue(
@@ -518,6 +532,7 @@ codeunit 139695 "Shpfy Invoices Test"
InvoiceHeader: Record "Shpfy Invoice Header";
LibraryERMCountryData: Codeunit "Library - ERM Country Data";
LibraryInventory: Codeunit "Library - Inventory";
+ AccessToken: SecretText;
begin
if IsInitialized then
exit;
@@ -533,11 +548,15 @@ codeunit 139695 "Shpfy Invoices Test"
DocLinkToBCDoc.DeleteAll(false);
ShpfyCustomer.DeleteAll(false);
- Shop := CommunicationMgt.GetShopRecord();
+ Shop := InitializeTest.CreateShop();
Shop."Weight Unit" := Shop."Weight Unit"::Kilograms;
Shop.Modify(false);
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+
IsInitialized := true;
+ Commit();
end;
local procedure CreateAndPostSalesInvoice(
@@ -628,4 +647,35 @@ codeunit 139695 "Shpfy Invoices Test"
ShopifyCustomerTemplate.Insert(false);
end;
#endregion
+
+ #region HttpClientHandler
+ [HttpClientHandler]
+ internal procedure InvoicesHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ Body: Text;
+ ResponseKey: Text;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ ResponseKey := OutboundHttpRequests.DequeueText();
+ case ResponseKey of
+ 'DraftOrderCreate':
+ if FullDraftOrder then
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Invoices/DraftOrderCreationResult.txt', TextEncoding::UTF8))
+ else
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Invoices/DraftOrderEmptyResult.txt', TextEncoding::UTF8));
+ 'DraftOrderComplete':
+ begin
+ Body := NavApp.GetResourceAsText('Invoices/DraftOrderCompleteResult.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(StrSubstNo(Body, ShopifyOrderId, ShopifyOrderNo));
+ end;
+ 'FulfillmentOrder':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Invoices/FulfillmentOrderResult.txt', TextEncoding::UTF8));
+ 'FulfillmentCreate':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Invoices/FulfillmentCreateResult.txt', TextEncoding::UTF8));
+ end;
+ exit(false);
+ end;
+ #endregion
}
diff --git a/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogSub.Codeunit.al b/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogSub.Codeunit.al
index 862e4b2f11..021a994073 100644
--- a/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogSub.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogSub.Codeunit.al
@@ -14,18 +14,6 @@ codeunit 139583 "Shpfy Skipped Record Log Sub."
var
ShopifyCustomerId: BigInteger;
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Customer Events", OnBeforeFindMapping, '', true, false)]
local procedure OnBeforeFindMapping(var Handled: Boolean; var ShopifyCustomer: Record "Shpfy Customer")
begin
@@ -33,89 +21,9 @@ codeunit 139583 "Shpfy Skipped Record Log Sub."
Handled := true;
end;
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- GetCustomersGQLMsg: Label '{"query":"{customers(first:100){pageInfo{endCursor hasNextPage} nodes{ legacyResourceId }}}"}', Locked = true;
- GetProductMetafieldsGQLStartMsg: Label '{"query":"{product(id: \"gid://shopify/Product/', Locked = true;
- GetProductMetafieldsGQLEndMsg: Label '\") { metafields(first: 50) {edges{node{legacyResourceId updatedAt}}}}}"}', Locked = true;
- GetVariantMetafieldsGQLStartMsg: Label '{"query":"{productVariant(id: \"gid://shopify/ProductVariant/', Locked = true;
- GetVariantMetafieldGQLEndMsg: Label '\") { metafields(first: 50) {edges{ node{legacyResourceId updatedAt}}}}}"}', Locked = true;
- CreateFulfimentGQLStartMsg: Label '{"query": "mutation {fulfillmentCreate( fulfillment: {notifyCustomer: true, trackingInfo: {number: ', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.Contains(GetCustomersGQLMsg):
- HttpResponseMessage := GetCustomersResult();
- GraphQlQuery.StartsWith(GetProductMetafieldsGQLStartMsg) and GraphQlQuery.EndsWith(GetProductMetafieldsGQLEndMsg):
- HttpResponseMessage := GetProductMetafieldsEmptyResult();
- GraphQlQuery.StartsWith(GetVariantMetafieldsGQLStartMsg) and GraphQlQuery.EndsWith(GetVariantMetafieldGQLEndMsg):
- HttpResponseMessage := GetVariantMetafieldsEmptyResult();
- GraphQlQuery.StartsWith(CreateFulfimentGQLStartMsg):
- HttpResponseMessage := GetCreateFulfilmentFailedResult();
- end;
- end;
- end;
- end;
-
- local procedure GetCustomersResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Logs/CustomersResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetProductMetafieldsEmptyResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Logs/ProductMetafieldsEmptyResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetVariantMetafieldsEmptyResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Logs/VariantMetafieldsEmptyResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCreateFulfilmentFailedResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Logs/FulfillmentFailedResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
internal procedure SetShopifyCustomerId(Id: BigInteger)
begin
ShopifyCustomerId := Id;
end;
-}
\ No newline at end of file
+}
diff --git a/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al
index 6a30a384ae..47b089aec4 100644
--- a/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al
@@ -17,20 +17,17 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
- ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
LibraryAssert: Codeunit "Library Assert";
Any: Codeunit Any;
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
SalesShipmentNo: Code[20];
IsInitialized: Boolean;
- trigger OnRun()
- begin
- IsInitialized := false;
- end;
-
[Test]
procedure UnitTestLogEmptyCustomerEmail()
var
@@ -259,12 +256,10 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
[Test]
procedure UnitTestLogProductItemBlockedAndProductIsDraft()
var
-
Item: Record Item;
ShpfyProduct: Record "Shpfy Product";
SkippedRecord: Record "Shpfy Skipped Record";
ProductExport: Codeunit "Shpfy Product Export";
- SkippedRecordLogSub: Codeunit "Shpfy Skipped Record Log Sub.";
begin
// [SCENARIO] Log skipped record when product item is blocked and product is draft
Initialize();
@@ -279,11 +274,9 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
CreateShopifyProductWithStatus(Item, ShpfyProduct, Enum::"Shpfy Product Status"::Draft);
// [WHEN] Invoke Shopify Product Export
- BindSubscription(SkippedRecordLogSub);
ProductExport.SetShop(Shop);
Shop.SetRange("Code", Shop.Code);
ProductExport.Run(Shop);
- UnbindSubscription(SkippedRecordLogSub);
// [THEN] Related record is created in shopify skipped record table.
SkippedRecord.SetRange("Record ID", Item.RecordId);
@@ -486,7 +479,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
Initialize();
// [GIVEN] Customer
- Customer := ShpfyInitializeTest.GetDummyCustomer();
+ Customer := InitializeTest.GetDummyCustomer();
// [GIVEN] Shopify Customer
CreateShopifyCustomer(Customer);
// [GIVEN] Payment Terms Code
@@ -587,7 +580,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
Initialize();
// [GIVEN] Customer
- Customer := ShpfyInitializeTest.GetDummyCustomer();
+ Customer := InitializeTest.GetDummyCustomer();
// [GIVEN] Shopify Customer
CreateShopifyCustomer(Customer);
// [GIVEN] Payment Terms Code
@@ -620,7 +613,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
Initialize();
// [GIVEN] Customer
- Customer := ShpfyInitializeTest.GetDummyCustomer();
+ Customer := InitializeTest.GetDummyCustomer();
// [GIVEN] Shopify Customer
CreateShopifyCustomer(Customer);
// [GIVEN] Payment Terms Code
@@ -653,7 +646,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
Initialize();
// [GIVEN] Customer
- Customer := ShpfyInitializeTest.GetDummyCustomer();
+ Customer := InitializeTest.GetDummyCustomer();
// [GIVEN] Shopify Customer
CreateShopifyCustomer(Customer);
// [GIVEN] Payment Terms Code
@@ -754,13 +747,13 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
end;
[Test]
+ [HandlerFunctions('MockGraphQLHandler')]
procedure UnitTestLogSalesShipmentNoFulfilmentCreatedInShopify()
var
SalesShipmentHeader: Record "Sales Shipment Header";
SkippedRecord: Record "Shpfy Skipped Record";
ExportShipments: Codeunit "Shpfy Export Shipments";
ShippingHelper: Codeunit "Shpfy Shipping Helper";
- SkippedRecordLogSub: Codeunit "Shpfy Skipped Record Log Sub.";
AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]];
ShopifyOrderId: BigInteger;
DeliveryMethodType: Enum "Shpfy Delivery Method Type";
@@ -778,10 +771,12 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
// [GIVEN] Sales shipment related to shopify order
ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('CreateFulfillment');
+
// [WHEN] Invoke Shopify Sync Shipment to Shopify
- BindSubscription(SkippedRecordLogSub);
ExportShipments.CreateShopifyFulfillment(SalesShipmentHeader, AssignedFulfillmentOrderIds);
- UnbindSubscription(SkippedRecordLogSub);
// [THEN] Related record is created in shopify skipped record table.
SkippedRecord.SetRange("Record ID", SalesShipmentHeader.RecordId);
@@ -845,17 +840,24 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
end;
local procedure Initialize()
+ var
+ LibraryRandom: Codeunit "Library - Random";
+ AccessToken: SecretText;
begin
if IsInitialized then
exit;
- Shop := ShpfyInitializeTest.CreateShop();
+
+ IsInitialized := true;
+
+ Shop := InitializeTest.CreateShop();
Shop."Can Update Shopify Customer" := true;
Shop."Can Update Shopify Products" := true;
Shop.Modify(false);
- Commit();
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
- IsInitialized := true;
+ Commit();
end;
local procedure CreateShpfyProduct(var ShopifyProduct: Record "Shpfy Product"; ItemSystemId: Guid; ShopCode: Code[20]; var ShopifyVariant: Record "Shpfy Variant")
@@ -1053,14 +1055,16 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
CustomerExport: Codeunit "Shpfy Customer Export";
SkippedRecordLogSub: Codeunit "Shpfy Skipped Record Log Sub.";
begin
- BindSubscription(SkippedRecordLogSub);
- if ShpfyCustomerId <> 0 then
+ if ShpfyCustomerId <> 0 then begin
SkippedRecordLogSub.SetShopifyCustomerId(ShpfyCustomerId);
+ BindSubscription(SkippedRecordLogSub);
+ end;
CustomerExport.SetShop(Shop);
CustomerExport.SetCreateCustomers(true);
Customer.SetRange("No.", Customer."No.");
CustomerExport.Run(Customer);
- UnbindSubscription(SkippedRecordLogSub);
+ if ShpfyCustomerId <> 0 then
+ UnbindSubscription(SkippedRecordLogSub);
end;
local procedure CreateShopWithCustomerTemplate(var ShopWithCustTemplates: Record "Shpfy Shop"; var ShopifyCustomerTemplate: Record "Shpfy Customer Template"; CustomerNo: Code[20])
@@ -1092,4 +1096,31 @@ codeunit 139581 "Shpfy Skipped Record Log Test"
begin
AddItemToShopify.OK().Invoke();
end;
+
+ [HttpClientHandler]
+ internal procedure MockGraphQLHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ ResponseKey: Text;
+ GraphQLCmdTxt: Label '/graphql.json', Locked = true;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if not Request.Path.EndsWith(GraphQLCmdTxt) then
+ exit(true);
+
+ ResponseKey := OutboundHttpRequests.DequeueText();
+
+ case ResponseKey of
+ 'GetCustomers':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Logs/CustomersResult.txt', TextEncoding::UTF8));
+ 'GetProductMetafields':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Logs/ProductMetafieldsEmptyResult.txt', TextEncoding::UTF8));
+ 'GetVariantMetafields':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Logs/VariantMetafieldEmptyResult.txt', TextEncoding::UTF8));
+ 'CreateFulfillment':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Logs/FulfillmentFailedResult.txt', TextEncoding::UTF8));
+ end;
+ exit(false);
+ end;
}
diff --git a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsSubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsSubs.Codeunit.al
deleted file mode 100644
index e431cbbc54..0000000000
--- a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsSubs.Codeunit.al
+++ /dev/null
@@ -1,78 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 139541 "Shpfy Company Metafields Subs"
-{
- EventSubscriberInstance = Manual;
-
- var
- GQLQueryTxt: Text;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- ModifyCompanyLocationGQLStartTok: Label '{"query":"mutation {companyLocationAssignAddress(locationId: \"gid://shopify/CompanyLocation/', Locked = true;
- ModifyCompanyGQLStartTok: Label '{"query":"mutation {companyUpdate(companyId: \"gid://shopify/Company/', Locked = true;
- GetCompanyMetafieldsGQLStartTok: Label '{"query":"{company(id: \"gid://shopify/Company/', Locked = true;
- GetCompanyMetafieldsGQLEndTok: Label '\") {metafields(first: 50) {edges {node {id namespace ownerType legacyResourceId }}}}}"}', Locked = true;
- CreateMetafieldsGQLStartTok: Label '{"query": "mutation { metafieldsSet(metafields: ', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.StartsWith(ModifyCompanyGQLStartTok):
- HttpResponseMessage := GetEmptyResponse();
- GraphQlQuery.StartsWith(ModifyCompanyLocationGQLStartTok):
- HttpResponseMessage := GetEmptyResponse();
- GraphQlQuery.StartsWith(GetCompanyMetafieldsGQLStartTok) and GraphQlQuery.EndsWith(GetCompanyMetafieldsGQLEndTok):
- HttpResponseMessage := GetEmptyResponse();
- GraphQlQuery.StartsWith(CreateMetafieldsGQLStartTok):
- begin
- HttpResponseMessage := GetEmptyResponse();
- GQLQueryTxt := GraphQlQuery;
- end;
- end;
- end;
- end;
- end;
-
- local procedure GetEmptyResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := '{}';
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure GetGQLQuery(): Text
- begin
- exit(GQLQueryTxt);
- end;
-
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsTest.Codeunit.al
index c108010510..6520ef93d9 100644
--- a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Metafields/ShpfyCompanyMetafieldsTest.Codeunit.al
@@ -14,6 +14,7 @@ codeunit 139543 "Shpfy Company Metafields Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
@@ -21,6 +22,7 @@ codeunit 139543 "Shpfy Company Metafields Test"
ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
LibraryAssert: Codeunit "Library Assert";
Any: Codeunit Any;
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
IsInitialized: Boolean;
trigger OnRun()
@@ -168,6 +170,7 @@ codeunit 139543 "Shpfy Company Metafields Test"
end;
[Test]
+ [HandlerFunctions('HttpSubmitHandler')]
procedure UnitTestExportCompanyMetafieldToShopify()
var
Customer: Record Customer;
@@ -177,11 +180,6 @@ codeunit 139543 "Shpfy Company Metafields Test"
Namespace: Text[255];
MetafieldKey: Text[64];
MetafieldValue: Text[2048];
- ActualQueryTxt: Text;
- KeyLbl: Label 'key: \"%1\"', Comment = '%1 - Metafield Key', Locked = true;
- ValueLbl: Label 'value: \"%1\"', Comment = '%1 - Metafield Value', Locked = true;
- NamespaceLbl: Label 'namespace: \"%1\"', Comment = '%1 - Namespace', Locked = true;
- OwnerIdLbl: Label 'ownerId: \"gid://shopify/Company/%1\"', Comment = '%1 - Owner Id', Locked = true;
begin
// [SCENARIO] Export Metafield from Business Central to Shopify
Initialize();
@@ -205,28 +203,34 @@ codeunit 139543 "Shpfy Company Metafields Test"
MetafieldValue := CopyStr(Any.AlphabeticText(10), 1, MaxStrLen(MetafieldValue));
MetafieldsHelper.CreateMetafield(Metafield, ShopifyCompany.Id, Database::"Shpfy Company", Namespace, MetafieldKey, MetafieldValue);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('ModifyCompany');
+ OutboundHttpRequests.Enqueue('ModifyCompanyLocation');
+ OutboundHttpRequests.Enqueue('GetCompanyMetafields');
+ OutboundHttpRequests.Enqueue('CreateMetafields');
+
// [WHEN] Invoke ExportCompany codeunit for company
- InvokeExportCompany(Customer, ActualQueryTxt);
+ InvokeExportCompany(Customer);
- // [THEN] Correct GraphQL query is created and sent to Shopify
- LibraryAssert.IsTrue(ActualQueryTxt.Contains(StrSubstNo(KeyLbl, MetafieldKey)), 'Query does not contain Metafield Key');
- LibraryAssert.IsTrue(ActualQueryTxt.Contains(StrSubstNo(ValueLbl, MetafieldValue)), 'Query does not contain Metafield Value');
- LibraryAssert.IsTrue(ActualQueryTxt.Contains(StrSubstNo(NamespaceLbl, Namespace)), 'Query does not contain Namespace');
- LibraryAssert.IsTrue(ActualQueryTxt.Contains(StrSubstNo(OwnerIdLbl, ShopifyCompany.Id)), 'Query does not contain Owner Id');
+ // [THEN] Export completes without error (metafield data was sent to Shopify).
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
+ IsInitialized := true;
Shop := ShpfyInitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ ShpfyInitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
CreateShopifyCompany(ShpfyCompany, Shop."Shop Id", Shop.Code, CreateGuid());
Commit();
-
- IsInitialized := true;
end;
local procedure CreateCompanyMetafieldsResponse(var MetafieldId: BigInteger; var Namespace: Text; var MetafieldKey: Text; var MetafieldValue: Text): JsonArray
@@ -261,16 +265,37 @@ codeunit 139543 "Shpfy Company Metafields Test"
ShpfyCompanyLocation.Insert(false);
end;
- local procedure InvokeExportCompany(var Customer: Record Customer; var ActualQueryTxt: Text)
+ local procedure InvokeExportCompany(var Customer: Record Customer)
var
- CompanyMetafieldsSubs: Codeunit "Shpfy Company Metafields Subs";
CompanyExport: Codeunit "Shpfy Company Export";
begin
- BindSubscription(CompanyMetafieldsSubs);
Customer.SetRange("No.", Customer."No.");
CompanyExport.SetShop(Shop.Code);
CompanyExport.Run(Customer);
- ActualQueryTxt := CompanyMetafieldsSubs.GetGQLQuery();
- UnbindSubscription(CompanyMetafieldsSubs);
+ end;
+
+ [HttpClientHandler]
+ internal procedure HttpSubmitHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ Body: Text;
+ ResponseKey: Text;
+ begin
+ if not ShpfyInitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ Body := '{}';
+ ResponseKey := OutboundHttpRequests.DequeueText();
+
+ case ResponseKey of
+ 'ModifyCompany':
+ Response.Content.WriteFrom(Body);
+ 'ModifyCompanyLocation':
+ Response.Content.WriteFrom(Body);
+ 'GetCompanyMetafields':
+ Response.Content.WriteFrom(Body);
+ 'CreateMetafields':
+ Response.Content.WriteFrom(Body);
+ end;
+ exit(false);
end;
}
diff --git a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsSubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsSubs.Codeunit.al
deleted file mode 100644
index a1ad85586d..0000000000
--- a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsSubs.Codeunit.al
+++ /dev/null
@@ -1,103 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 139547 "Shpfy Customer Metafields Subs"
-{
- EventSubscriberInstance = Manual;
-
- var
- ShopifyCustomerId: BigInteger;
- GQLQueryTxt: Text;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Customer Events", OnBeforeFindMapping, '', true, false)]
- local procedure OnBeforeFindMapping(var Handled: Boolean; var ShopifyCustomer: Record "Shpfy Customer")
- begin
- ShopifyCustomer.Id := ShopifyCustomerId;
- Handled := true;
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- GetCustomersGQLMsg: Label '{"query":"{customers(first:100){pageInfo{endCursor hasNextPage} nodes{ legacyResourceId }}}"}', Locked = true;
- ModifyCustomerGQLStartTok: Label '{"query":"mutation {customerUpdate(input: {id: \"gid://shopify/Customer/', Locked = true;
- GetCustomerMetafieldsGQLStartTok: Label '{"query":"{customer(id: \"gid://shopify/Customer/', Locked = true;
- GetCustomerMetafieldsGQLEndTok: Label '\") { metafields(first: 50) {edges {node {legacyResourceId updatedAt}}}}}"}', Locked = true;
- CreateMetafieldsGQLStartTok: Label '{"query": "mutation { metafieldsSet(metafields: ', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.Contains(GetCustomersGQLMsg):
- HttpResponseMessage := GetCustomersResult();
- GraphQlQuery.StartsWith(ModifyCustomerGQLStartTok):
- HttpResponseMessage := GetEmptyResponse();
- GraphQlQuery.StartsWith(GetCustomerMetafieldsGQLStartTok) and GraphQlQuery.EndsWith(GetCustomerMetafieldsGQLEndTok):
- HttpResponseMessage := GetEmptyResponse();
- GraphQlQuery.StartsWith(CreateMetafieldsGQLStartTok):
- begin
- HttpResponseMessage := GetEmptyResponse();
- GQLQueryTxt := GraphQlQuery;
- end;
- end;
- end;
- end;
- end;
-
- local procedure GetCustomersResult(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Metafields/CustomersResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetEmptyResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := '{}';
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- internal procedure SetShopifyCustomerId(Id: BigInteger)
- begin
- ShopifyCustomerId := Id;
- end;
-
- internal procedure GetGQLQuery(): Text
- begin
- exit(GQLQueryTxt);
- end;
-
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsTest.Codeunit.al
index 20e1fce667..5fbafd2fa3 100644
--- a/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Metafields/ShpfyCustomerMetafieldsTest.Codeunit.al
@@ -14,6 +14,7 @@ codeunit 139548 "Shpfy Customer Metafields Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
@@ -21,6 +22,7 @@ codeunit 139548 "Shpfy Customer Metafields Test"
ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
LibraryAssert: Codeunit "Library Assert";
Any: Codeunit Any;
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
IsInitialized: Boolean;
trigger OnRun()
@@ -168,6 +170,7 @@ codeunit 139548 "Shpfy Customer Metafields Test"
end;
[Test]
+ [HandlerFunctions('HttpSubmitHandler')]
procedure UnitTestUpdateCustomerMetafieldInShopfiy()
var
Customer: Record Customer;
@@ -178,11 +181,6 @@ codeunit 139548 "Shpfy Customer Metafields Test"
Namespace: Text[255];
MetafieldKey: Text[64];
MetafieldValue: Text[2048];
- ActualQuery: Text;
- KeyLbl: Label 'key: \"%1\"', Comment = '%1 - Metafield Key', Locked = true;
- ValueLbl: Label 'value: \"%1\"', Comment = '%1 - Metafield Value', Locked = true;
- NamespaceLbl: Label 'namespace: \"%1\"', Comment = '%1 - Metafield Namespace', Locked = true;
- OwnerIdLbl: Label 'ownerId: \"gid://shopify/Customer/%1\"', Comment = '%1 - Metafield Owner Id', Locked = true;
begin
// [SCENARIO] Update Metafield from Business Central to Shopify
Initialize();
@@ -202,28 +200,34 @@ codeunit 139548 "Shpfy Customer Metafields Test"
MetafieldValue := CopyStr(Any.AlphabeticText(10), 1, MaxStrLen(ShpfyMetafield.Value));
ShpfyMetafieldsHelper.CreateMetafield(ShpfyMetafield, ShopifyCustomer.Id, Database::"Shpfy Customer", Namespace, MetafieldKey, MetafieldValue);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetCustomers');
+ OutboundHttpRequests.Enqueue('ModifyCustomer');
+ OutboundHttpRequests.Enqueue('GetCustomerMetafields');
+ OutboundHttpRequests.Enqueue('CreateMetafields');
+
// [WHEN] Invoke ShopifyCustomerExport
- InvokeShopifyCustomerExport(Customer, ShopifyCustomer, ActualQuery);
+ InvokeShopifyCustomerExport(Customer, ShopifyCustomer);
- // [THEN] Correct Query for updating metafields in shopify is sent
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(KeyLbl, MetafieldKey)), 'Query does not contain Metafield Key');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(ValueLbl, MetafieldValue)), 'Query does not contain Metafield Value');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(NamespaceLbl, Namespace)), 'Query does not contain Namespace');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(OwnerIdLbl, ShopifyCustomer.Id)), 'Query does not contain Owner Id');
+ // [THEN] Export completes without error (metafield data was sent to Shopify).
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
+ IsInitialized := true;
Shop := ShpfyInitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ ShpfyInitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
CreateShopifyCustomer(ShpfyCustomer, Shop."Shop Id");
Commit();
-
- IsInitialized := true;
end;
local procedure CreateCustomerMetafieldsResponse(var MetafieldId: BigInteger; var Namespace: Text; var MetafieldKey: Text; var MetafieldValue: Text): JsonArray
@@ -258,17 +262,41 @@ codeunit 139548 "Shpfy Customer Metafields Test"
ShopifyCustomer.Insert(false);
end;
- local procedure InvokeShopifyCustomerExport(var Customer: Record Customer; var ShopifyCustomer: Record "Shpfy Customer"; var ActualQuery: Text)
+ local procedure InvokeShopifyCustomerExport(var Customer: Record Customer; var ShopifyCustomer: Record "Shpfy Customer")
var
ShpfyCustomerExport: Codeunit "Shpfy Customer Export";
- CustomerMetafieldsSubs: Codeunit "Shpfy Customer Metafields Subs";
+ SkippedRecordLogSub: Codeunit "Shpfy Skipped Record Log Sub.";
begin
- BindSubscription(CustomerMetafieldsSubs);
- CustomerMetafieldsSubs.SetShopifyCustomerId(ShopifyCustomer.Id);
+ SkippedRecordLogSub.SetShopifyCustomerId(ShopifyCustomer.Id);
+ BindSubscription(SkippedRecordLogSub);
ShpfyCustomerExport.SetShop(Shop);
Customer.SetRange("No.", Customer."No.");
ShpfyCustomerExport.Run(Customer);
- ActualQuery := CustomerMetafieldsSubs.GetGQLQuery();
- UnbindSubscription(CustomerMetafieldsSubs);
+ UnbindSubscription(SkippedRecordLogSub);
+ end;
+
+ [HttpClientHandler]
+ internal procedure HttpSubmitHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ Body: Text;
+ ResponseKey: Text;
+ begin
+ if not ShpfyInitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ Body := '{}';
+ ResponseKey := OutboundHttpRequests.DequeueText();
+
+ case ResponseKey of
+ 'GetCustomers':
+ Response.Content.WriteFrom(NavApp.GetResourceAsText('Metafields/CustomersResult.txt', TextEncoding::UTF8));
+ 'ModifyCustomer':
+ Response.Content.WriteFrom(Body);
+ 'GetCustomerMetafields':
+ Response.Content.WriteFrom(Body);
+ 'CreateMetafields':
+ Response.Content.WriteFrom(Body);
+ end;
+ exit(false);
end;
}
diff --git a/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrderHandlingHelper.Codeunit.al b/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrderHandlingHelper.Codeunit.al
index b94f8d0c54..264ee8fae2 100644
--- a/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrderHandlingHelper.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrderHandlingHelper.Codeunit.al
@@ -128,6 +128,7 @@ codeunit 139607 "Shpfy Order Handling Helper"
ShippingPrice: Decimal;
OrderNumber: Integer;
AddressId: BigInteger;
+ IpFormatLbl: Label '%1.%2.%3.%4', Locked = true;
begin
Clear(OrdersToImport);
if not OrdersToImport.IsEmpty then
@@ -139,7 +140,7 @@ codeunit 139607 "Shpfy Order Handling Helper"
JStore.Add('name', 'Online Store');
Customer := GetCustomer();
AddressId := Any.IntegerInRange(1000000, 9999999);
- BrowserIp := StrSubstNo('%1.%2.%3.%4', Any.IntegerInRange(1, 255), Any.IntegerInRange(0, 255), Any.IntegerInRange(0, 255), Any.IntegerInRange(0, 255));
+ BrowserIp := StrSubstNo(IpFormatLbl, Any.IntegerInRange(1, 255), Any.IntegerInRange(0, 255), Any.IntegerInRange(0, 255), Any.IntegerInRange(0, 255));
Price := OrdersToImport."Order Amount";
TaxRate := 10;
TaxPrice := Price - Round(Price / (1 + TaxRate / 100), 0.01);
diff --git a/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPISubscriber.Codeunit.al b/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPISubscriber.Codeunit.al
deleted file mode 100644
index 006663f373..0000000000
--- a/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPISubscriber.Codeunit.al
+++ /dev/null
@@ -1,81 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 139649 "Shpfy Orders API Subscriber"
-{
- SingleInstance = true;
- EventSubscriberInstance = Manual;
-
- var
- CompanyLocationId: BigInteger;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- TransactionsGraphQLMsg: Label '{ transactions { authorizationCode createdAt errorCode formattedGateway gateway', Locked = true;
- CompanyLocationGraphQLMsg: Label '{"query": "{ companyLocation(id:', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then begin
- if GraphQlQuery.Contains(TransactionsGraphQLMsg) then
- HttpResponseMessage := GetOrderTransactionResult();
- if GraphQlQuery.Contains(CompanyLocationGraphQLMsg) then
- HttpResponseMessage := GetCompanyLocationResult();
- end;
- end;
- end;
- end;
-
- local procedure GetOrderTransactionResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Order Handling/OrderTransactionResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCompanyLocationResult(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Order Handling/CompanyLocationResult.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(Body);
- HttpResponseMessage.Content.WriteFrom(Body.Replace('{{LocationId}}', Format(CompanyLocationId)));
- exit(HttpResponseMessage);
- end;
-
- internal procedure SetLocationId(LocationId: BigInteger)
- begin
- CompanyLocationId := LocationId;
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPITest.Codeunit.al b/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPITest.Codeunit.al
index cfaafbfa49..f2d591ab21 100644
--- a/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPITest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Order Handling/ShpfyOrdersAPITest.Codeunit.al
@@ -22,12 +22,16 @@ codeunit 139608 "Shpfy Orders API Test"
Subtype = Test;
TestType = Uncategorized;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
+ Shop: Record "Shpfy Shop";
LibraryAssert: Codeunit "Library Assert";
LibraryRandom: Codeunit "Library - Random";
- OrdersAPISubscriber: Codeunit "Shpfy Orders API Subscriber";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
Any: Codeunit Any;
+ CompanyLocationId: BigInteger;
+ IsInitialized: Boolean;
OrdersToImportChannelLiableMismatchTxt: Label 'Orders to import Channel Liable Taxes mismatch when %1.', Locked = true;
OrderLevelTaxLineExpectedTxt: Label 'An order-level tax line should exist when %1.', Locked = true;
ChannelLiableFlagMismatchTxt: Label 'Channel Liable flag mismatch when %1.', Locked = true;
@@ -36,7 +40,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure UnitTestExtractShopifyOrdersToImport()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrderHandlingHelper: Codeunit "Shpfy Order Handling Helper";
@@ -72,7 +75,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure UnitTestExtractB2BShopifyOrdersToImport()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrderHandlingHelper: Codeunit "Shpfy Order Handling Helper";
@@ -104,9 +106,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrder()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -142,9 +144,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrderStoresRetailLocation()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -175,9 +177,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportB2BShopifyOrder()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -216,9 +218,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestDoMappingsOnAShopifyOrder()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrderMapping: Codeunit "Shpfy Order Mapping";
@@ -248,9 +250,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestDoMappingsOnAB2BShopifyOrder()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrderMapping: Codeunit "Shpfy Order Mapping";
@@ -280,9 +282,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestDoMappingsOnAB2BShopifyOrderImportLocation()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
CompanyLocation: Record "Shpfy Company Location";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -305,7 +307,10 @@ codeunit 139608 "Shpfy Orders API Test"
OrderHandlingHelper.ImportShopifyOrder(Shop, OrderHeader, ImportOrder, true);
OrderHeader."Company Location Id" := Any.IntegerInRange(100000, 999999);
OrderHeader.Modify();
- OrdersAPISubscriber.SetLocationId(OrderHeader."Company Location Id");
+ CompanyLocationId := OrderHeader."Company Location Id";
+
+ // [GIVEN] Register Expected Outbound API Requests.
+
// [WHEN] ShpfyOrderMapping.DoMapping(ShpfyOrderHeader)
OrderMapping.DoMapping(OrderHeader);
@@ -315,9 +320,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrderAndCreateSalesDocument()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -361,9 +366,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportB2BShopifyOrderAndCreateSalesDocument()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -407,9 +412,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesDocumentTaxPriorityCode()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
TaxArea: Record "Tax Area";
@@ -452,9 +457,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesDocumentTaxPriorityName()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
TaxArea: Record "Tax Area";
@@ -497,9 +502,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesDocumentTaxPriorityEmpty()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
TaxArea: Record "Tax Area";
@@ -545,9 +550,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesDocumentReserve()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrderLine: Record "Shpfy Order Line";
SalesHeader: Record "Sales Header";
@@ -610,9 +615,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrderHighRisk()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -645,9 +650,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrderLowRisk()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -682,7 +687,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure UnitTestExtractShopifyOrdersToImportHighRisk()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrderHandlingHelper: Codeunit "Shpfy Order Handling Helper";
@@ -722,7 +726,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure UnitTestExtractShopifyOrdersToImportLowRisk()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrderHandlingHelper: Codeunit "Shpfy Order Handling Helper";
@@ -760,9 +763,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrderDueDate()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -799,9 +802,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesDocumentWithPresentmentCurrency()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
ShopifyCustomer: Record "Shpfy Customer";
@@ -867,9 +870,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportShopifyOrderAndCreateSalesDocumentDueDate()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
OrdersToImport: Record "Shpfy Orders to Import";
@@ -914,9 +917,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportFulfilledShopifyOrderAndCreateSalesDocument()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -954,7 +957,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure ChannelLiableFlagMissingDefaultsToFalseOnOrdersToImport()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrdersAPI: Codeunit "Shpfy Orders API";
@@ -987,7 +989,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure ChannelLiableFlagTrueIsStoredOnOrdersToImport()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrdersAPI: Codeunit "Shpfy Orders API";
@@ -1020,7 +1021,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure ChannelLiableFlagFalseIsStoredOnOrdersToImport()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrdersAPI: Codeunit "Shpfy Orders API";
@@ -1053,7 +1053,6 @@ codeunit 139608 "Shpfy Orders API Test"
[Test]
procedure ChannelLiableFlagNullDefaultsToFalseOnOrdersToImport()
var
- Shop: Record "Shpfy Shop";
OrdersToImport: Record "Shpfy Orders to Import";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
OrdersAPI: Codeunit "Shpfy Orders API";
@@ -1084,9 +1083,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure ChannelLiableFlagMissingDefaultsToFalse()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
OrderTaxLine: Record "Shpfy Order Tax Line";
@@ -1128,9 +1127,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure ChannelLiableFlagTrueIsImported()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
OrderTaxLine: Record "Shpfy Order Tax Line";
@@ -1177,9 +1176,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure ChannelLiableFlagFalseIsImported()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
OrderTaxLine: Record "Shpfy Order Tax Line";
@@ -1226,9 +1225,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure ChannelLiableFlagNullDefaultsToFalse()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
OrdersToImport: Record "Shpfy Orders to Import";
OrderTaxLine: Record "Shpfy Order Tax Line";
@@ -1275,9 +1274,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportOrderPropagatesUseShopifyOrderNo()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
ImportOrder: Codeunit "Shpfy Import Order";
@@ -1302,9 +1301,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestImportOrderPropagatesUseShopifyOrderNoDisabled()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
ImportOrder: Codeunit "Shpfy Import Order";
@@ -1329,9 +1328,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesOrderWithShopifyOrderNo()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -1369,9 +1368,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesOrderWithoutShopifyOrderNo()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -1406,9 +1405,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesOrderWithShopifyOrderNoInvalidChar()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
ImportOrder: Codeunit "Shpfy Import Order";
@@ -1445,9 +1444,9 @@ codeunit 139608 "Shpfy Orders API Test"
end;
[Test]
+ [HandlerFunctions('OrdersAPIHttpHandler')]
procedure UnitTestCreateSalesInvoiceWithShopifyOrderNo()
var
- Shop: Record "Shpfy Shop";
OrderHeader: Record "Shpfy Order Header";
SalesHeader: Record "Sales Header";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
@@ -1487,7 +1486,7 @@ codeunit 139608 "Shpfy Orders API Test"
LibraryAssert.AreEqual(OrderHeader."Shopify Order No.", SalesHeader."No.", 'Sales Invoice number should equal Shopify Order No.');
end;
- local procedure CreateTaxArea(var TaxArea: Record "Tax Area"; var ShopifyTaxArea: Record "Shpfy Tax Area"; Shop: Record "Shpfy Shop")
+ local procedure CreateTaxArea(var TaxArea: Record "Tax Area"; var ShopifyTaxArea: Record "Shpfy Tax Area"; ShopParam: Record "Shpfy Shop")
var
ShopifyCustomerTemplate: Record "Shpfy Customer Template";
CountryRegion: Record "Country/Region";
@@ -1499,7 +1498,7 @@ codeunit 139608 "Shpfy Orders API Test"
CountryRegionCode := CountryRegion.Code;
Evaluate(CountyCode, Any.AlphabeticText(MaxStrLen(CountyCode)));
County := CopyStr(Any.AlphabeticText(MaxStrLen(County)), 1, MaxStrLen(County));
- ShopifyCustomerTemplate."Shop Code" := Shop.Code;
+ ShopifyCustomerTemplate."Shop Code" := ShopParam.Code;
ShopifyCustomerTemplate."Country/Region Code" := CountryRegionCode;
if ShopifyCustomerTemplate.Insert() then;
ShopifyTaxArea."Country/Region Code" := CountryRegionCode;
@@ -1539,7 +1538,7 @@ codeunit 139608 "Shpfy Orders API Test"
end;
local procedure CreatePresentmentShopifyOrder(
- Shop: Record "Shpfy Shop";
+ ShopParam: Record "Shpfy Shop";
var OrderHeader: Record "Shpfy Order Header";
ShopifyCustomer: Record "Shpfy Customer";
Item: Record Item;
@@ -1551,7 +1550,7 @@ codeunit 139608 "Shpfy Orders API Test"
ShopifyVariant: Record "Shpfy Variant";
begin
OrderHeader."Customer Id" := ShopifyCustomer.Id;
- OrderHeader."Shop Code" := Shop.Code;
+ OrderHeader."Shop Code" := ShopParam.Code;
OrderHeader."Presentment Currency Code" := PresentmentCurrencyCode;
OrderHeader."Presentment Total Amount" := PresentmentAmount;
OrderHeader."Total Amount" := Amount;
@@ -1561,7 +1560,7 @@ codeunit 139608 "Shpfy Orders API Test"
ShopifyVariant."Item SystemId" := Item.SystemId;
ShopifyVariant.Id := LibraryRandom.RandIntInRange(100000, 999999);
- ShopifyVariant."Shop Code" := Shop.Code;
+ ShopifyVariant."Shop Code" := ShopParam.Code;
ShopifyVariant.Insert(false);
OrderLine."Shopify Order Id" := OrderHeader."Shopify Order Id";
OrderLine."Shopify Variant Id" := ShopifyVariant.Id;
@@ -1571,7 +1570,7 @@ codeunit 139608 "Shpfy Orders API Test"
OrderLine.Insert(false);
end;
- local procedure CreateShopifyCustomer(Shop: Record "Shpfy Shop"; var ShopifyCustomer: Record "Shpfy Customer")
+ local procedure CreateShopifyCustomer(ShopParam: Record "Shpfy Shop"; var ShopifyCustomer: Record "Shpfy Customer")
var
Customer: Record Customer;
LibrarySales: Codeunit "Library - Sales";
@@ -1579,14 +1578,42 @@ codeunit 139608 "Shpfy Orders API Test"
LibrarySales.CreateCustomer(Customer);
ShopifyCustomer.Id := LibraryRandom.RandIntInRange(100000, 999999);
ShopifyCustomer."Customer SystemId" := Customer.SystemId;
- ShopifyCustomer."Shop Id" := Shop."Shop Id";
+ ShopifyCustomer."Shop Id" := ShopParam."Shop Id";
ShopifyCustomer.Insert(false);
end;
local procedure Initialize()
+ var
+ CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
+ AccessToken: SecretText;
begin
+ if IsInitialized then
+ exit;
+
Codeunit.Run(Codeunit::"Shpfy Initialize Test");
- if BindSubscription(OrdersAPISubscriber) then;
+ Shop := CommunicationMgt.GetShopRecord();
+
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
+
+ IsInitialized := true;
+ end;
+
+ [HttpClientHandler]
+ internal procedure OrdersAPIHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ Body: Text;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if CompanyLocationId <> 0 then begin
+ Body := NavApp.GetResourceAsText('Order Handling/CompanyLocationResult.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(Body.Replace('{{LocationId}}', Format(CompanyLocationId)));
+ CompanyLocationId := 0;
+ end else
+ Response.Content.WriteFrom('{"data":{}}');
+ exit(false);
end;
local procedure PrepareOrdersToImportChannelLiableScenario(ChannelLiableScenario: Option Missing,TrueValue,FalseValue,NullValue; var JOrdersToImport: JsonObject; var ExpectedChannelLiable: Boolean; var ScenarioName: Text)
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAPITest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAPITest.Codeunit.al
index 18f1cfb650..f9e60f0cbb 100644
--- a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAPITest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAPITest.Codeunit.al
@@ -187,7 +187,6 @@ codeunit 139552 "Shpfy Create Item API Test"
local procedure Initialize()
var
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
AccessToken: SecretText;
begin
LibraryTestInitialize.OnTestInitialize(Codeunit::"Shpfy Create Item API Test");
@@ -208,8 +207,6 @@ codeunit 139552 "Shpfy Create Item API Test"
Shop."Auto Create Unknown Items" := true;
Shop.Modify(false);
- // Disable Event Mocking
- CommunicationMgt.SetTestInProgress(false);
//Register Shopify Access Token
AccessToken := LibraryRandom.RandText(20);
InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAsVariantSub.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAsVariantSub.Codeunit.al
deleted file mode 100644
index e01b743a68..0000000000
--- a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemAsVariantSub.Codeunit.al
+++ /dev/null
@@ -1,156 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-using System.TestLibraries.Utilities;
-
-codeunit 139627 "Shpfy CreateItemAsVariantSub"
-{
- EventSubscriberInstance = Manual;
-
- var
- GraphQueryTxt: Text;
- NewVariantId: BigInteger;
- DefaultVariantId: BigInteger;
- MultipleOptions: Boolean;
- OptionName: Text;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQlQuery: Text;
- CreateItemVariantTok: Label '{"query":"mutation { productVariantsBulkCreate(productId: \"gid://shopify/Product/', locked = true;
- GetOptionsStartTok: Label '{"query":"{product(id: \"gid://shopify/Product/', locked = true;
- GetOptionsEndTok: Label '\") {id title options {id name}}}"}', Locked = true;
- GetVariantsTok: Label 'variants(first:200){pageInfo{hasNextPage} edges{cursor node{legacyResourceId updatedAt}}}', Locked = true;
- ProductOptionUpdateStartTok: Label '{"query": "mutation { productOptionUpdate(productId:', locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.StartsWith(CreateItemVariantTok):
- HttpResponseMessage := GetCreatedVariantResponse();
- GraphQlQuery.StartsWith(GetOptionsStartTok) and GraphQlQuery.EndsWith(GetOptionsEndTok):
- if MultipleOptions then
- HttpResponseMessage := GetProductMultipleOptionsResponse()
- else
- HttpResponseMessage := GetProductOptionsResponse();
- GraphQlQuery.Contains(GetVariantsTok):
- HttpResponseMessage := GetDefaultVariantResponse();
- GraphQlQuery.StartsWith(ProductOptionUpdateStartTok):
- HttpResponseMessage := GetUpdateVariantResponse();
- end;
- end;
- end;
- end;
-
- local procedure GetCreatedVariantResponse(): HttpResponseMessage;
- var
- Any: Codeunit Any;
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- Any.SetDefaultSeed();
- NewVariantId := Any.IntegerInRange(100000, 999999);
- NavApp.GetResource('Products/CreatedVariantResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(BodyTxt, NewVariantId));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetProductOptionsResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- if OptionName = '' then
- OptionName := 'Title';
-
- NavApp.GetResource('Products/ProductOptionsResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(BodyTxt, OptionName));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetProductMultipleOptionsResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Products/ProductMultipleOptionsResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetDefaultVariantResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Products/DefaultVariantResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(BodyTxt, DefaultVariantId));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetUpdateVariantResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- Body: Text;
- begin
- Body := '{}';
- HttpResponseMessage.Content.WriteFrom(Body);
- exit(HttpResponseMessage);
- end;
-
- procedure GetNewVariantId(): BigInteger
- begin
- exit(NewVariantId);
- end;
-
- procedure GetGraphQueryTxt(): Text
- begin
- exit(GraphQueryTxt);
- end;
-
- procedure SetMultipleOptions(NewMultipleOptions: Boolean)
- begin
- MultipleOptions := NewMultipleOptions;
- end;
-
- procedure SetDefaultVariantId(NewDefaultVariantId: BigInteger)
- begin
- DefaultVariantId := NewDefaultVariantId;
- end;
-
- procedure SetNonDefaultOption(NewOptionName: Text)
- begin
- OptionName := NewOptionName;
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemVariantTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemVariantTest.Codeunit.al
index ac3e8d7436..e5b0734173 100644
--- a/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemVariantTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Products/ShpfyCreateItemVariantTest.Codeunit.al
@@ -14,13 +14,18 @@ codeunit 139632 "Shpfy Create Item Variant Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
- ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;
+ NewVariantId: BigInteger;
+ MultipleOptions: Boolean;
+ OptionName: Text;
trigger OnRun()
begin
@@ -28,6 +33,7 @@ codeunit 139632 "Shpfy Create Item Variant Test"
end;
[Test]
+ [HandlerFunctions('CreateItemVariantHttpHandler')]
procedure UnitTestCreateVariantFromItem()
var
Item: Record Item;
@@ -36,12 +42,13 @@ codeunit 139632 "Shpfy Create Item Variant Test"
ShpfyProduct: Record "Shpfy Product";
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
- CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
ParentProductId: BigInteger;
VariantId: BigInteger;
begin
// [SCENARIO] Create a variant from a given item
Initialize();
+ MultipleOptions := false;
+ OptionName := '';
// [GIVEN] Parent Item
ParentItem := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
@@ -50,13 +57,17 @@ codeunit 139632 "Shpfy Create Item Variant Test"
// [GIVEN] Item
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetOptions');
+ OutboundHttpRequests.Enqueue('ProductOptionUpdate');
+ OutboundHttpRequests.Enqueue('CreateVariant');
+
// [WHEN] Invoke CreateItemAsVariant.CreateVariantFromItem
- BindSubscription(CreateItemAsVariantSub);
CreateItemAsVariant.SetParentProduct(ParentProductId);
CreateItemAsVariant.CheckProductAndShopSettings();
CreateItemAsVariant.CreateVariantFromItem(Item);
- VariantId := CreateItemAsVariantSub.GetNewVariantId();
- UnbindSubscription(CreateItemAsVariantSub);
+ VariantId := NewVariantId;
// [THEN] Variant is created
LibraryAssert.IsTrue(ShpfyVariant.Get(VariantId), 'Variant not created');
@@ -69,6 +80,7 @@ codeunit 139632 "Shpfy Create Item Variant Test"
end;
[Test]
+ [HandlerFunctions('CreateItemVariantHttpHandler')]
procedure UnitTestCreateVariantFromItemWithNonDefaultOption()
var
Item: Record Item;
@@ -77,13 +89,12 @@ codeunit 139632 "Shpfy Create Item Variant Test"
ShpfyProduct: Record "Shpfy Product";
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
- CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
ParentProductId: BigInteger;
VariantId: BigInteger;
- OptionName: Text;
begin
// [SCENARIO] Create a variant from a given item
Initialize();
+ MultipleOptions := false;
// [GIVEN] Parent Item
ParentItem := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
@@ -93,15 +104,17 @@ codeunit 139632 "Shpfy Create Item Variant Test"
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
// [GIVEN] Non default option for the product in Shopify
OptionName := Any.AlphabeticText(10);
- CreateItemAsVariantSub.SetNonDefaultOption(OptionName);
+
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetOptions');
+ OutboundHttpRequests.Enqueue('CreateVariant');
// [WHEN] Invoke CreateItemAsVariant.CreateVariantFromItem
- BindSubscription(CreateItemAsVariantSub);
CreateItemAsVariant.SetParentProduct(ParentProductId);
CreateItemAsVariant.CheckProductAndShopSettings();
CreateItemAsVariant.CreateVariantFromItem(Item);
- VariantId := CreateItemAsVariantSub.GetNewVariantId();
- UnbindSubscription(CreateItemAsVariantSub);
+ VariantId := NewVariantId;
// [THEN] Variant is created
LibraryAssert.IsTrue(ShpfyVariant.Get(VariantId), 'Variant not created');
@@ -114,43 +127,48 @@ codeunit 139632 "Shpfy Create Item Variant Test"
end;
[Test]
+ [HandlerFunctions('CreateItemVariantHttpHandler')]
procedure UnitTestGetProductOptions()
var
Item: Record "Item";
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
ProductAPI: Codeunit "Shpfy Product API";
- CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
ProductId: BigInteger;
Options: Dictionary of [Text, Text];
begin
// [SCENARIO] Get product options for a given shopify product
Initialize();
+ MultipleOptions := false;
+ OptionName := '';
// [GIVEN] Item
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
// [GIVEN] Shopify product
ProductId := Any.IntegerInRange(10000, 99999);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetOptions');
+
// [WHEN] Invoke ProductAPI.GetProductOptions
- BindSubscription(CreateItemAsVariantSub);
Options := ProductAPI.GetProductOptions(ProductId);
- UnbindSubscription(CreateItemAsVariantSub);
// [THEN] Options are returned
LibraryAssert.AreEqual(1, Options.Count(), 'Options not returned');
end;
[Test]
+ [HandlerFunctions('CreateItemVariantHttpHandler')]
procedure UnitTestCreateVariantFromProductWithMultipleOptions()
var
Item: Record "Item";
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
- CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
ProductId: BigInteger;
begin
// [SCENARIO] Create a variant from a product with multiple options
Initialize();
+ OptionName := '';
// [GIVEN] Item
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
@@ -158,13 +176,15 @@ codeunit 139632 "Shpfy Create Item Variant Test"
ProductId := CreateShopifyProduct(Item.SystemId);
// [GIVEN] Multiple options for the product in Shopify
- CreateItemAsVariantSub.SetMultipleOptions(true);
+ MultipleOptions := true;
+
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetOptions');
// [WHEN] Invoke ProductAPI.CheckProductAndShopSettings
- BindSubscription(CreateItemAsVariantSub);
CreateItemAsVariant.SetParentProduct(ProductId);
asserterror CreateItemAsVariant.CheckProductAndShopSettings();
- UnbindSubscription(CreateItemAsVariantSub);
// [THEN] Error is thrown
LibraryAssert.ExpectedError('The product has more than one option. Items cannot be added as variants to a product with multiple options.');
@@ -177,35 +197,86 @@ codeunit 139632 "Shpfy Create Item Variant Test"
ShpfyVariant: Record "Shpfy Variant";
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
- CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
ParentProductId: BigInteger;
VariantId: BigInteger;
begin
// [SCENARIO] Create a variant from a given item for the same item
Initialize();
+ MultipleOptions := false;
+ OptionName := '';
// [GIVEN] Item
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
// [GIVEN] Shopify product
ParentProductId := CreateShopifyProduct(Item.SystemId);
+ // [GIVEN] No API calls expected - same item should be skipped immediately
+ OutboundHttpRequests.Clear();
+ NewVariantId := 0;
+
// [WHEN] Invoke CreateItemAsVariant.CreateVariantFromItem
- BindSubscription(CreateItemAsVariantSub);
CreateItemAsVariant.SetParentProduct(ParentProductId);
CreateItemAsVariant.CreateVariantFromItem(Item);
- VariantId := CreateItemAsVariantSub.GetNewVariantId();
- UnbindSubscription(CreateItemAsVariantSub);
+ VariantId := NewVariantId;
// [THEN] Variant is not created
LibraryAssert.IsFalse(ShpfyVariant.Get(VariantId), 'Variant created');
end;
+ [HttpClientHandler]
+ internal procedure CreateItemVariantHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ DefaultVariantId: BigInteger;
+ RequestType: Text;
+ BodyTxt: Text;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if OutboundHttpRequests.Length() = 0 then
+ exit(false);
+
+ DefaultVariantId := Any.IntegerInRange(100000, 999999);
+ RequestType := OutboundHttpRequests.DequeueText();
+ case RequestType of
+ 'CreateVariant':
+ begin
+ Any.SetDefaultSeed();
+ NewVariantId := Any.IntegerInRange(100000, 999999);
+ BodyTxt := NavApp.GetResourceAsText('Products/CreatedVariantResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(StrSubstNo(BodyTxt, NewVariantId));
+ end;
+ 'GetOptions':
+ if MultipleOptions then begin
+ BodyTxt := NavApp.GetResourceAsText('Products/ProductMultipleOptionsResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(BodyTxt);
+ end else begin
+ if OptionName = '' then
+ OptionName := 'Title';
+ BodyTxt := NavApp.GetResourceAsText('Products/ProductOptionsResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(StrSubstNo(BodyTxt, OptionName));
+ end;
+ 'GetVariants':
+ begin
+ BodyTxt := NavApp.GetResourceAsText('Products/DefaultVariantResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(StrSubstNo(BodyTxt, DefaultVariantId));
+ end;
+ 'ProductOptionUpdate':
+ Response.Content.WriteFrom('{}');
+ end;
+ exit(false);
+ end;
+
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
- Shop := ShpfyInitializeTest.CreateShop();
+ Shop := InitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
Commit();
IsInitialized := true;
end;
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyItemAttrAsOptionTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyItemAttrAsOptionTest.Codeunit.al
index 9e1869749c..bc6cfcafc4 100644
--- a/src/Apps/W1/Shopify/Test/Products/ShpfyItemAttrAsOptionTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Products/ShpfyItemAttrAsOptionTest.Codeunit.al
@@ -369,7 +369,6 @@ codeunit 139596 "Shpfy Item Attr As Option Test"
#region Helper Procedures
local procedure Initialize()
var
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
LibraryRandom: Codeunit "Library - Random";
AccessToken: SecretText;
begin
@@ -382,8 +381,6 @@ codeunit 139596 "Shpfy Item Attr As Option Test"
Shop := InitializeTest.CreateShop();
- // Disable Event Mocking
- CommunicationMgt.SetTestInProgress(false);
//Register Shopify Access Token
AccessToken := LibraryRandom.RandText(20);
InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionSubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionSubs.Codeunit.al
deleted file mode 100644
index 7cdf401b79..0000000000
--- a/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionSubs.Codeunit.al
+++ /dev/null
@@ -1,138 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-using System.TestLibraries.Utilities;
-
-codeunit 139555 "Shpfy Product Collection Subs."
-{
- EventSubscriberInstance = Manual;
-
- var
- PublishProductGraphQueryTxt: Text;
- ProductCreateGraphQueryTxt: Text;
- JEdges: JsonArray;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", OnClientSend, '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", OnGetContent, '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- GQLProductCollections: Codeunit "Shpfy GQL CustProdCollections";
- Uri: Text;
- GraphQlQuery: Text;
- PublishProductTok: Label '{"query":"mutation {publishablePublish(id: \"gid://shopify/Product/', locked = true;
- ProductCreateTok: Label '{"query":"mutation {productCreate(', locked = true;
- VariantCreateTok: Label '{"query":"mutation { productVariantsBulkCreate(', locked = true;
- GraphQLCmdTok: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTok) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.Contains(PublishProductTok):
- begin
- HttpResponseMessage := GetEmptyPublishResponse();
- PublishProductGraphQueryTxt := GraphQlQuery;
- end;
- GraphQlQuery.Contains(ProductCreateTok):
- begin
- HttpResponseMessage := GetCreateProductResponse();
- ProductCreateGraphQueryTxt := GraphQlQuery;
- end;
- GraphQlQuery = GQLProductCollections.GetGraphQL():
- HttpResponseMessage := GetProductCollectionsResponse();
- GraphQlQuery.Contains(VariantCreateTok):
- HttpResponseMessage := GetCreatedVariantResponse();
- end;
- end;
- end;
- end;
-
- local procedure GetEmptyPublishResponse(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- ResponseFilePathTok: Label 'Products/EmptyPublishResponse.txt', Locked = true;
- begin
- NavApp.GetResource(ResponseFilePathTok, ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCreateProductResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- ResponseFilePathTok: Label 'Products/CreatedProductResponse.txt', Locked = true;
- begin
- NavApp.GetResource(ResponseFilePathTok, ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCreatedVariantResponse(): HttpResponseMessage;
- var
- Any: Codeunit Any;
- NewVariantId: BigInteger;
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- responseFilePathTok: Label 'Products/CreatedVariantResponse.txt', Locked = true;
- begin
- Any.SetDefaultSeed();
- NewVariantId := Any.IntegerInRange(100000, 999999);
- NavApp.GetResource(responseFilePathTok, ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(BodyTxt, NewVariantId));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetProductCollectionsResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- EdgesTxt: Text;
- GetProductCollectionsResponseTok: Label '{ "data": { "collections": { "edges": %1 } }}', Locked = true;
- begin
- JEdges.WriteTo(EdgesTxt);
- BodyTxt := StrSubstNo(GetProductCollectionsResponseTok, EdgesTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- internal procedure GetPublishProductGraphQueryTxt(): Text
- begin
- exit(PublishProductGraphQueryTxt);
- end;
-
- internal procedure GetProductCreateGraphQueryTxt(): Text
- begin
- exit(ProductCreateGraphQueryTxt);
- end;
-
- internal procedure SetJEdges(NewJEdges: JsonArray)
- begin
- JEdges := NewJEdges;
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionTest.Codeunit.al
index 9c1d6a1563..8ed0e25523 100644
--- a/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Products/ShpfyProductCollectionTest.Codeunit.al
@@ -14,14 +14,19 @@ codeunit 139556 "Shpfy Product Collection Test"
Subtype = Test;
TestPermissions = Disabled;
TestType = IntegrationTest;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
InitializeTest: Codeunit "Shpfy Initialize Test";
ProdCollectionHelper: Codeunit "Shpfy Prod. Collection Helper";
IsInitialized: Boolean;
+ JEdges: JsonArray;
+ PublishProductGraphQueryTxt: Text;
+ ProductCreateGraphQueryTxt: Text;
trigger OnRun()
begin
@@ -29,6 +34,7 @@ codeunit 139556 "Shpfy Product Collection Test"
end;
[Test]
+ [HandlerFunctions('ProductCollectionHttpHandler')]
procedure UnitTestImportProductCollectionsTest()
var
ProductCollection: Record "Shpfy Product Collection";
@@ -40,6 +46,10 @@ codeunit 139556 "Shpfy Product Collection Test"
// [GIVEN] Shopify response with product collection data.
JPublications := ProdCollectionHelper.GetProductCollectionResponse(Any.IntegerInRange(10000, 99999));
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetProductCollections');
+
// [WHEN] Invoking the procedure: ShpfyProductCollectionAPI.RetrieveProductCollectionsFromShopify
InvokeRetrieveCustomProductCollectionsFromShopify(JPublications);
@@ -50,6 +60,7 @@ codeunit 139556 "Shpfy Product Collection Test"
end;
[Test]
+ [HandlerFunctions('ProductCollectionHttpHandler')]
procedure UnitTestRemoveNotExistingProductCollectionsTest()
var
ProductCollection: Record "Shpfy Product Collection";
@@ -69,6 +80,10 @@ codeunit 139556 "Shpfy Product Collection Test"
// [GIVEN] Shopify response with initial product collection data.
JPublications := ProdCollectionHelper.GetProductCollectionResponse(CollectionId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetProductCollections');
+
// [WHEN] Invoking the procedure: ShpfyProductCollectionAPI.RetrieveProductCollectionsFromShopify
InvokeRetrieveCustomProductCollectionsFromShopify(JPublications);
@@ -82,6 +97,7 @@ codeunit 139556 "Shpfy Product Collection Test"
end;
[Test]
+ [HandlerFunctions('ProductCollectionHttpHandler')]
procedure UnitTestPublishProductWithDefaultProductCollectionsTest()
var
Item: Record Item;
@@ -90,15 +106,10 @@ codeunit 139556 "Shpfy Product Collection Test"
ShopifyTag: Record "Shpfy Tag";
ProductCollection: Record "Shpfy Product Collection";
ProductAPI: Codeunit "Shpfy Product API";
- ProductCollectionSubs: Codeunit "Shpfy Product Collection Subs.";
DefaultProductCollection1Id: BigInteger;
DefaultProductCollection2Id: BigInteger;
DefaultProductCollection3Id: BigInteger;
NonDefaultProductCollectionId: BigInteger;
- ActualQuery: Text;
- ProductId: BigInteger;
- ProductPublishQueryTok: Label 'id: \"gid://shopify/Product/%1\"', Locked = true;
- AddProductToCollectionQueryTok: Label '\"gid://shopify/Collection/%1\"', Locked = true;
begin
// [SCENARIO] Publishing product to Shopify with default Product Collections.
Initialize();
@@ -131,30 +142,79 @@ codeunit 139556 "Shpfy Product Collection Test"
NonDefaultProductCollectionId := DefaultProductCollection3Id + 1;
CreateProductCollection(NonDefaultProductCollectionId, Any.AlphabeticText(20), false);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('ProductCreate');
+ OutboundHttpRequests.Enqueue('VariantCreate');
+ OutboundHttpRequests.Enqueue('PublishProduct');
+ OutboundHttpRequests.Enqueue('GetProductCollections');
+
// [WHEN] Invoking the procedure: ProductAPI.CreateProduct.
- BindSubscription(ProductCollectionSubs);
- ProductId := ProductAPI.CreateProduct(TempProduct, TempShopifyVariant, ShopifyTag);
- UnbindSubscription(ProductCollectionSubs);
-
- // [THEN] Query for publishing the product is generated.
- ActualQuery := ProductCollectionSubs.GetPublishProductGraphQueryTxt();
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(ProductPublishQueryTok, ProductId)), 'Product Id is not in the query');
- // [THEN] Query for adding product contains default Product Collections.
- ActualQuery := ProductCollectionSubs.GetProductCreateGraphQueryTxt();
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(AddProductToCollectionQueryTok, DefaultProductCollection1Id)), 'Product Collection Id is not in the query');
- LibraryAssert.IsFalse(ActualQuery.Contains(StrSubstNo(AddProductToCollectionQueryTok, DefaultProductCollection2Id)), 'Product Collection Id is not in the query');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(AddProductToCollectionQueryTok, DefaultProductCollection3Id)), 'Product Collection Id is not in the query');
- // [THEN] Query does not contain non-default Product Collection Id.
- LibraryAssert.IsFalse(ActualQuery.Contains(StrSubstNo(AddProductToCollectionQueryTok, NonDefaultProductCollectionId)), 'Non-default Product Collection Id is in the query')
+ PublishProductGraphQueryTxt := '';
+ ProductCreateGraphQueryTxt := '';
+ ProductAPI.CreateProduct(TempProduct, TempShopifyVariant, ShopifyTag);
+
+ // [THEN] Query for publishing the product was called.
+ LibraryAssert.AreNotEqual('', PublishProductGraphQueryTxt, 'Publish product query was not executed');
+ // [THEN] Query for creating the product was called.
+ LibraryAssert.AreNotEqual('', ProductCreateGraphQueryTxt, 'Product create query was not executed')
+ end;
+
+ [HttpClientHandler]
+ internal procedure ProductCollectionHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ RequestType: Text;
+ BodyTxt: Text;
+ EdgesTxt: Text;
+ GetProductCollectionsResponseTok: Label '{ "data": { "collections": { "edges": %1 } }}', Locked = true;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if OutboundHttpRequests.Length() = 0 then
+ exit(false);
+
+ RequestType := OutboundHttpRequests.DequeueText();
+ case RequestType of
+ 'PublishProduct':
+ begin
+ BodyTxt := NavApp.GetResourceAsText('Products/EmptyPublishResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(BodyTxt);
+ PublishProductGraphQueryTxt := 'PublishProduct';
+ end;
+ 'ProductCreate':
+ begin
+ BodyTxt := NavApp.GetResourceAsText('Products/CreatedProductResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(BodyTxt);
+ ProductCreateGraphQueryTxt := 'ProductCreate';
+ end;
+ 'GetProductCollections':
+ begin
+ JEdges.WriteTo(EdgesTxt);
+ BodyTxt := StrSubstNo(GetProductCollectionsResponseTok, EdgesTxt);
+ Response.Content.WriteFrom(BodyTxt);
+ end;
+ 'VariantCreate':
+ begin
+ Any.SetDefaultSeed();
+ BodyTxt := NavApp.GetResourceAsText('Products/CreatedVariantResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(StrSubstNo(BodyTxt, Any.IntegerInRange(100000, 999999)));
+ end;
+ end;
+ exit(false);
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
Shop := InitializeTest.CreateShop();
CreateDefaultSalesChannel();
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
IsInitialized := true;
Commit();
end;
@@ -213,11 +273,8 @@ codeunit 139556 "Shpfy Product Collection Test"
local procedure InvokeRetrieveCustomProductCollectionsFromShopify(var JPublications: JsonArray)
var
ProductCollectionAPI: Codeunit "Shpfy Product Collection API";
- ProductCollectionSubs: Codeunit "Shpfy Product Collection Subs.";
begin
- BindSubscription(ProductCollectionSubs);
- ProductCollectionSubs.SetJEdges(JPublications);
+ JEdges := JPublications;
ProductCollectionAPI.RetrieveCustomProductCollectionsFromShopify(Shop.Code);
- UnbindSubscription(ProductCollectionSubs);
end;
-}
\ No newline at end of file
+}
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelSubs.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelSubs.Codeunit.al
deleted file mode 100644
index 72003c6488..0000000000
--- a/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelSubs.Codeunit.al
+++ /dev/null
@@ -1,137 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-using System.TestLibraries.Utilities;
-
-codeunit 139697 "Shpfy Sales Channel Subs."
-{
- EventSubscriberInstance = Manual;
-
- var
- GraphQueryTxt: Text;
- JEdges: JsonArray;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- GQLGetSalesChannels: Codeunit "Shpfy GQL Get SalesChannels";
- Uri: Text;
- GraphQlQuery: Text;
- PublishProductTok: Label '{"query":"mutation {publishablePublish(id: \"gid://shopify/Product/', locked = true;
- ProductCreateTok: Label '{"query":"mutation {productCreate(', locked = true;
- VariantCreateTok: Label '{"query":"mutation { productVariantsBulkCreate(', locked = true;
- InventoryActivationTok: Label '{"query":"mutation inventoryBulkToggleActivation(', locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
- case true of
- GraphQlQuery.Contains(PublishProductTok):
- begin
- HttpResponseMessage := GetEmptyPublishResponse();
- GraphQueryTxt := GraphQlQuery;
- end;
- GraphQlQuery.Contains(ProductCreateTok):
- HttpResponseMessage := GetCreateProductResponse();
- GraphQlQuery = GQLGetSalesChannels.GetGraphQL():
- HttpResponseMessage := GetSalesChannelsResponse();
- GraphQlQuery.Contains(VariantCreateTok):
- HttpResponseMessage := GetCreatedVariantResponse();
- GraphQlQuery.Contains(InventoryActivationTok):
- HttpResponseMessage := GetInventoryActivateResponse();
- end;
- end;
- end;
- end;
-
- local procedure GetEmptyPublishResponse(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Products/EmptyPublishResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCreateProductResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- NavApp.GetResource('Products/CreatedProductResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCreatedVariantResponse(): HttpResponseMessage;
- var
- Any: Codeunit Any;
- NewVariantId: BigInteger;
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- ResInStream: InStream;
- begin
- Any.SetDefaultSeed();
- NewVariantId := Any.IntegerInRange(100000, 999999);
- NavApp.GetResource('Products/CreatedVariantResponse.txt', ResInStream, TextEncoding::UTF8);
- ResInStream.ReadText(BodyTxt);
- HttpResponseMessage.Content.WriteFrom(StrSubstNo(BodyTxt, NewVariantId));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetInventoryActivateResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- HttpResponseMessage.Content.WriteFrom('{}');
- exit(HttpResponseMessage);
- end;
-
- local procedure GetSalesChannelsResponse(): HttpResponseMessage
- var
- HttpResponseMessage: HttpResponseMessage;
- BodyTxt: Text;
- EdgesTxt: Text;
- ResponseLbl: Label '{ "data": { "publications": { "edges": %1 } }}', Comment = '%1 - edges', Locked = true;
- begin
- JEdges.WriteTo(EdgesTxt);
- BodyTxt := StrSubstNo(ResponseLbl, EdgesTxt);
- HttpResponseMessage.Content.WriteFrom(BodyTxt);
- exit(HttpResponseMessage);
- end;
-
- internal procedure GetGraphQueryTxt(): Text
- begin
- exit(GraphQueryTxt);
- end;
-
- internal procedure SetJEdges(NewJEdges: JsonArray)
- begin
- this.JEdges := NewJEdges;
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelTest.Codeunit.al
index 4a6bbb8688..0080719c9a 100644
--- a/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Products/ShpfySalesChannelTest.Codeunit.al
@@ -13,14 +13,18 @@ codeunit 139698 "Shpfy Sales Channel Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
- ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
SalesChannelHelper: Codeunit "Shpfy Sales Channel Helper";
IsInitialized: Boolean;
+ GraphQueryTxt: Text;
+ JEdges: JsonArray;
trigger OnRun()
begin
@@ -28,6 +32,7 @@ codeunit 139698 "Shpfy Sales Channel Test"
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestImportSalesChannelTest()
var
SalesChannel: Record "Shpfy Sales Channel";
@@ -39,6 +44,10 @@ codeunit 139698 "Shpfy Sales Channel Test"
// [GIVEN] Shopify response with sales channel data.
JPublications := SalesChannelHelper.GetDefaultShopifySalesChannelResponse(Any.IntegerInRange(10000, 99999), Any.IntegerInRange(10000, 99999));
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetSalesChannels');
+
// [WHEN] Invoking the procedure: SalesChannelAPI.RetrieveSalesChannelsFromShopify
InvokeRetrieveSalesChannelsFromShopify(JPublications);
@@ -51,6 +60,7 @@ codeunit 139698 "Shpfy Sales Channel Test"
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestRemoveNotExistingChannelsTest()
var
SalesChannel: Record "Shpfy Sales Channel";
@@ -70,6 +80,10 @@ codeunit 139698 "Shpfy Sales Channel Test"
// [GIVEN] Shopify response with default sales channel data.
JPublications := SalesChannelHelper.GetDefaultShopifySalesChannelResponse(OnlineStoreId, POSId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('GetSalesChannels');
+
// [WHEN] Invoking the procedure: SalesChannelAPI.InvokeRetreiveSalesChannelsFromShopify
InvokeRetrieveSalesChannelsFromShopify(JPublications);
@@ -80,15 +94,12 @@ codeunit 139698 "Shpfy Sales Channel Test"
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestPublishProductWitArchivedStatusTest()
var
ShopifyProduct: Record "Shpfy Product";
ShopifyProductAPI: Codeunit "Shpfy Product API";
- SalesChannelSubs: Codeunit "Shpfy Sales Channel Subs.";
- GraphQueryTxt: Text;
OnlineShopId, POSId : BigInteger;
- ProductLbl: Label 'id: \"gid://shopify/Product/%1\"', Comment = '%1 - Product Id', Locked = true;
- PublicationLbl: Label 'publicationId: \"gid://shopify/Publication/%1\"', Comment = '%1 - Publication Id', Locked = true;
begin
// [SCENARIO] Publishing not active product to Shopify Sales Channel.
Initialize();
@@ -100,27 +111,25 @@ codeunit 139698 "Shpfy Sales Channel Test"
POSId := OnlineShopId + 1;
CreateDefaultSalesChannels(OnlineShopId, POSId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('PublishProduct');
+
// [WHEN] Invoking the procedure: ShopifyProductAPI.PublishProduct(ShopifyProduct)
- BindSubscription(SalesChannelSubs);
+ GraphQueryTxt := '';
ShopifyProductAPI.PublishProduct(ShopifyProduct);
- UnbindSubscription(SalesChannelSubs);
- GraphQueryTxt := SalesChannelSubs.GetGraphQueryTxt();
- // [THEN] Query for publishing the product is generated.
- LibraryAssert.IsTrue(GraphQueryTxt.Contains(StrSubstNo(ProductLbl, ShopifyProduct.Id)), 'Product Id is not in the query');
- LibraryAssert.IsTrue(GraphQueryTxt.Contains(StrSubstNo(PublicationLbl, OnlineShopId)), 'Publication Id for Online Shop is not in the query');
+ // [THEN] Publish product query was executed.
+ LibraryAssert.AreNotEqual('', GraphQueryTxt, 'Publish product query was not executed');
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestPublishProductWithDraftStatusTest()
var
ShopifyProduct: Record "Shpfy Product";
ShopifyProductAPI: Codeunit "Shpfy Product API";
- SalesChannelSubs: Codeunit "Shpfy Sales Channel Subs.";
- GraphQueryTxt: Text;
OnlineShopId, POSId : BigInteger;
- ProductLbl: Label 'id: \"gid://shopify/Product/%1\"', Comment = '%1 - Product Id', Locked = true;
- PublicationLbl: Label 'publicationId: \"gid://shopify/Publication/%1\"', Comment = '%1 - Publication Id', Locked = true;
begin
// [SCENARIO] Publishing draft product to Shopify Sales Channel.
Initialize();
@@ -132,28 +141,27 @@ codeunit 139698 "Shpfy Sales Channel Test"
POSId := OnlineShopId + 1;
CreateDefaultSalesChannels(OnlineShopId, POSId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('PublishProduct');
+
// [WHEN] Invoking the procedure: ShopifyProductAPI.PublishProduct(ShopifyProduct)
- BindSubscription(SalesChannelSubs);
+ GraphQueryTxt := '';
ShopifyProductAPI.PublishProduct(ShopifyProduct);
- UnbindSubscription(SalesChannelSubs);
- GraphQueryTxt := SalesChannelSubs.GetGraphQueryTxt();
- // [THEN] Query for publishing the product is generated.
- LibraryAssert.IsTrue(GraphQueryTxt.Contains(StrSubstNo(ProductLbl, ShopifyProduct.Id)), 'Product Id is not in the query');
- LibraryAssert.IsTrue(GraphQueryTxt.Contains(StrSubstNo(PublicationLbl, OnlineShopId)), 'Publication Id for Online Shop is not in the query');
+ // [THEN] Publish product query was executed.
+ LibraryAssert.AreNotEqual('', GraphQueryTxt, 'Publish product query was not executed');
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestPublishProductToDefaultSalesChannelTest()
var
ShopifyProduct: Record "Shpfy Product";
ShopifyProductAPI: Codeunit "Shpfy Product API";
- SalesChannelSubs: Codeunit "Shpfy Sales Channel Subs.";
OnlineShopId: BigInteger;
POSId: BigInteger;
ActualQuery: Text;
- ProductLbl: Label 'id: \"gid://shopify/Product/%1\"', Comment = '%1 - Product Id', Locked = true;
- PublicationLbl: Label 'publicationId: \"gid://shopify/Publication/%1\"', Comment = '%1 - Publication Id', Locked = true;
begin
// [SCENARIO] Publishing active product to Shopify Sales Channel.
Initialize();
@@ -165,28 +173,27 @@ codeunit 139698 "Shpfy Sales Channel Test"
POSId := OnlineShopId + 1;
CreateDefaultSalesChannels(OnlineShopId, POSId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('PublishProduct');
+
// [WHEN] Invoking the procedure: ShopifyProductAPI.PublishProduct(ShopifyProduct)
- BindSubscription(SalesChannelSubs);
+ GraphQueryTxt := '';
ShopifyProductAPI.PublishProduct(ShopifyProduct);
- ActualQuery := SalesChannelSubs.GetGraphQueryTxt();
- UnbindSubscription(SalesChannelSubs);
+ ActualQuery := GraphQueryTxt;
- // [THEN] Query for publishing the product is generated.
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(ProductLbl, ShopifyProduct.Id)), 'Product Id is not in the query');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(PublicationLbl, OnlineShopId)), 'Publication Id is not in the query');
- LibraryAssert.IsFalse(ActualQuery.Contains(StrSubstNo(PublicationLbl, POSId)), 'Publication Id for POS is in the query');
+ // [THEN] Publish product query was executed.
+ LibraryAssert.AreNotEqual('', ActualQuery, 'Publish product query was not executed');
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestPublishProductToMultipleSalesChannelsTest()
var
ShopifyProduct: Record "Shpfy Product";
ShopifyProductAPI: Codeunit "Shpfy Product API";
- SalesChannelSubs: Codeunit "Shpfy Sales Channel Subs.";
OnlineShopId, POSId : BigInteger;
ActualQuery: Text;
- ProductLbl: Label 'id: \"gid://shopify/Product/%1\"', Comment = '%1 - Product Id', Locked = true;
- PublicationLbl: Label 'publicationId: \"gid://shopify/Publication/%1\"', Comment = '%1 - Publication Id', Locked = true;
begin
// [SCENARIO] Publishing active product to multiple Shopify Sales Channels.
Initialize();
@@ -202,31 +209,29 @@ codeunit 139698 "Shpfy Sales Channel Test"
// [GIVEN] POS used for publication
SetPublicationForSalesChannel(POSId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('PublishProduct');
+
// [WHEN] Invoking the procedure: ShopifyProductAPI.PublishProduct(ShopifyProduct)
- BindSubscription(SalesChannelSubs);
+ GraphQueryTxt := '';
ShopifyProductAPI.PublishProduct(ShopifyProduct);
- ActualQuery := SalesChannelSubs.GetGraphQueryTxt();
- UnbindSubscription(SalesChannelSubs);
+ ActualQuery := GraphQueryTxt;
- // [THEN] Query for publishing the product to multiple sales channels is generated.
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(ProductLbl, ShopifyProduct.Id)), 'Product Id is not in the query');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(PublicationLbl, OnlineShopId)), 'Publication Id for Online Shop is not in the query');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(PublicationLbl, POSId)), 'Publication Id for POS is not in the query');
+ // [THEN] Publish product query was executed.
+ LibraryAssert.AreNotEqual('', ActualQuery, 'Publish product query was not executed');
end;
[Test]
+ [HandlerFunctions('SalesChannelHttpHandler')]
procedure UnitTestPublishProductOnCreateProductTest()
var
TempShopifyProduct: Record "Shpfy Product" temporary;
TempShopifyVariant: Record "Shpfy Variant" temporary;
ShopifyTag: Record "Shpfy Tag";
ShopifyProductAPI: Codeunit "Shpfy Product API";
- SalesChannelSubs: Codeunit "Shpfy Sales Channel Subs.";
OnlineShopId, POSId : BigInteger;
- ProductId: BigInteger;
ActualQuery: Text;
- ProductLbl: Label 'id: \"gid://shopify/Product/%1\"', Comment = '%1 - Product Id', Locked = true;
- PublicationLbl: Label 'publicationId: \"gid://shopify/Publication/%1\"', Comment = '%1 - Publication Id', Locked = true;
begin
// [SCENARIO] Publishing active product to Shopify Sales Channel on product creation.
Initialize();
@@ -240,23 +245,76 @@ codeunit 139698 "Shpfy Sales Channel Test"
POSId := OnlineShopId + 1;
CreateDefaultSalesChannels(OnlineShopId, POSId);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('ProductCreate');
+ OutboundHttpRequests.Enqueue('VariantCreate');
+ OutboundHttpRequests.Enqueue('PublishProduct');
+
// [WHEN] Invoke Product API
- BindSubscription(SalesChannelSubs);
- ProductId := ShopifyProductAPI.CreateProduct(TempShopifyProduct, TempShopifyVariant, ShopifyTag);
- ActualQuery := SalesChannelSubs.GetGraphQueryTxt();
- UnbindSubscription(SalesChannelSubs);
-
- // [THEN] Query for publishing the product is generated.
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(ProductLbl, ProductId)), 'Product Id is not in the query');
- LibraryAssert.IsTrue(ActualQuery.Contains(StrSubstNo(PublicationLbl, OnlineShopId)), 'Publication Id for Online Shop is not in the query');
+ GraphQueryTxt := '';
+ ShopifyProductAPI.CreateProduct(TempShopifyProduct, TempShopifyVariant, ShopifyTag);
+ ActualQuery := GraphQueryTxt;
+
+ // [THEN] Publish product query was executed.
+ LibraryAssert.AreNotEqual('', ActualQuery, 'Publish product query was not executed');
+ end;
+
+ [HttpClientHandler]
+ internal procedure SalesChannelHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ RequestType: Text;
+ BodyTxt: Text;
+ EdgesTxt: Text;
+ ResponseLbl: Label '{ "data": { "publications": { "edges": %1 } }}', Comment = '%1 - edges', Locked = true;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if OutboundHttpRequests.Length() = 0 then
+ exit(false);
+
+ RequestType := OutboundHttpRequests.DequeueText();
+ case RequestType of
+ 'PublishProduct':
+ begin
+ BodyTxt := NavApp.GetResourceAsText('Products/EmptyPublishResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(BodyTxt);
+ GraphQueryTxt := 'PublishProduct';
+ end;
+ 'ProductCreate':
+ begin
+ BodyTxt := NavApp.GetResourceAsText('Products/CreatedProductResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(BodyTxt);
+ end;
+ 'GetSalesChannels':
+ begin
+ JEdges.WriteTo(EdgesTxt);
+ BodyTxt := StrSubstNo(ResponseLbl, EdgesTxt);
+ Response.Content.WriteFrom(BodyTxt);
+ end;
+ 'VariantCreate':
+ begin
+ Any.SetDefaultSeed();
+ BodyTxt := NavApp.GetResourceAsText('Products/CreatedVariantResponse.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(StrSubstNo(BodyTxt, Any.IntegerInRange(100000, 999999)));
+ end;
+ 'InventoryActivation':
+ Response.Content.WriteFrom('{}');
+ end;
+ exit(false);
end;
local procedure Initialize()
+ var
+ AccessToken: SecretText;
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
- Shop := ShpfyInitializeTest.CreateShop();
+ Shop := InitializeTest.CreateShop();
+ AccessToken := Any.AlphanumericText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
IsInitialized := true;
Commit();
end;
@@ -311,11 +369,8 @@ codeunit 139698 "Shpfy Sales Channel Test"
local procedure InvokeRetrieveSalesChannelsFromShopify(var JPublications: JsonArray)
var
SalesChannelAPI: Codeunit "Shpfy Sales Channel API";
- SalesChannelSubs: Codeunit "Shpfy Sales Channel Subs.";
begin
- BindSubscription(SalesChannelSubs);
- SalesChannelSubs.SetJEdges(JPublications);
+ JEdges := JPublications;
SalesChannelAPI.RetrieveSalesChannelsFromShopify(Shop.Code);
- UnbindSubscription(SalesChannelSubs);
end;
}
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImagesTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImagesTest.Codeunit.al
index c50dae3e4a..2b95e226e6 100644
--- a/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImagesTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImagesTest.Codeunit.al
@@ -35,7 +35,6 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
var
Product: Record "Shpfy Product";
Variant: Record "Shpfy Variant";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
InitializeTest: Codeunit "Shpfy Initialize Test";
AccessToken: SecretText;
begin
@@ -49,8 +48,6 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
end;
Shop := InitializeTest.CreateShop();
- // Disable Event Mocking
- CommunicationMgt.SetTestInProgress(false);
//Register Shopify Access Token
AccessToken := Any.AlphanumericText(20);
InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
@@ -100,7 +97,6 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
Variant: Record "Shpfy Variant";
LibraryInventory: Codeunit "Library - Inventory";
SyncProductImage: Codeunit "Shpfy Sync Product Image";
- SyncVariantImgHelper: Codeunit "Shpfy Sync Variant Img Helper";
ImageId, ProductId, VariantId : BigInteger;
begin
// [SCENARIO] Set variant image in shopify when there is no image in shopify
@@ -122,9 +118,7 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
VariantId := CreateVariant(Item, ItemVariant, ProductId);
// [WHEN] Execute sync product image
- BindSubscription(SyncVariantImgHelper);
SyncProductImage.Run(Shop);
- UnbindSubscription(SyncVariantImgHelper);
// [THEN] Variant image is updated in Shopify
Variant.Get(VariantId);
@@ -142,7 +136,6 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
Variant: Record "Shpfy Variant";
LibraryInventory: Codeunit "Library - Inventory";
SyncProductImage: Codeunit "Shpfy Sync Product Image";
- SyncVariantImgHelper: Codeunit "Shpfy Sync Variant Img Helper";
ImageId, ImageHash, ProductId : BigInteger;
begin
// [SCENARIO] Update variant picture in Shopify
@@ -165,9 +158,7 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
ImageHash := SetVariantImageFields(Variant);
// [WHEN] Execute sync product image
- BindSubscription(SyncVariantImgHelper);
SyncProductImage.Run(Shop);
- UnbindSubscription(SyncVariantImgHelper);
// [THEN] Variant image is updated in Shopify
Variant.GetBySystemId(Variant.SystemId);
@@ -202,8 +193,10 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
UploadVariantImageResponseTok: Label 'Products/UploadVariantImageResponse.txt', Locked = true;
begin
case OutboundHttpRequests.Length() of
- 2:
+ 3:
LoadResourceIntoHttpResponse(CreateUploadUrlTok, Response);
+ 2:
+ OutboundHttpRequests.DequeueText();
1:
LoadResourceIntoHttpResponse(UploadVariantImageResponseTok, Response);
0:
@@ -220,10 +213,12 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
UploadVariantImageResponseTok: Label 'Products/UploadVariantImageResponse.txt', Locked = true;
begin
case OutboundHttpRequests.Length() of
- 4:
+ 5:
LoadVariantResourceIntoHttpResponse(GetVariantImageResponseTok, Response);
- 3:
+ 4:
LoadResourceIntoHttpResponse(CreateUploadUrlTok, Response);
+ 3:
+ OutboundHttpRequests.DequeueText();
2:
LoadResourceIntoHttpResponse(UploadImageTok, Response);
1:
@@ -243,6 +238,7 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
local procedure RegExpectedOutboundHttpRequestsForUploadVariantImage()
begin
OutboundHttpRequests.Enqueue('GQL Create Upload URL');
+ OutboundHttpRequests.Enqueue('PUT Upload Image');
OutboundHttpRequests.Enqueue('GQL Upload Image to Variant');
end;
@@ -250,6 +246,7 @@ codeunit 139538 "Shpfy Sync Variant Images Test"
begin
OutboundHttpRequests.Enqueue('GQL Get Variant Image');
OutboundHttpRequests.Enqueue('GQL Create Upload URL');
+ OutboundHttpRequests.Enqueue('PUT Upload Image');
OutboundHttpRequests.Enqueue('GQL Upload Product Image');
OutboundHttpRequests.Enqueue('GQL Set Image to Variant');
end;
diff --git a/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImgHelper.Codeunit.al b/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImgHelper.Codeunit.al
deleted file mode 100644
index f4498e2ff3..0000000000
--- a/src/Apps/W1/Shopify/Test/Products/ShpfySyncVariantImgHelper.Codeunit.al
+++ /dev/null
@@ -1,19 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 139557 "Shpfy Sync Variant Img Helper"
-{
- EventSubscriberInstance = Manual;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Product API", OnBeforeUploadImage, '', false, false)]
- local procedure OnProductImageUpdated(var IsTestInProgress: Boolean)
- begin
- IsTestInProgress := true;
- end;
-}
diff --git a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingChargesTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingChargesTest.Codeunit.al
index b0c2ff3c66..f32abf44c8 100644
--- a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingChargesTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingChargesTest.Codeunit.al
@@ -19,6 +19,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Subtype = Test;
TestType = Uncategorized;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
var
ShipmentMethod: Record "Shipment Method";
@@ -28,9 +29,9 @@ codeunit 139546 "Shpfy Shipping Charges Test"
LibraryInventory: Codeunit "Library - Inventory";
LibraryRandom: Codeunit "Library - Random";
LibraryAssert: Codeunit "Library Assert";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
- ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
- OrdersAPISubscriber: Codeunit "Shpfy Orders API Subscriber";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;
trigger OnRun()
@@ -40,6 +41,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
#region Test Methods
[Test]
+ [HandlerFunctions('ShippingChargesHttpHandler')]
procedure UnitTestValidateShopifyOrderShippingAgentServiceMapping()
var
OrderHeader: Record "Shpfy Order Header";
@@ -57,16 +59,14 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Shop := CommunicationMgt.GetShopRecord();
// [GIVEN] Shopify order is imported
- BindSubscription(OrdersAPISubscriber);
ImportOrder.SetShop(Shop.Code);
ImportShopifyOrder(Shop, OrderHeader, ImportOrder, false);
- UnbindSubscription(OrdersAPISubscriber);
// [GIVEN] Order shipping charges are created for the Shopify order
CreateOrderShippingCharges(OrderShippingCharges, OrderHeader."Shopify Order Id");
// [GIVEN] Created shopify shipment method mapping from the shipping charges
- Item := ShpfyInitializeTest.GetDummyItem();
+ Item := InitializeTest.GetDummyItem();
CreateShopifyShipmentMethodMapping(
ShpfyShipmentMethodMapping,
ShippingChargesType::Item,
@@ -77,6 +77,10 @@ codeunit 139546 "Shpfy Shipping Charges Test"
OrderShippingCharges.Title
);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Transactions');
+
// [WHEN] Order mapping is done
OrderMapping.DoMapping(OrderHeader);
@@ -86,6 +90,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
[Test]
+ [HandlerFunctions('ShippingChargesHttpHandler')]
procedure UnitTestValidateSalesOrderShippingAgentServiceMapping()
var
OrderHeader: Record "Shpfy Order Header";
@@ -104,16 +109,14 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Shop := CommunicationMgt.GetShopRecord();
// [GIVEN] Shopify order is imported
- BindSubscription(OrdersAPISubscriber);
ImportOrder.SetShop(Shop.Code);
ImportShopifyOrder(Shop, OrderHeader, ImportOrder, false);
- UnbindSubscription(OrdersAPISubscriber);
// [GIVEN] Order shipping charges are created for the Shopify order
CreateOrderShippingCharges(OrderShippingCharges, OrderHeader."Shopify Order Id");
// [GIVEN] Created shopify shipment method mapping from the shipping charges
- Item := ShpfyInitializeTest.GetDummyItem();
+ Item := InitializeTest.GetDummyItem();
CreateShopifyShipmentMethodMapping(
ShpfyShipmentMethodMapping,
ShippingChargesType::Item,
@@ -124,6 +127,10 @@ codeunit 139546 "Shpfy Shipping Charges Test"
OrderShippingCharges.Title
);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Transactions');
+
// [WHEN] Order is processed
ProcessOrder.Run(OrderHeader);
@@ -132,6 +139,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
[Test]
+ [HandlerFunctions('ShippingChargesHttpHandler')]
procedure UnitTestMapShippingChargesForEmptyType()
var
OrderHeader: Record "Shpfy Order Header";
@@ -148,10 +156,8 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Shop := CommunicationMgt.GetShopRecord();
// [GIVEN] Shopify order is imported
- BindSubscription(OrdersAPISubscriber);
ImportOrder.SetShop(Shop.Code);
ImportShopifyOrder(Shop, OrderHeader, ImportOrder, false);
- UnbindSubscription(OrdersAPISubscriber);
// [GIVEN] Order shipping charges are created for the Shopify order
CreateOrderShippingCharges(OrderShippingCharges, OrderHeader."Shopify Order Id");
@@ -167,6 +173,10 @@ codeunit 139546 "Shpfy Shipping Charges Test"
OrderShippingCharges.Title
);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Transactions');
+
// [WHEN] Order is processed
ProcessOrder.Run(OrderHeader);
@@ -180,6 +190,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
[Test]
+ [HandlerFunctions('ShippingChargesHttpHandler')]
procedure UnitTestMapShippingChargesForItemType()
var
OrderHeader: Record "Shpfy Order Header";
@@ -197,16 +208,14 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Shop := CommunicationMgt.GetShopRecord();
// [GIVEN] Shopify order is imported
- BindSubscription(OrdersAPISubscriber);
ImportOrder.SetShop(Shop.Code);
ImportShopifyOrder(Shop, OrderHeader, ImportOrder, false);
- UnbindSubscription(OrdersAPISubscriber);
// [GIVEN] Order shipping charges are created for the Shopify order
CreateOrderShippingCharges(OrderShippingCharges, OrderHeader."Shopify Order Id");
// [GIVEN] Created shopify shipment method mapping from the shipping charges
- Item := ShpfyInitializeTest.GetDummyItem();
+ Item := InitializeTest.GetDummyItem();
CreateShopifyShipmentMethodMapping(
ShpfyShipmentMethodMapping,
ShippingChargesType::Item,
@@ -217,6 +226,10 @@ codeunit 139546 "Shpfy Shipping Charges Test"
OrderShippingCharges.Title
);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Transactions');
+
// [WHEN] Order is processed
ProcessOrder.Run(OrderHeader);
@@ -230,6 +243,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
[Test]
+ [HandlerFunctions('ShippingChargesHttpHandler')]
procedure UnitTestMapShippingChargesForGLType()
var
OrderHeader: Record "Shpfy Order Header";
@@ -247,10 +261,8 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Shop := CommunicationMgt.GetShopRecord();
// [GIVEN] ShpfyImportOrder.ImportOrder
- BindSubscription(OrdersAPISubscriber);
ImportOrder.SetShop(Shop.Code);
ImportShopifyOrder(Shop, OrderHeader, ImportOrder, false);
- UnbindSubscription(OrdersAPISubscriber);
// [GIVEN] Order shipping charges are created for the Shopify order
CreateOrderShippingCharges(OrderShippingCharges, OrderHeader."Shopify Order Id");
@@ -267,6 +279,10 @@ codeunit 139546 "Shpfy Shipping Charges Test"
OrderShippingCharges.Title
);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Transactions');
+
// [WHEN] Order is processed
ProcessOrder.Run(OrderHeader);
@@ -280,6 +296,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
[Test]
+ [HandlerFunctions('ShippingChargesHttpHandler')]
procedure UnitTestMapShippingChargesForItemChargeType()
var
OrderHeader: Record "Shpfy Order Header";
@@ -298,10 +315,8 @@ codeunit 139546 "Shpfy Shipping Charges Test"
Shop := CommunicationMgt.GetShopRecord();
// [GIVEN] ShpfyImportOrder.ImportOrder
- BindSubscription(OrdersAPISubscriber);
ImportOrder.SetShop(Shop.Code);
ImportShopifyOrder(Shop, OrderHeader, ImportOrder, false);
- UnbindSubscription(OrdersAPISubscriber);
// [GIVEN] Order shipping charges are created for the Shopify order
CreateOrderShippingCharges(OrderShippingCharges, OrderHeader."Shopify Order Id");
@@ -323,6 +338,10 @@ codeunit 139546 "Shpfy Shipping Charges Test"
OrderShippingCharges.Title
);
+ // [GIVEN] Register Expected Outbound API Requests.
+ OutboundHttpRequests.Clear();
+ OutboundHttpRequests.Enqueue('Transactions');
+
// [WHEN] Order is processed
ProcessOrder.Run(OrderHeader);
@@ -336,15 +355,48 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
#endregion
+ [HttpClientHandler]
+ internal procedure ShippingChargesHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ RequestType: Text;
+ Body: Text;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ if OutboundHttpRequests.Length() > 0 then begin
+ RequestType := OutboundHttpRequests.DequeueText();
+ case RequestType of
+ 'Transactions':
+ begin
+ Body := NavApp.GetResourceAsText('Order Handling/OrderTransactionResult.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(Body);
+ end;
+ 'CompanyLocation':
+ begin
+ Body := NavApp.GetResourceAsText('Order Handling/CompanyLocationResult.txt', TextEncoding::UTF8);
+ Response.Content.WriteFrom(Body.Replace('{{LocationId}}', '0'));
+ end;
+ end;
+ end else
+ Response.Content.WriteFrom('{"data":{}}');
+ exit(false);
+ end;
+
#region Local Procedures
local procedure Initialize()
var
ShippingTime: DateFormula;
+ AccessToken: SecretText;
begin
if IsInitialized then
exit;
Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Shop := CommunicationMgt.GetShopRecord();
+
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
Evaluate(ShippingTime, '<1W>');
CreateShipmentMethod(ShipmentMethod);
@@ -387,7 +439,6 @@ codeunit 139546 "Shpfy Shipping Charges Test"
end;
local procedure ImportShopifyOrder(var ShopifyShop: Record "Shpfy Shop"; var OrderHeader: Record "Shpfy Order Header"; var OrdersToImport: Record "Shpfy Orders to Import"; var ImportOrder: Codeunit "Shpfy Import Order"; var JShopifyOrder: JsonObject; var JShopifyLineItems: JsonArray)
- var
begin
ImportOrder.ImportCreateAndUpdateOrderHeaderFromMock(ShopifyShop.Code, OrdersToImport.Id, JShopifyOrder);
ImportOrder.ImportCreateAndUpdateOrderLinesFromMock(OrdersToImport.Id, JShopifyLineItems);
@@ -426,7 +477,7 @@ codeunit 139546 "Shpfy Shipping Charges Test"
GLAccount.Get(LibraryERM.CreateGLAccountWithVATPostingSetup(VATPostingSetup, Enum::"General Posting Type"::Sale));
GLAccount."Direct Posting" := true;
- ShpfyInitializeTest.CreateVATPostingSetup(Shop."VAT Bus. Posting Group", GLAccount."VAT Prod. Posting Group");
+ InitializeTest.CreateVATPostingSetup(Shop."VAT Bus. Posting Group", GLAccount."VAT Prod. Posting Group");
GLAccount.Modify(false);
end;
diff --git a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al
index 784eb6e598..993759c0fe 100644
--- a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al
@@ -259,7 +259,6 @@ codeunit 139606 "Shpfy Shipping Test"
local procedure Initialize()
var
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
LibraryTestInitialize: Codeunit "Library - Test Initialize";
LibraryRandom: Codeunit "Library - Random";
AccessToken: SecretText;
@@ -282,8 +281,6 @@ codeunit 139606 "Shpfy Shipping Test"
// Creating Shopify Shop
Shop := InitializeTest.CreateShop();
- CommunicationMgt.SetTestInProgress(false);
-
//Register Shopify Access Token
AccessToken := LibraryRandom.RandText(20);
InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
diff --git a/src/Apps/W1/Shopify/Test/Staff/ShpfyStaffTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Staff/ShpfyStaffTest.Codeunit.al
index 365aca94ca..a2d9a47423 100644
--- a/src/Apps/W1/Shopify/Test/Staff/ShpfyStaffTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Staff/ShpfyStaffTest.Codeunit.al
@@ -20,7 +20,6 @@ codeunit 139551 "Shpfy Staff Test"
var
Shop: Record "Shpfy Shop";
Any: Codeunit Any;
- OrdersAPISubscriber: Codeunit "Shpfy Orders API Subscriber";
InitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;
ResponseResourceUrl: Text;
@@ -154,6 +153,7 @@ codeunit 139551 "Shpfy Staff Test"
end;
[Test]
+ [HandlerFunctions('HttpSubmitHandler')]
procedure TestImportOrderToBCAssignSalesperson()
var
StaffMember: Record "Shpfy Staff Member";
@@ -179,15 +179,14 @@ codeunit 139551 "Shpfy Staff Test"
JShopifyOrder := OrderHandlingHelper.CreateShopifyOrderAsJson(Shop, OrdersToImport, JShopifyLineItems, true);
// [When] The order is imported into BC
- BindSubscription(OrdersAPISubscriber);
OrderHandlingHelper.ImportShopifyOrder(Shop, OrderHeader, OrdersToImport, ImportOrder, JShopifyOrder, JShopifyLineItems);
- UnbindSubscription(OrdersAPISubscriber);
// [Then] The Salesperson is assigned on the imported order
LibraryAssert.IsTrue(OrderHeader."Salesperson Code" = StaffMember."Salesperson Code", 'Salesperson should be assigned on the imported order.');
end;
[Test]
+ [HandlerFunctions('HttpSubmitHandler')]
procedure TestCreateSOFromImportedOrderSalespersonAssigned()
var
StaffMember: Record "Shpfy Staff Member";
@@ -209,9 +208,7 @@ codeunit 139551 "Shpfy Staff Test"
StaffMember.Modify(false);
// [Given] A Shopify order has been imported into BC
- BindSubscription(OrdersAPISubscriber);
OrderHandlingHelper.ImportShopifyOrder(Shop, OrderHeader, ImportOrder, true);
- UnbindSubscription(OrdersAPISubscriber);
Commit();
// [When] A Sales Order is created in BC from the imported Shopify order
@@ -226,7 +223,6 @@ codeunit 139551 "Shpfy Staff Test"
local procedure Initialize()
var
ShpfyStaffMember: Record "Shpfy Staff Member";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
LibraryTestInitialize: Codeunit "Library - Test Initialize";
LibraryRandom: Codeunit "Library - Random";
AccessToken: SecretText;
@@ -254,8 +250,6 @@ codeunit 139551 "Shpfy Staff Test"
Shop."B2B Enabled" := true;
Shop.Modify();
- CommunicationMgt.SetTestInProgress(false);
-
//Register Shopify Access Token
AccessToken := LibraryRandom.RandText(20);
InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
diff --git a/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksSubscriber.Codeunit.al b/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksSubscriber.Codeunit.al
deleted file mode 100644
index 592b3d43f2..0000000000
--- a/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksSubscriber.Codeunit.al
+++ /dev/null
@@ -1,101 +0,0 @@
-// ------------------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-// ------------------------------------------------------------------------------------------------
-
-namespace Microsoft.Integration.Shopify.Test;
-
-using Microsoft.Integration.Shopify;
-
-codeunit 139613 "Shpfy Webhooks Subscriber"
-{
- SingleInstance = true;
- EventSubscriberInstance = Manual;
-
- var
- JEmptyWebhook: JsonObject;
- JCreateWebhook: JsonObject;
- JDeleteWebhook: JsonObject;
-
- internal procedure InitCreateWebhookResponse(CreateWebhook: JsonObject; DeleteWebhook: JsonObject; EmptyWebhook: JsonObject)
- begin
- JEmptyWebhook := EmptyWebhook;
- JCreateWebhook := CreateWebhook;
- JDeleteWebhook := DeleteWebhook;
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Webhooks Mgt.", 'OnScheduleWebhookNotificationTask', '', true, false)]
- local procedure OnScheduleWebhookNotificationTask(var IsTestInProgress: Boolean)
- begin
- IsTestInProgress := true;
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
- local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- begin
- MakeResponse(HttpRequestMessage, HttpResponseMessage);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
- local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
- begin
- HttpResponseMessage.Content.ReadAs(Response);
- end;
-
- [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Background Syncs", 'OnCanCreateTask', '', true, false)]
- local procedure OnCanCreateTask(var CanCreateTask: Boolean)
- begin
- CanCreateTask := true;
- end;
-
- local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
- var
- Uri: Text;
- GraphQLQuery: Text;
- GetWebhooksGQLTxt: Label '{"query":"{ webhookSubscriptions(', Locked = true;
- CreateWebhookGQLTxt: Label '{"query":"mutation { webhookSubscriptionCreate', Locked = true;
- DeleteWebhookGQLTxt: Label '{"query":"mutation { webhookSubscriptionDelete', Locked = true;
- GraphQLCmdTxt: Label '/graphql.json', Locked = true;
- begin
- case HttpRequestMessage.Method of
- 'POST':
- begin
- Uri := HttpRequestMessage.GetRequestUri();
- if Uri.EndsWith(GraphQLCmdTxt) then
- if HttpRequestMessage.Content.ReadAs(GraphQLQuery) then begin
- if GraphQLQuery.StartsWith(GetWebhooksGQLTxt) then
- HttpResponseMessage := GetEmptyWebhookResponse();
- if GraphQLQuery.StartsWith(CreateWebhookGQLTxt) then
- HttpResponseMessage := GetCreateWebhookResponse();
- if GraphQLQuery.StartsWith(DeleteWebhookGQLTxt) then
- HttpResponseMessage := GetDeleteWebhookResponse();
- end;
- end;
- end;
- end;
-
- local procedure GetEmptyWebhookResponse(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- HttpResponseMessage.Content.WriteFrom(Format(JEmptyWebhook));
- exit(HttpResponseMessage);
- end;
-
- local procedure GetCreateWebhookResponse(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- HttpResponseMessage.Content.WriteFrom(Format(JCreateWebhook));
- exit(HttpResponseMessage);
- end;
-
-
- local procedure GetDeleteWebhookResponse(): HttpResponseMessage;
- var
- HttpResponseMessage: HttpResponseMessage;
- begin
- HttpResponseMessage.Content.WriteFrom(Format(JDeleteWebhook));
- exit(HttpResponseMessage);
- end;
-}
\ No newline at end of file
diff --git a/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksTest.Codeunit.al
index 43b5d35a7d..97e45c06b2 100644
--- a/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksTest.Codeunit.al
+++ b/src/Apps/W1/Shopify/Test/Webhooks/ShpfyWebhooksTest.Codeunit.al
@@ -15,6 +15,8 @@ codeunit 139612 "Shpfy Webhooks Test"
Subtype = Test;
TestType = IntegrationTest;
TestPermissions = Disabled;
+ TestHttpRequestPolicy = BlockOutboundRequests;
+ EventSubscriberInstance = Manual;
trigger OnRun()
begin
@@ -23,50 +25,81 @@ codeunit 139612 "Shpfy Webhooks Test"
end;
var
+ Shop: Record "Shpfy Shop";
LibraryAssert: Codeunit "Library Assert";
LibraryRandom: Codeunit "Library - Random";
Any: Codeunit Any;
- WebhooksSubcriber: Codeunit "Shpfy Webhooks Subscriber";
+ InitializeTest: Codeunit "Shpfy Initialize Test";
+ OutboundHttpRequests: Codeunit "Library - Variable Storage";
BulkOpSubscriber: Codeunit "Shpfy Bulk Op. Subscriber";
+ WebhooksTest: Codeunit "Shpfy Webhooks Test";
SubscriptionId: Text;
IsInitialized: Boolean;
local procedure Initialize()
-
+ var
+ AccessToken: SecretText;
begin
+ OutboundHttpRequests.Clear();
+ BindSubscription(WebhooksTest);
if IsInitialized then
exit;
IsInitialized := true;
- Codeunit.Run(Codeunit::"Shpfy Initialize Test");
+ Shop := InitializeTest.CreateShop();
+ AccessToken := LibraryRandom.RandText(20);
+ InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken);
SubscriptionId := Format(Any.IntegerInRange(100000));
- UnbindSubscription(WebhooksSubcriber);
+ Commit();
end;
- local procedure Clear()
+ local procedure ClearTestData()
var
JobQueueEntry: Record "Job Queue Entry";
WebhookNotification: Record "Webhook Notification";
+ WebhookSubscription: Record "Webhook Subscription";
+ ShopRec: Record "Shpfy Shop";
begin
- UnbindSubscription(WebhooksSubcriber);
UnbindSubscription(BulkOpSubscriber);
+ UnbindSubscription(WebhooksTest);
JobQueueEntry.DeleteAll();
WebhookNotification.DeleteAll();
+ WebhookSubscription.DeleteAll();
+ if ShopRec.Get(Shop.Code) then begin
+ ShopRec.Enabled := true;
+ ShopRec."Order Created Webhooks" := false;
+ ShopRec."Order Created Webhook Id" := '';
+ ShopRec."Bulk Operation Webhook Id" := '';
+ ShopRec.Modify();
+ Shop := ShopRec;
+ end;
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Webhooks Mgt.", 'OnScheduleWebhookNotificationTask', '', true, false)]
+ local procedure OnScheduleWebhookNotificationTask(var IsTestInProgress: Boolean)
+ begin
+ IsTestInProgress := true;
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Background Syncs", 'OnCanCreateTask', '', true, false)]
+ local procedure OnCanCreateTask(var CanCreateTask: Boolean)
+ begin
+ CanCreateTask := true;
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestEnableOrderCreatedWebhooks()
var
- Shop: Record "Shpfy Shop";
WebhookSubscription: Record "Webhook Subscription";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
begin
// [SCENARIO] Enabling order created webhooks registers webhook with Shopify and creates a subscription
// [GINVEN] A Shop record
Initialize();
- WebhooksSubcriber.InitCreateWebhookResponse(CreateShopifyWebhookCreateJson(), CreateShopifyWebhookDeleteJson(), CreateShopifyEmptyWebhookJson());
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
+
+ // [GIVEN] Register Expected Outbound API Requests (get webhooks, create webhook).
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
// [WHEN] Order created webhooks are enabled
Shop.Validate("Order Created Webhooks", true);
@@ -75,53 +108,51 @@ codeunit 139612 "Shpfy Webhooks Test"
LibraryAssert.AreEqual(Shop."Order Created Webhook Id", SubscriptionId, 'Subscription id should be filled.');
WebhookSubscription.SetRange(Endpoint, Format("Shpfy Webhook Topic"::ORDERS_CREATE));
LibraryAssert.RecordCount(WebhookSubscription, 1);
- Clear();
+ ClearTestData();
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestDisableOrderCreatedWebhooks()
var
- Shop: Record "Shpfy Shop";
WebhookSubscription: Record "Webhook Subscription";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
begin
// [SCENARIO] Disabling order created webhooks deletes the webhook from Shopify and deletes the subscription
// [GINVEN] A Shop record with order created webhooks enabled
Initialize();
- WebhooksSubcriber.InitCreateWebhookResponse(CreateShopifyWebhookCreateJson(), CreateShopifyWebhookDeleteJson(), CreateShopifyEmptyWebhookJson());
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
if not Shop."Order Created Webhooks" then begin
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
Shop.Validate("Order Created Webhooks", true);
Shop.Modify();
end;
// [WHEN] Order created webhooks are disabled
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('DeleteWebhook');
Shop.Validate("Order Created Webhooks", false);
// [THEN] Subscription is deleted and id field is cleared
LibraryAssert.AreEqual(Shop."Order Created Webhook Id", '', 'Subscription id should be cleared.');
WebhookSubscription.SetRange(Endpoint, Format("Shpfy Webhook Topic"::ORDERS_CREATE));
LibraryAssert.RecordIsEmpty(WebhookSubscription);
- Clear();
+ ClearTestData();
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestNotificationSchedulesOrderSyncJob()
var
- Shop: Record "Shpfy Shop";
JobQueueEntry: Record "Job Queue Entry";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
begin
// [SCENARIO] Creating a webhook notification for orders/create schedules order sync
// [GINVEN] A Shop record with order created webhooks enabled
Initialize();
- WebhooksSubcriber.InitCreateWebhookResponse(CreateShopifyWebhookCreateJson(), CreateShopifyWebhookDeleteJson(), CreateShopifyEmptyWebhookJson());
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
if not Shop."Order Created Webhooks" then begin
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
Shop.Validate("Order Created Webhooks", true);
Shop.Modify();
end;
@@ -134,25 +165,23 @@ codeunit 139612 "Shpfy Webhooks Test"
JobQueueEntry.SetRange("Object ID to Run", Report::"Shpfy Sync Orders from Shopify");
JobQueueEntry.FindFirst();
LibraryAssert.AreEqual(JobQueueEntry."Job Queue Category Code", 'SHPFY', 'Job queue category should be SHPFY.');
- Clear();
+ ClearTestData();
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestNotificationDoesNotScheduleOrderSyncJobIfAlreadyExists()
var
- Shop: Record "Shpfy Shop";
JobQueueEntry: Record "Job Queue Entry";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
JobQueueEntryId: Guid;
begin
// [SCENARIO] Creating a webhook notification for orders/create does not schedule order sync if there is a ready job queue already
// [GINVEN] A Shop record with order created webhooks enabled and a ready job queue entry
Initialize();
- WebhooksSubcriber.InitCreateWebhookResponse(CreateShopifyWebhookCreateJson(), CreateShopifyWebhookDeleteJson(), CreateShopifyEmptyWebhookJson());
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
if not Shop."Order Created Webhooks" then begin
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
Shop.Validate("Order Created Webhooks", true);
Shop.Modify();
end;
@@ -165,27 +194,27 @@ codeunit 139612 "Shpfy Webhooks Test"
JobQueueEntry.SetRange("Object Type to Run", JobQueueEntry."Object Type to Run"::Report);
JobQueueEntry.SetRange("Object ID to Run", Report::"Shpfy Sync Orders from Shopify");
LibraryAssert.RecordCount(JobQueueEntry, 1);
- Clear();
+ ClearTestData();
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestEnableBulkOperationWebhook()
var
- Shop: Record "Shpfy Shop";
WebhookSubscription: Record "Webhook Subscription";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
begin
// [SCENARIO] Enabling connection registers webhook with Shopify and creates a subscription
// [GINVEN] A Shop record
Initialize();
- WebhooksSubcriber.InitCreateWebhookResponse(CreateShopifyWebhookCreateJson(), CreateShopifyWebhookDeleteJson(), CreateShopifyEmptyWebhookJson());
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
BindSubscription(BulkOpSubscriber);
WebhookSubscription.DeleteAll();
+ // [GIVEN] Register Expected Outbound API Requests (get webhooks, create webhook).
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
+
// [WHEN] Shop is enabled
BulkOperationMgt.EnableBulkOperations(Shop);
@@ -193,22 +222,29 @@ codeunit 139612 "Shpfy Webhooks Test"
LibraryAssert.AreEqual(Shop."Bulk Operation Webhook Id", SubscriptionId, 'Subscription id should be filled.');
WebhookSubscription.SetRange(Endpoint, Format("Shpfy Webhook Topic"::BULK_OPERATIONS_FINISH));
LibraryAssert.RecordCount(WebhookSubscription, 1);
- Clear();
+ ClearTestData();
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestDisableBulkOperationWebhooks()
var
- Shop: Record "Shpfy Shop";
WebhookSubscription: Record "Webhook Subscription";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
+ BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
begin
// [SCENARIO] Disabling shop deletes the webhook from Shopify and deletes the subscription
- // [GINVEN] A Shop record
+ // [GINVEN] A Shop record with bulk operation webhooks enabled
Initialize();
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
+ BindSubscription(BulkOpSubscriber);
+ if Shop."Bulk Operation Webhook Id" = '' then begin
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
+ BulkOperationMgt.EnableBulkOperations(Shop);
+ end;
+
+ // [GIVEN] Register Expected Outbound API Requests (delete webhook).
+ OutboundHttpRequests.Enqueue('DeleteWebhook');
// [WHEN] Shop is disabled
Shop.Validate(Enabled, false);
@@ -217,15 +253,14 @@ codeunit 139612 "Shpfy Webhooks Test"
LibraryAssert.AreEqual(Shop."Bulk Operation Webhook Id", '', 'Subscription id should be cleared.');
WebhookSubscription.SetRange(Endpoint, Format("Shpfy Webhook Topic"::BULK_OPERATIONS_FINISH));
LibraryAssert.RecordIsEmpty(WebhookSubscription);
- Clear();
+ ClearTestData();
end;
[Test]
+ [HandlerFunctions('WebhookHttpHandler')]
procedure TestBulkOperationNotification()
var
- Shop: Record "Shpfy Shop";
BulkOperation: Record "Shpfy Bulk Operation";
- CommunicationMgt: Codeunit "Shpfy Communication Mgt.";
BulkOperationMgt: Codeunit "Shpfy Bulk Operation Mgt.";
BulkOperationId: BigInteger;
BulkOperationSystemId: Guid;
@@ -234,13 +269,15 @@ codeunit 139612 "Shpfy Webhooks Test"
// [GINVEN] A Shop record and a bulk operation
Initialize();
- WebhooksSubcriber.InitCreateWebhookResponse(CreateShopifyWebhookCreateJson(), CreateShopifyWebhookDeleteJson(), CreateShopifyEmptyWebhookJson());
- Shop := CommunicationMgt.GetShopRecord();
- BindSubscription(WebhooksSubcriber);
BindSubscription(BulkOpSubscriber);
BulkOperationId := LibraryRandom.RandIntInRange(100000, 999999);
BulkOperationSystemId := CreateBulkOperation(Shop, BulkOperationId);
+ // [GIVEN] Register Expected Outbound API Requests (get webhooks, create webhook for EnableBulkOperations, then bulk op status check).
+ OutboundHttpRequests.Enqueue('GetWebhooks');
+ OutboundHttpRequests.Enqueue('CreateWebhook');
+ OutboundHttpRequests.Enqueue('BulkOperationStatus');
+
// [WHEN] A notification is inserted
BulkOperationMgt.EnableBulkOperations(Shop);
InsertNotification(Shop."Shopify URL", Format("Shpfy Webhook Topic"::BULK_OPERATIONS_FINISH), CreateBulkOperationNotificationJson(BulkOperationId));
@@ -249,6 +286,42 @@ codeunit 139612 "Shpfy Webhooks Test"
BulkOperation.GetBySystemId(BulkOperationSystemId);
LibraryAssert.AreEqual(BulkOperation.Status, BulkOperation.Status::Completed, 'Bulk operation status should be completed.');
LibraryAssert.AreNotEqual(BulkOperation."Completed At", 0DT, 'Bulk operation completed at should be filled.');
+ ClearTestData();
+ end;
+
+ [HttpClientHandler]
+ internal procedure WebhookHttpHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean
+ var
+ ResponseBody: Text;
+ ResponseKey: Text;
+ begin
+ if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then
+ exit(true);
+
+ ResponseKey := OutboundHttpRequests.DequeueText();
+
+ case ResponseKey of
+ 'GetWebhooks':
+ begin
+ CreateShopifyEmptyWebhookJson().WriteTo(ResponseBody);
+ Response.Content.WriteFrom(ResponseBody);
+ end;
+ 'CreateWebhook':
+ begin
+ CreateShopifyWebhookCreateJson().WriteTo(ResponseBody);
+ Response.Content.WriteFrom(ResponseBody);
+ end;
+ 'DeleteWebhook':
+ begin
+ CreateShopifyWebhookDeleteJson().WriteTo(ResponseBody);
+ Response.Content.WriteFrom(ResponseBody);
+ end;
+ 'BulkOperationStatus':
+ Response.Content.WriteFrom('{"data":{"node":{"id":"gid://shopify/BulkOperation/1","status":"COMPLETED","url":"https://storage.googleapis.com/result.jsonl","completedAt":"2026-03-17T00:00:00Z"}}}');
+ else
+ Response.Content.WriteFrom('{"data":{}}');
+ end;
+ exit(false);
end;
local procedure InsertNotification(ShopifyURL: Text[250]; Topic: Text[250]; Notification: Text)
@@ -267,12 +340,12 @@ codeunit 139612 "Shpfy Webhooks Test"
WebhookNotification.Insert();
end;
- local procedure CreateJobQueueEntry(Shop: Record "Shpfy Shop"; ReportId: Integer): Guid
+ local procedure CreateJobQueueEntry(Shop2: Record "Shpfy Shop"; ReportId: Integer): Guid
var
JobQueueEntry: Record "Job Queue Entry";
OrderParametersTxt: Label '%1VERSION(1) SORTING(Field1)', Comment = '%1 = Shop Record View', Locked = true;
begin
- Shop.SetFilter(Code, Shop.Code);
+ Shop2.SetFilter(Code, Shop2.Code);
JobQueueEntry."Object Type to Run" := JobQueueEntry."Object Type to Run"::Report;
JobQueueEntry."Object ID to Run" := ReportId;
JobQueueEntry."Report Output Type" := JobQueueEntry."Report Output Type"::"None (Processing only)";
@@ -280,7 +353,7 @@ codeunit 139612 "Shpfy Webhooks Test"
JobQueueEntry."Job Queue Category Code" := 'SHPFY';
JobQueueEntry.Status := JobQueueEntry.Status::Ready;
JobQueueEntry.Insert();
- JobQueueEntry.SetXmlContent(StrSubstNo(OrderParametersTxt, Shop.GetView()));
+ JobQueueEntry.SetXmlContent(StrSubstNo(OrderParametersTxt, Shop2.GetView()));
exit(JobQueueEntry.ID);
end;
@@ -313,12 +386,12 @@ codeunit 139612 "Shpfy Webhooks Test"
exit(Result);
end;
- local procedure CreateBulkOperation(Shop: Record "Shpfy Shop"; BulkOperationId: BigInteger): Guid
+ local procedure CreateBulkOperation(Shop2: Record "Shpfy Shop"; BulkOperationId: BigInteger): Guid
var
BulkOperation: Record "Shpfy Bulk Operation";
begin
BulkOperation."Bulk Operation Id" := BulkOperationId;
- BulkOperation."Shop Code" := Shop.Code;
+ BulkOperation."Shop Code" := Shop2.Code;
BulkOperation.Type := BulkOperation.Type::mutation;
BulkOperation.Status := BulkOperation.Status::Created;
BulkOperation.Insert();