Skip to content

Commit c3c737e

Browse files
OMpawar-21claude
andcommitted
refactor(variants): extract ResolveBranch helper and consolidate test utilities
- Extract duplicated branch-resolution logic into a private ResolveBranch() method in both Entry and Query, eliminating inline ternary repetition - Add DefaultBranch = "main" constant shared across Variant overloads - Promote Query._Headers to internal visibility to remove reflection in unit tests - Introduce UnitTestHelpers.GetMockClient() shared helper, removing duplicate private factory methods from EntryUnitTests and QueryUnitTests - Strengthen integration test assertions: use ThrowsAnyAsync and assert that exception message contains "branch" rather than just checking non-null - Replace hard-coded "development" branch strings with TestDataHelper.BranchUid - Bump contentstack.utils dependency from 2.0.0 to 2.0.1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d533ac1 commit c3c737e

8 files changed

Lines changed: 175 additions & 120 deletions

File tree

Contentstack.Core.Tests/Integration/VariantsTests/EntryVariantsComprehensiveTest.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public async Task Variant_WithInvalidBranch_ThrowsException()
3939
// Act & Assert
4040
LogAct("Fetching entry with variant and INVALID branch using .Variant() method");
4141

42-
var exception = await Assert.ThrowsAsync<Exception>(async () =>
42+
var exception = await Assert.ThrowsAnyAsync<Exception>(async () =>
4343
{
4444
await client
4545
.ContentType(TestDataHelper.ComplexContentTypeUid)
@@ -48,8 +48,8 @@ await client
4848
.Fetch<Entry>();
4949
});
5050

51-
LogAssert("Verifying exception was thrown");
52-
TestAssert.NotNull(exception);
51+
LogAssert("Verifying exception was thrown for invalid branch");
52+
Assert.Contains("branch", exception.Message, System.StringComparison.OrdinalIgnoreCase);
5353
}
5454

5555
[Fact(DisplayName = "Entry Operations - Variant With Valid Branch Returns Results")]
@@ -60,7 +60,7 @@ public async Task Variant_WithValidBranch_ReturnsResults()
6060
LogContext("ContentType", TestDataHelper.ComplexContentTypeUid);
6161
LogContext("EntryUid", TestDataHelper.ComplexEntryUid);
6262
LogContext("VariantUid", TestDataHelper.VariantUid);
63-
LogContext("Branch", "development");
63+
LogContext("Branch", TestDataHelper.BranchUid);
6464

6565
var client = CreateClient();
6666

@@ -70,7 +70,7 @@ public async Task Variant_WithValidBranch_ReturnsResults()
7070
var entry = await client
7171
.ContentType(TestDataHelper.ComplexContentTypeUid)
7272
.Entry(TestDataHelper.ComplexEntryUid)
73-
.Variant(TestDataHelper.VariantUid, "development")
73+
.Variant(TestDataHelper.VariantUid, TestDataHelper.BranchUid)
7474
.Fetch<Entry>();
7575

7676
// Assert
@@ -329,13 +329,13 @@ public async Task Variant_Query_WithInvalidBranch_ThrowsException()
329329
query.Variant(TestDataHelper.VariantUid, "invalid_branch_name_123");
330330
query.Limit(5);
331331

332-
var exception = await Assert.ThrowsAsync<Exception>(async () =>
332+
var exception = await Assert.ThrowsAnyAsync<Exception>(async () =>
333333
{
334334
await query.Find<Entry>();
335335
});
336336

337-
LogAssert("Verifying exception was thrown");
338-
TestAssert.NotNull(exception);
337+
LogAssert("Verifying exception was thrown for invalid branch");
338+
Assert.Contains("branch", exception.Message, System.StringComparison.OrdinalIgnoreCase);
339339
}
340340

341341
[Fact(DisplayName = "Entry Operations - Variant Query With Valid Branch Returns Results")]
@@ -345,15 +345,15 @@ public async Task Variant_Query_WithValidBranch_ReturnsResults()
345345
LogArrange("Setting up query operation with valid branch");
346346
LogContext("ContentType", TestDataHelper.ComplexContentTypeUid);
347347
LogContext("VariantUid", TestDataHelper.VariantUid);
348-
LogContext("Branch", "development");
348+
LogContext("Branch", TestDataHelper.BranchUid);
349349

350350
var client = CreateClient();
351351
var query = client.ContentType(TestDataHelper.ComplexContentTypeUid).Query();
352352

