Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Shopify] - Add Item As Variant Tests #4

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions Apps/W1/Shopify/test/Products/ShpfyCreateItemAsVariantSub.Codeunit.al
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
codeunit 139583 "Shpfy CreateItemAsVariantSub"
{
EventSubscriberInstance = Manual;

var
GraphQueryTxt: Text;
NewVariantId: BigInteger;
DefaultVariantId: BigInteger;
MultipleOptions: 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;
CreateItemVariantTok: Label '{"query":"mutation { productVariantCreate(input: {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;
RemoveVariantStartTok: Label '{"query":"mutation {productVariantDelete(id: \"gid://shopify/ProductVariant/', Locked = true;
RemoveVariantEndTok: Label '\") {deletedProductVariantId userErrors{field message}}}"}', Locked = true;
GetVariantsTok: Label 'variants(first:200){pageInfo{hasNextPage} edges{cursor node{legacyResourceId updatedAt}}}', 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.StartsWith(RemoveVariantStartTok) and GraphQlQuery.EndsWith(RemoveVariantEndTok):
begin
HttpResponseMessage := GetRemoveVariantResponse();
GraphQueryTxt := GraphQlQuery;
end;
GraphQlQuery.Contains(GetVariantsTok):
HttpResponseMessage := GetDefaultVariantResponse();
end;
end;
end;
end;

local procedure GetCreatedVariantResponse(): HttpResponseMessage;
var
Any: Codeunit Any;
HttpResponseMessage: HttpResponseMessage;
BodyTxt: Text;
begin
Any.SetDefaultSeed();
NewVariantId := Any.IntegerInRange(100000, 999999);
BodyTxt := StrSubstNo('{ "data": { "productVariantCreate": { "legacyResourceId": %1 } } }', NewVariantId);
HttpResponseMessage.Content.WriteFrom(BodyTxt);
exit(HttpResponseMessage);
end;

local procedure GetProductOptionsResponse(): HttpResponseMessage
var
HttpResponseMessage: HttpResponseMessage;
BodyTxt: Text;
begin
BodyTxt := '{"data": {"product": {"id": "gid://shopify/Product/123456", "title": "Product 1", "options": [{"id": "gid://shopify/ProductOption/1", "name": "Option 1"}]}}}';
HttpResponseMessage.Content.WriteFrom(BodyTxt);
exit(HttpResponseMessage);
end;

local procedure GetRemoveVariantResponse(): HttpResponseMessage
var
HttpResponseMessage: HttpResponseMessage;
BodyTxt: Text;
begin
BodyTxt := '{}';
HttpResponseMessage.Content.WriteFrom(BodyTxt);
exit(HttpResponseMessage);
end;

local procedure GetProductMultipleOptionsResponse(): HttpResponseMessage
var
HttpResponseMessage: HttpResponseMessage;
BodyTxt: Text;
begin
BodyTxt := '{"data": {"product": {"id": "gid://shopify/Product/123456", "title": "Product 1", "options": [{"id": "gid://shopify/ProductOption/1", "name": "Option 1"}, {"id": "gid://shopify/ProductOption/2", "name": "Option 2"}]}}}';
HttpResponseMessage.Content.WriteFrom(BodyTxt);
exit(HttpResponseMessage);
end;

local procedure GetDefaultVariantResponse(): HttpResponseMessage
var
HttpResponseMessage: HttpResponseMessage;
BodyTxt: Text;
begin
BodyTxt := StrSubstNo('{ "data" : { "product" : { "variants" : { "edges" : [ { "node" : { "legacyResourceId" : %1 } } ] } } } }', DefaultVariantId);
HttpResponseMessage.Content.WriteFrom(BodyTxt);
exit(HttpResponseMessage);
end;

procedure GetNewVariantId(): BigInteger
begin
exit(NewVariantId);
end;

procedure GetGraphQueryTxt(): Text
begin
exit(GraphQueryTxt);
end;

procedure SetMultipleOptions(NewMultipleOptions: Boolean)
begin
this.MultipleOptions := NewMultipleOptions;
end;

procedure SetDefaultVariantId(NewDefaultVariantId: BigInteger)
begin
this.DefaultVariantId := NewDefaultVariantId;
end;
}
206 changes: 206 additions & 0 deletions Apps/W1/Shopify/test/Products/ShpfyCreateItemVariantTest.Codeunit.al
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
codeunit 139581 "Shpfy Create Item Variant Test"
Copy link
Collaborator

@tinestaric tinestaric Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the agreement is on how thorough the tests should be. I see you're mainly doing unit tests on a level of a procedure. I'd also like to see a tests or two that handle the cases where Option > 1 and one for removing the default variant.

