Skip to content

Commit ea13da4

Browse files
[Shopify] - Add Item As Variant Tests (#27541)
This pull request does not have a related issue as it's part of delivery for development agreed directly with @AndreiPanko Fixes #26819 ### Add Item As Variant Test Automated tests for changes #26712 Fixes [AB#555979](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/555979) --------- Co-authored-by: Piotr Michalak <[email protected]>
1 parent fe1fe17 commit ea13da4

File tree

2 files changed

+340
-0
lines changed

2 files changed

+340
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
codeunit 139620 "Shpfy CreateItemAsVariantSub"
2+
{
3+
EventSubscriberInstance = Manual;
4+
5+
var
6+
GraphQueryTxt: Text;
7+
NewVariantId: BigInteger;
8+
DefaultVariantId: BigInteger;
9+
MultipleOptions: Boolean;
10+
11+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)]
12+
local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
13+
begin
14+
MakeResponse(HttpRequestMessage, HttpResponseMessage);
15+
end;
16+
17+
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)]
18+
local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text)
19+
begin
20+
HttpResponseMessage.Content.ReadAs(Response);
21+
end;
22+
23+
local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage)
24+
var
25+
Uri: Text;
26+
GraphQlQuery: Text;
27+
CreateItemVariantTok: Label '{"query":"mutation { productVariantCreate(input: {productId: \"gid://shopify/Product/', locked = true;
28+
GetOptionsStartTok: Label '{"query":"{product(id: \"gid://shopify/Product/', locked = true;
29+
GetOptionsEndTok: Label '\") {id title options {id name}}}"}', Locked = true;
30+
RemoveVariantStartTok: Label '{"query":"mutation {productVariantDelete(id: \"gid://shopify/ProductVariant/', Locked = true;
31+
RemoveVariantEndTok: Label '\") {deletedProductVariantId userErrors{field message}}}"}', Locked = true;
32+
GetVariantsTok: Label 'variants(first:200){pageInfo{hasNextPage} edges{cursor node{legacyResourceId updatedAt}}}', Locked = true;
33+
34+
GraphQLCmdTxt: Label '/graphql.json', Locked = true;
35+
begin
36+
case HttpRequestMessage.Method of
37+
'POST':
38+
begin
39+
Uri := HttpRequestMessage.GetRequestUri();
40+
if Uri.EndsWith(GraphQLCmdTxt) then
41+
if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then
42+
case true of
43+
GraphQlQuery.StartsWith(CreateItemVariantTok):
44+
HttpResponseMessage := GetCreatedVariantResponse();
45+
GraphQlQuery.StartsWith(GetOptionsStartTok) and GraphQlQuery.EndsWith(GetOptionsEndTok):
46+
if MultipleOptions then
47+
HttpResponseMessage := GetProductMultipleOptionsResponse()
48+
else
49+
HttpResponseMessage := GetProductOptionsResponse();
50+
GraphQlQuery.StartsWith(RemoveVariantStartTok) and GraphQlQuery.EndsWith(RemoveVariantEndTok):
51+
begin
52+
HttpResponseMessage := GetRemoveVariantResponse();
53+
GraphQueryTxt := GraphQlQuery;
54+
end;
55+
GraphQlQuery.Contains(GetVariantsTok):
56+
HttpResponseMessage := GetDefaultVariantResponse();
57+
end;
58+
end;
59+
end;
60+
end;
61+
62+
local procedure GetCreatedVariantResponse(): HttpResponseMessage;
63+
var
64+
Any: Codeunit Any;
65+
HttpResponseMessage: HttpResponseMessage;
66+
BodyTxt: Text;
67+
begin
68+
Any.SetDefaultSeed();
69+
NewVariantId := Any.IntegerInRange(100000, 999999);
70+
BodyTxt := StrSubstNo('{ "data": { "productVariantCreate": { "legacyResourceId": %1 } } }', NewVariantId);
71+
HttpResponseMessage.Content.WriteFrom(BodyTxt);
72+
exit(HttpResponseMessage);
73+
end;
74+
75+
local procedure GetProductOptionsResponse(): HttpResponseMessage
76+
var
77+
HttpResponseMessage: HttpResponseMessage;
78+
BodyTxt: Text;
79+
begin
80+
BodyTxt := '{"data": {"product": {"id": "gid://shopify/Product/123456", "title": "Product 1", "options": [{"id": "gid://shopify/ProductOption/1", "name": "Option 1"}]}}}';
81+
HttpResponseMessage.Content.WriteFrom(BodyTxt);
82+
exit(HttpResponseMessage);
83+
end;
84+
85+
local procedure GetRemoveVariantResponse(): HttpResponseMessage
86+
var
87+
HttpResponseMessage: HttpResponseMessage;
88+
BodyTxt: Text;
89+
begin
90+
BodyTxt := '{}';
91+
HttpResponseMessage.Content.WriteFrom(BodyTxt);
92+
exit(HttpResponseMessage);
93+
end;
94+
95+
local procedure GetProductMultipleOptionsResponse(): HttpResponseMessage
96+
var
97+
HttpResponseMessage: HttpResponseMessage;
98+
BodyTxt: Text;
99+
begin
100+
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"}]}}}';
101+
HttpResponseMessage.Content.WriteFrom(BodyTxt);
102+
exit(HttpResponseMessage);
103+
end;
104+
105+
local procedure GetDefaultVariantResponse(): HttpResponseMessage
106+
var
107+
HttpResponseMessage: HttpResponseMessage;
108+
BodyTxt: Text;
109+
begin
110+
BodyTxt := StrSubstNo('{ "data" : { "product" : { "variants" : { "edges" : [ { "node" : { "legacyResourceId" : %1 } } ] } } } }', DefaultVariantId);
111+
HttpResponseMessage.Content.WriteFrom(BodyTxt);
112+
exit(HttpResponseMessage);
113+
end;
114+
115+
procedure GetNewVariantId(): BigInteger
116+
begin
117+
exit(NewVariantId);
118+
end;
119+
120+
procedure GetGraphQueryTxt(): Text
121+
begin
122+
exit(GraphQueryTxt);
123+
end;
124+
125+
procedure SetMultipleOptions(NewMultipleOptions: Boolean)
126+
begin
127+
this.MultipleOptions := NewMultipleOptions;
128+
end;
129+
130+
procedure SetDefaultVariantId(NewDefaultVariantId: BigInteger)
131+
begin
132+
this.DefaultVariantId := NewDefaultVariantId;
133+
end;
134+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
codeunit 139619 "Shpfy Create Item Variant Test"
2+
{
3+
Subtype = Test;
4+
TestPermissions = Disabled;
5+
6+
var
7+
Shop: Record "Shpfy Shop";
8+
Any: Codeunit Any;
9+
LibraryAssert: Codeunit "Library Assert";
10+
ShpfyInitializeTest: Codeunit "Shpfy Initialize Test";
11+
IsInitialized: Boolean;
12+
13+
trigger OnRun()
14+
begin
15+
IsInitialized := false;
16+
end;
17+
18+
[Test]
19+
procedure UnitTestCreateVariantFromItem()
20+
var
21+
Item: Record "Item";
22+
ShpfyVariant: Record "Shpfy Variant";
23+
ShpfyProduct: Record "Shpfy Product";
24+
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
25+
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
26+
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
27+
ParentProductId: BigInteger;
28+
VariantId: BigInteger;
29+
begin
30+
// [SCENARIO] Create a variant from a given item
31+
Initialize();
32+
33+
// [GIVEN] Item
34+
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
35+
// [GIVEN] Shopify product
36+
ParentProductId := CreateShopifyProduct(Item.SystemId);
37+
38+
// [WHEN] Invoke CreateItemAsVariant.CreateVariantFromItem
39+
BindSubscription(CreateItemAsVariantSub);
40+
CreateItemAsVariant.SetParentProduct(ParentProductId);
41+
CreateItemAsVariant.CreateVariantFromItem(Item);
42+
VariantId := CreateItemAsVariantSub.GetNewVariantId();
43+
UnbindSubscription(CreateItemAsVariantSub);
44+
45+
// [THEN] Variant is created
46+
LibraryAssert.IsTrue(ShpfyVariant.Get(VariantId), 'Variant not created');
47+
LibraryAssert.AreEqual(Item."No.", ShpfyVariant.Title, 'Title not set');
48+
LibraryAssert.AreEqual(Item."No.", ShpfyVariant."Option 1 Value", 'Option 1 Value not set');
49+
LibraryAssert.AreEqual('Variant', ShpfyVariant."Option 1 Name", 'Option 1 Name not set');
50+
LibraryAssert.AreEqual(ParentProductId, ShpfyVariant."Product Id", 'Parent product not set');
51+
LibraryAssert.IsTrue(ShpfyProduct.Get(ParentProductId), 'Parent product not found');
52+
LibraryAssert.IsTrue(ShpfyProduct."Has Variants", 'Has Variants not set');
53+
end;
54+
55+
[Test]
56+
procedure UnitTestGetProductOptions()
57+
var
58+
Item: Record "Item";
59+
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
60+
ProductAPI: Codeunit "Shpfy Product API";
61+
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
62+
ProductId: BigInteger;
63+
Options: Dictionary of [Text, Text];
64+
begin
65+
// [SCENARIO] Get product options for a given shopify product
66+
Initialize();
67+
68+
// [GIVEN] Item
69+
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
70+
// [GIVEN] Shopify product
71+
ProductId := Any.IntegerInRange(10000, 99999);
72+
73+
// [WHEN] Invoke ProductAPI.GetProductOptions
74+
BindSubscription(CreateItemAsVariantSub);
75+
Options := ProductAPI.GetProductOptions(ProductId);
76+
UnbindSubscription(CreateItemAsVariantSub);
77+
78+
// [THEN] Options are returned
79+
LibraryAssert.AreEqual(1, Options.Count(), 'Options not returned');
80+
end;
81+
82+
[Test]
83+
procedure UnitTestDeleteProductVariant()
84+
var
85+
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
86+
VariantAPI: Codeunit "Shpfy Variant API";
87+
VariantId: BigInteger;
88+
ActualQueryTxt: Text;
89+
begin
90+
// [SCENARIO] Delete a product variant
91+
Initialize();
92+
93+
// [GIVEN] Shopify Variant Id
94+
VariantId := Any.IntegerInRange(10000, 99999);
95+
96+
// [WHEN] Invoke ProductAPI.DeleteProductVariant
97+
BindSubscription(CreateItemAsVariantSub);
98+
VariantAPI.DeleteProductVariant(VariantId);
99+
ActualQueryTxt := CreateItemAsVariantSub.GetGraphQueryTxt();
100+
UnbindSubscription(CreateItemAsVariantSub);
101+
102+
// [THEN] Query is correct
103+
LibraryAssert.IsTrue(ActualQueryTxt.Contains('{"query":"mutation {productVariantDelete('), 'Query not correct');
104+
LibraryAssert.IsTrue(ActualQueryTxt.Contains(StrSubstNo('id: \"gid://shopify/ProductVariant/%1\"', VariantId)), 'Variant Id not set');
105+
end;
106+
107+
[Test]
108+
procedure UnitTestCreateVariantFromProductWithMultipleOptions()
109+
var
110+
Item: Record "Item";
111+
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
112+
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
113+
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
114+
ProductId: BigInteger;
115+
begin
116+
// [SCENARIO] Create a variant from a product with multiple options
117+
Initialize();
118+
119+
// [GIVEN] Item
120+
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
121+
// [GIVEN] Shopify product
122+
ProductId := CreateShopifyProduct(Item.SystemId);
123+
124+
// [GIVEN] Multiple options for the product in Shopify
125+
CreateItemAsVariantSub.SetMultipleOptions(true);
126+
127+
// [WHEN] Invoke ProductAPI.CheckProductAndShopSettings
128+
BindSubscription(CreateItemAsVariantSub);
129+
CreateItemAsVariant.SetParentProduct(ProductId);
130+
asserterror CreateItemAsVariant.CheckProductAndShopSettings();
131+
UnbindSubscription(CreateItemAsVariantSub);
132+
133+
// [THEN] Error is thrown
134+
LibraryAssert.ExpectedError('The product has more than one option. Items cannot be added as variants to a product with multiple options.');
135+
end;
136+
137+
[Test]
138+
procedure UnitTestRemoveDefaultVariantTest()
139+
var
140+
Item: Record Item;
141+
ShpfyVariant: Record "Shpfy Variant";
142+
ShpfyProductInitTest: Codeunit "Shpfy Product Init Test";
143+
CreateItemAsVariant: Codeunit "Shpfy Create Item As Variant";
144+
CreateItemAsVariantSub: Codeunit "Shpfy CreateItemAsVariantSub";
145+
ProductId, VariantId : BigInteger;
146+
begin
147+
// [SCENARIO] Remove default variant
148+
Initialize();
149+
150+
// [GIVEN] Item
151+
Item := ShpfyProductInitTest.CreateItem(Shop."Item Templ. Code", Any.DecimalInRange(10, 100, 2), Any.DecimalInRange(100, 500, 2));
152+
// [GIVEN] Shopify product
153+
ProductId := CreateShopifyProduct(Item.SystemId);
154+
// [GIVEN] Shopify variant
155+
VariantId := CreateShopifyVariant(ProductId);
156+
// [GIVEN] Default variant exists in Shopify
157+
CreateItemAsVariantSub.SetDefaultVariantId(VariantId);
158+
159+
// [WHEN] Invoke CreateItemAsVariant.RemoveDefaultVariant
160+
BindSubscription(CreateItemAsVariantSub);
161+
CreateItemAsVariant.SetParentProduct(ProductId);
162+
CreateItemAsVariant.FindDefaultVariantId();
163+
CreateItemAsVariant.CreateVariantFromItem(Item);
164+
CreateItemAsVariant.RemoveDefaultVariant();
165+
UnbindSubscription(CreateItemAsVariantSub);
166+
167+
// [THEN] Default variant is removed
168+
ShpfyVariant.SetRange(Id, VariantId);
169+
LibraryAssert.IsTrue(ShpfyVariant.IsEmpty(), 'Default variant not removed');
170+
171+
end;
172+
173+
local procedure Initialize()
174+
begin
175+
Any.SetDefaultSeed();
176+
if IsInitialized then
177+
exit;
178+
Shop := ShpfyInitializeTest.CreateShop();
179+
Commit();
180+
IsInitialized := true;
181+
end;
182+
183+
local procedure CreateShopifyProduct(SystemId: Guid): BigInteger
184+
var
185+
ShopifyProduct: Record "Shpfy Product";
186+
begin
187+
ShopifyProduct.Init();
188+
ShopifyProduct.Id := Any.IntegerInRange(10000, 99999);
189+
ShopifyProduct."Shop Code" := Shop."Code";
190+
ShopifyProduct."Item SystemId" := SystemId;
191+
ShopifyProduct.Insert(true);
192+
exit(ShopifyProduct."Id");
193+
end;
194+
195+
local procedure CreateShopifyVariant(ProductId: BigInteger): BigInteger
196+
var
197+
ShpfyVariant: Record "Shpfy Variant";
198+
begin
199+
ShpfyVariant.Init();
200+
ShpfyVariant.Id := Any.IntegerInRange(10000, 99999);
201+
ShpfyVariant."Shop Code" := Shop."Code";
202+
ShpfyVariant."Product Id" := ProductId;
203+
ShpfyVariant.Insert(false);
204+
exit(ShpfyVariant."Id");
205+
end;
206+
}

0 commit comments

Comments
 (0)