353353
// Act
354354
LogAct("Executing query with variant and valid branch");
355355

356-
query.Variant(TestDataHelper.VariantUid, "development");
356+
query.Variant(TestDataHelper.VariantUid, TestDataHelper.BranchUid);
357357
query.Limit(5);
358358
var result = await query.Find<Entry>();
359359

Contentstack.Core.Unit.Tests/EntryUnitTests.cs

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,32 +2748,20 @@ public void Entry_Fetch_WithCachePolicyNotSet_Setup_VerifiesDefault()
27482748

27492749
#region Variant Tests
27502750

2751-
private ContentstackClient GetMockClient(string stackBranch = null)
2752-
{
2753-
var options = new ContentstackOptions
2754-
{
2755-
ApiKey = "dummy_api_key",
2756-
DeliveryToken = "dummy_delivery_token",
2757-
Environment = "dummy_environment",
2758-
Branch = stackBranch
2759-
};
2760-
return new ContentstackClient(options);
2761-
}
2762-
27632751
[Fact(DisplayName = "Entry Operations - Variant With Branch Sets Branch Header")]
27642752
public void Entry_Variant_WithBranch_SetsBranchHeader()
27652753
{
27662754
// Arrange
2767-
var client = GetMockClient("main");
2768-
var entry = client.ContentType("dummy_content_type").Entry("dummy_entry_uid");
2755+
var client = UnitTestHelpers.GetMockClient("main");
2756+
var entry = client.ContentType("DUMMY_CONTENT_TYPE").Entry("DUMMY_ENTRY_UID");
27692757

27702758
// Act
2771-
entry.Variant("variant_1", "development");
2759+
entry.Variant("VARIANT_1", "development");
27722760

27732761
// Assert
27742762
Assert.True(entry._Headers.ContainsKey("x-cs-variant-uid"));
2775-
Assert.Equal("variant_1", entry._Headers["x-cs-variant-uid"]);
2776-
2763+
Assert.Equal("VARIANT_1", entry._Headers["x-cs-variant-uid"]);
2764+
27772765
Assert.True(entry._Headers.ContainsKey("branch"));
27782766
Assert.Equal("development", entry._Headers["branch"]);
27792767
}
@@ -2782,16 +2770,16 @@ public void Entry_Variant_WithBranch_SetsBranchHeader()
27822770
public void Entry_Variant_WithNullBranch_FallsBackToStackBranch()
27832771
{
27842772
// Arrange
2785-
var client = GetMockClient("stack_branch");
2786-
var entry = client.ContentType("dummy_content_type").Entry("dummy_entry_uid");
2773+
var client = UnitTestHelpers.GetMockClient("stack_branch");
2774+
var entry = client.ContentType("DUMMY_CONTENT_TYPE").Entry("DUMMY_ENTRY_UID");
27872775

27882776
// Act
2789-
entry.Variant("variant_1", null);
2777+
entry.Variant("VARIANT_1", null);
27902778

27912779
// Assert
27922780
Assert.True(entry._Headers.ContainsKey("x-cs-variant-uid"));
2793-
Assert.Equal("variant_1", entry._Headers["x-cs-variant-uid"]);
2794-
2781+
Assert.Equal("VARIANT_1", entry._Headers["x-cs-variant-uid"]);
2782+
27952783
Assert.True(entry._Headers.ContainsKey("branch"));
27962784
Assert.Equal("stack_branch", entry._Headers["branch"]);
27972785
}
@@ -2800,16 +2788,16 @@ public void Entry_Variant_WithNullBranch_FallsBackToStackBranch()
28002788
public void Entry_Variant_WithEmptyBranch_FallsBackToMainIfStackBranchIsNull()
28012789
{
28022790
// Arrange
2803-
var client = GetMockClient(null);
2804-
var entry = client.ContentType("dummy_content_type").Entry("dummy_entry_uid");
2791+
var client = UnitTestHelpers.GetMockClient(null);
2792+
var entry = client.ContentType("DUMMY_CONTENT_TYPE").Entry("DUMMY_ENTRY_UID");
28052793

28062794
// Act
2807-
entry.Variant("variant_1", " ");
2795+
entry.Variant("VARIANT_1", " ");
28082796

28092797
// Assert
28102798
Assert.True(entry._Headers.ContainsKey("x-cs-variant-uid"));
2811-
Assert.Equal("variant_1", entry._Headers["x-cs-variant-uid"]);
2812-
2799+
Assert.Equal("VARIANT_1", entry._Headers["x-cs-variant-uid"]);
2800+
28132801
Assert.True(entry._Headers.ContainsKey("branch"));
28142802
Assert.Equal("main", entry._Headers["branch"]);
28152803
}
@@ -2818,17 +2806,17 @@ public void Entry_Variant_WithEmptyBranch_FallsBackToMainIfStackBranchIsNull()
28182806
public void Entry_Variant_WithMultipleVariantsAndBranch_SetsHeaders()
28192807
{
28202808
// Arrange
2821-
var client = GetMockClient("main");
2822-
var entry = client.ContentType("dummy_content_type").Entry("dummy_entry_uid");
2823-
var variants = new List<string> { "variant_1", "variant_2" };
2809+
var client = UnitTestHelpers.GetMockClient("main");
2810+
var entry = client.ContentType("DUMMY_CONTENT_TYPE").Entry("DUMMY_ENTRY_UID");
2811+
var variants = new List<string> { "VARIANT_1", "VARIANT_2" };
28242812

28252813
// Act
28262814
entry.Variant(variants, "feature_branch");
28272815

28282816
// Assert
28292817
Assert.True(entry._Headers.ContainsKey("x-cs-variant-uid"));
2830-
Assert.Equal("variant_1,variant_2", entry._Headers["x-cs-variant-uid"]);
2831-
2818+
Assert.Equal("VARIANT_1,VARIANT_2", entry._Headers["x-cs-variant-uid"]);
2819+
28322820
Assert.True(entry._Headers.ContainsKey("branch"));
28332821
Assert.Equal("feature_branch", entry._Headers["branch"]);
28342822
}