{
Subtype = Test;
TestPermissions = Disabled;

var
Shop: Record "Shpfy Shop";
Any: Codeunit Any;
LibraryAssert: Codeunit "Library Assert";
ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
IsInitialized: Boolean;

trigger OnRun()
begin
IsInitialized := false;
end;

[Test]
procedure UnitTestCreateVariantFromItem()
var
Item: Record "Item";
ShpfyVariant: Record "Shpfy Variant";
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();

// [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);

// [WHEN] Invoke CreateItemAsVariant.CreateVariantFromItem
BindSubscription(CreateItemAsVariantSub);
CreateItemAsVariant.SetParentProduct(ParentProductId);
CreateItemAsVariant.CreateVariantFromItem(Item);
VariantId := CreateItemAsVariantSub.GetNewVariantId();
UnbindSubscription(CreateItemAsVariantSub);

// [THEN] Variant is created
LibraryAssert.IsTrue(ShpfyVariant.Get(VariantId), 'Variant not created');
LibraryAssert.AreEqual(Item."No.", ShpfyVariant.Title, 'Title not set');
LibraryAssert.AreEqual(Item."No.", ShpfyVariant."Option 1 Value", 'Option 1 Value not set');
LibraryAssert.AreEqual('Variant', ShpfyVariant."Option 1 Name", 'Option 1 Name not set');
LibraryAssert.AreEqual(ParentProductId, ShpfyVariant."Product Id", 'Parent product not set');
LibraryAssert.IsTrue(ShpfyProduct.Get(ParentProductId), 'Parent product not found');
LibraryAssert.IsTrue(ShpfyProduct."Has Variants", 'Has Variants not set');
end;

[Test]
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();

// [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);

// [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]
procedure UnitTestDeleteProductVariant()
var
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
VariantAPI: Codeunit "Shpfy Variant API";
VariantId: BigInteger;
ActualQueryTxt: Text;
begin
// [SCENARIO] Delete a product variant
Initialize();

// [GIVEN] Shopify Variant Id
VariantId := Any.IntegerInRange(10000, 99999);

// [WHEN] Invoke ProductAPI.DeleteProductVariant
BindSubscription(CreateItemAsVariantSub);
VariantAPI.DeleteProductVariant(VariantId);
ActualQueryTxt := CreateItemAsVariantSub.GetGraphQueryTxt();
UnbindSubscription(CreateItemAsVariantSub);

// [THEN] Query is correct
LibraryAssert.IsTrue(ActualQueryTxt.Contains('{"query":"mutation {productVariantDelete('), 'Query not correct');
LibraryAssert.IsTrue(ActualQueryTxt.Contains(StrSubstNo('id: \"gid://shopify/ProductVariant/%1\"', VariantId)), 'Variant Id not set');
end;

[Test]
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();

// [GIVEN] Item
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
// [GIVEN] Shopify product
ProductId := CreateShopifyProduct(Item.SystemId);

// [GIVEN] Multiple options for the product in Shopify
CreateItemAsVariantSub.SetMultipleOptions(true);

// [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.');
end;

[Test]
procedure UnitTestRemoveDefaultVariantTest()
var
Item: Record Item;
ShpfyVariant: Record "Shpfy Variant";
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
ProductId, VariantId : BigInteger;
begin
// [SCENARIO] Remove default variant
Initialize();

// [GIVEN] Item
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
// [GIVEN] Shopify product
ProductId := CreateShopifyProduct(Item.SystemId);
// [GIVEN] Shopify variant
VariantId := CreateShopifyVariant(ProductId);
// [GIVEN] Default variant exists in Shopify
CreateItemAsVariantSub.SetDefaultVariantId(VariantId);

// [WHEN] Invoke CreateItemAsVariant.RemoveDefaultVariant
BindSubscription(CreateItemAsVariantSub);
CreateItemAsVariant.SetParentProduct(ProductId);
CreateItemAsVariant.FindDefaultVariantId();
CreateItemAsVariant.CreateVariantFromItem(Item);
CreateItemAsVariant.RemoveDefaultVariant();
UnbindSubscription(CreateItemAsVariantSub);

// [THEN] Default variant is removed
ShpfyVariant.SetRange(Id, VariantId);
LibraryAssert.IsTrue(ShpfyVariant.IsEmpty(), 'Default variant not removed');

end;

local procedure Initialize()
begin
Any.SetDefaultSeed();
if IsInitialized then
exit;
Shop := ShpfyInitializeTest.CreateShop();
Commit();
IsInitialized := true;
end;

local procedure CreateShopifyProduct(SystemId: Guid): BigInteger
var
ShopifyProduct: Record "Shpfy Product";
begin
ShopifyProduct.Init();
ShopifyProduct.Id := Any.IntegerInRange(10000, 99999);
ShopifyProduct."Shop Code" := Shop."Code";
ShopifyProduct."Item SystemId" := SystemId;
ShopifyProduct.Insert(true);
exit(ShopifyProduct."Id");
end;

local procedure CreateShopifyVariant(ProductId: BigInteger): BigInteger
var
ShpfyVariant: Record "Shpfy Variant";
begin
ShpfyVariant.Init();
ShpfyVariant.Id := Any.IntegerInRange(10000, 99999);
ShpfyVariant."Shop Code" := Shop."Code";
ShpfyVariant."Product Id" := ProductId;
ShpfyVariant.Insert(false);
exit(ShpfyVariant."Id");
end;
}
Loading