Contentstack.Core.Unit.Tests/QueryUnitTests.cs

Lines changed: 24 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,101 +2635,69 @@ public void Query_WithNullUrlQueries_Setup_HandlesGracefully()
26352635

26362636
#region Variant Tests
26372637

2638-
private ContentstackClient GetMockClient(string stackBranch = null)
2639-
{
2640-
var options = new ContentstackOptions
2641-
{
2642-
ApiKey = "dummy_api_key",
2643-
DeliveryToken = "dummy_delivery_token",
2644-
Environment = "dummy_environment",
2645-
Branch = stackBranch
2646-
};
2647-
return new ContentstackClient(options);
2648-
}
2649-
26502638
[Fact(DisplayName = "Query Operations - Variant With Branch Sets Branch Header")]
26512639
public void Query_Variant_WithBranch_SetsBranchHeader()
26522640
{
26532641
// Arrange
2654-
var client = GetMockClient("main");
2655-
var query = client.ContentType("dummy_content_type").Query();
2642+
var query = UnitTestHelpers.GetMockClient("main").ContentType("DUMMY_CONTENT_TYPE").Query();
26562643

26572644
// Act
2658-
query.Variant("variant_1", "development");
2645+
query.Variant("VARIANT_1", "development");
26592646

26602647
// Assert
2661-
var headersField = typeof(Query).GetField("_Headers", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
2662-
var headers = (Dictionary<string, object>)headersField.GetValue(query);
2663-
2664-
Assert.True(headers.ContainsKey("x-cs-variant-uid"));
2665-
Assert.Equal("variant_1", headers["x-cs-variant-uid"]);
2666-
2667-
Assert.True(headers.ContainsKey("branch"));
2668-
Assert.Equal("development", headers["branch"]);
2648+
Assert.True(query._Headers.ContainsKey("x-cs-variant-uid"));
2649+
Assert.Equal("VARIANT_1", query._Headers["x-cs-variant-uid"]);
2650+
Assert.True(query._Headers.ContainsKey("branch"));
2651+
Assert.Equal("development", query._Headers["branch"]);
26692652
}
26702653

26712654
[Fact(DisplayName = "Query Operations - Variant With Null Branch Falls Back To Stack Branch")]
26722655
public void Query_Variant_WithNullBranch_FallsBackToStackBranch()
26732656
{
26742657
// Arrange
2675-
var client = GetMockClient("stack_branch");
2676-
var query = client.ContentType("dummy_content_type").Query();
2658+
var query = UnitTestHelpers.GetMockClient("stack_branch").ContentType("DUMMY_CONTENT_TYPE").Query();
26772659

26782660
// Act
2679-
query.Variant("variant_1", null);
2661+
query.Variant("VARIANT_1", null);
26802662

26812663
// Assert
2682-
var headersField = typeof(Query).GetField("_Headers", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
2683-
var headers = (Dictionary<string, object>)headersField.GetValue(query);
2684-
2685-
Assert.True(headers.ContainsKey("x-cs-variant-uid"));
2686-
Assert.Equal("variant_1", headers["x-cs-variant-uid"]);
2687-
2688-
Assert.True(headers.ContainsKey("branch"));
2689-
Assert.Equal("stack_branch", headers["branch"]);
2664+
Assert.True(query._Headers.ContainsKey("x-cs-variant-uid"));
2665+
Assert.Equal("VARIANT_1", query._Headers["x-cs-variant-uid"]);
2666+
Assert.True(query._Headers.ContainsKey("branch"));
2667+
Assert.Equal("stack_branch", query._Headers["branch"]);
26902668
}
26912669

26922670
[Fact(DisplayName = "Query Operations - Variant With Empty Branch Falls Back To Main If Stack Branch Is Null")]
26932671
public void Query_Variant_WithEmptyBranch_FallsBackToMainIfStackBranchIsNull()
26942672
{
26952673
// Arrange
2696-
var client = GetMockClient(null);
2697-
var query = client.ContentType("dummy_content_type").Query();
2674+
var query = UnitTestHelpers.GetMockClient(null).ContentType("DUMMY_CONTENT_TYPE").Query();
26982675

26992676
// Act
2700-
query.Variant("variant_1", " ");
2677+
query.Variant("VARIANT_1", " ");
27012678

27022679
// Assert
2703-
var headersField = typeof(Query).GetField("_Headers", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
2704-
var headers = (Dictionary<string, object>)headersField.GetValue(query);
2705-
2706-
Assert.True(headers.ContainsKey("x-cs-variant-uid"));
2707-
Assert.Equal("variant_1", headers["x-cs-variant-uid"]);
2708-
2709-
Assert.True(headers.ContainsKey("branch"));
2710-
Assert.Equal("main", headers["branch"]);
2680+
Assert.True(query._Headers.ContainsKey("x-cs-variant-uid"));
2681+
Assert.Equal("VARIANT_1", query._Headers["x-cs-variant-uid"]);
2682+
Assert.True(query._Headers.ContainsKey("branch"));
2683+
Assert.Equal("main", query._Headers["branch"]);
27112684
}
27122685

27132686
[Fact(DisplayName = "Query Operations - Variant With Multiple Variants And Branch Sets Headers")]
27142687
public void Query_Variant_WithMultipleVariantsAndBranch_SetsHeaders()
27152688
{
27162689
// Arrange
2717-
var client = GetMockClient("main");
2718-
var query = client.ContentType("dummy_content_type").Query();
2719-
var variants = new List<string> { "variant_1", "variant_2" };
2690+
var query = UnitTestHelpers.GetMockClient("main").ContentType("DUMMY_CONTENT_TYPE").Query();
2691+
var variants = new List<string> { "VARIANT_1", "VARIANT_2" };
27202692

27212693
// Act
27222694
query.Variant(variants, "feature_branch");
27232695

27242696
// Assert
2725-
var headersField = typeof(Query).GetField("_Headers", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
2726-
var headers = (Dictionary<string, object>)headersField.GetValue(query);
2727-
2728-
Assert.True(headers.ContainsKey("x-cs-variant-uid"));
2729-
Assert.Equal("variant_1,variant_2", headers["x-cs-variant-uid"]);
2730-
2731-
Assert.True(headers.ContainsKey("branch"));
2732-
Assert.Equal("feature_branch", headers["branch"]);
2697+
Assert.True(query._Headers.ContainsKey("x-cs-variant-uid"));
2698+
Assert.Equal("VARIANT_1,VARIANT_2", query._Headers["x-cs-variant-uid"]);
2699+
Assert.True(query._Headers.ContainsKey("branch"));
2700+
Assert.Equal("feature_branch", query._Headers["branch"]);
27332701
}
27342702

27352703
#endregion
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Contentstack.Core;
2+
using Contentstack.Core.Configuration;
3+
4+
namespace Contentstack.Core.Unit.Tests
5+
{
6+
internal static class UnitTestHelpers
7+
{
8+
internal static ContentstackClient GetMockClient(string stackBranch = null)
9+
{
10+
var options = new ContentstackOptions
11+
{
12+
ApiKey = "DUMMY_API_KEY",
13+
DeliveryToken = "DUMMY_DELIVERY_TOKEN",
14+
Environment = "DUMMY_ENVIRONMENT",
15+
Branch = stackBranch
16+
};
17+
return new ContentstackClient(options);
18+
}
19+
}
20+
}

Contentstack.Core/Contentstack.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<PackageReference Include="System.Text.Json" Version="8.0.5" />
3333
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
3434
<PackageReference Include="Markdig" Version="0.36.2" />
35-
<PackageReference Include="contentstack.utils" Version="2.0.0" />
35+
<PackageReference Include="contentstack.utils" Version="2.0.1" />
3636
<PackageReference Include="System.Net.Http" Version="4.3.4" Condition="'$(TargetFramework)' == 'net47' Or '$(TargetFramework)' == 'net472'" />
3737
</ItemGroup>
3838
<ItemGroup>

Contentstack.Core/Models/Entry.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -395,12 +395,13 @@ public void RemoveHeader(string key)
395395
/// To set variants header using Entry instance.
396396
/// </summary>
397397
/// <param name="variant_header">Entry instance</param>
398+
/// <param name="branch">Optional branch to fetch the variant from. Falls back to the stack's configured branch, then "main".</param>
398399
/// <returns>Current instance of Entry, this will be useful for a chaining calls.</returns>
399400
/// <example>
400401
/// <code>
401402
/// ContentstackClient stack = new ContentstackClinet("api_key", "delivery_token", "environment");
402403
/// Entry csEntry = stack.ContentType("contentType_id").Entry("entry_uid");
403-
///
404+
///
404405
/// csEntry.Variant("variant_entry_1");
405406
/// csEntry.Fetch<Product>().ContinueWith((entryResult) => {
406407
/// //Your callback code.
@@ -411,10 +412,7 @@ public void RemoveHeader(string key)
411412
public Entry Variant(string variant_header, string branch = null)
412413
{
413414
this.SetHeader("x-cs-variant-uid", variant_header);
414-
string branchToUse = string.IsNullOrWhiteSpace(branch)
415-
? (this.ContentTypeInstance?.StackInstance?.Config?.Branch ?? "main")
416-
: branch;
417-
this.SetHeader("branch", branchToUse);
415+
this.SetHeader("branch", ResolveBranch(branch));
418416
return this;
419417
}
420418

@@ -424,12 +422,13 @@ public Entry Variant(string variant_header, string branch = null)
424422
/// To set multiple variants headers using Entry instance.
425423
/// </summary>
426424
/// <param name="variant_headers">Entry instance</param>
425+
/// <param name="branch">Optional branch to fetch the variant from. Falls back to the stack's configured branch, then "main".</param>
427426
/// <returns>Current instance of Entry, this will be useful for a chaining calls.</returns>
428427
/// <example>
429428
/// <code>
430429
/// ContentstackClient stack = new ContentstackClinet("api_key", "delivery_token", "environment");
431430
/// Entry csEntry = stack.ContentType("contentType_id").Query();
432-
///
431+
///
433432
/// csEntry.Variant(new List<string> { "variant_entry_1", "variant_entry_2", "variant_entry_3" });
434433
/// csEntry.Fetch<Product>().ContinueWith((entryResult) => {
435434
/// //Your callback code.
@@ -440,13 +439,17 @@ public Entry Variant(string variant_header, string branch = null)
440439
public Entry Variant(List<string> variant_headers, string branch = null)
441440
{
442441
this.SetHeader("x-cs-variant-uid", string.Join(",", variant_headers));
443-
string branchToUse = string.IsNullOrWhiteSpace(branch)
444-
? (this.ContentTypeInstance?.StackInstance?.Config?.Branch ?? "main")
445-
: branch;
446-
this.SetHeader("branch", branchToUse);
442+
this.SetHeader("branch", ResolveBranch(branch));
447443
return this;
448444
}
449445

446+
private const string DefaultBranch = "main";
447+
448+
private string ResolveBranch(string branch) =>
449+
string.IsNullOrWhiteSpace(branch)
450+
? (ContentTypeInstance?.StackInstance?.Config?.Branch ?? DefaultBranch)
451+
: branch;
452+
450453
/// <summary>
451454
/// Get metadata of entry.
452455
/// </summary>

0 commit comments

Comments
 (0)