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

feat: back targetingKey with internal map #287

Merged
merged 6 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 17 additions & 6 deletions src/OpenFeature/Model/EvaluationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,30 @@ namespace OpenFeature.Model
/// <seealso href="https://github.com/open-feature/spec/blob/v0.5.2/specification/sections/03-evaluation-context.md">Evaluation context</seealso>
public sealed class EvaluationContext
{
/// <summary>
/// The index for the "targeting key" property when the EvaluationContext is serialized or expressed as a dictionary.
/// </summary>
internal const string TargetingKeyIndex = "targetingKey";


private readonly Structure _structure;

/// <summary>
/// Internal constructor used by the builder.
/// </summary>
/// <param name="targetingKey">The targeting key</param>
/// <param name="content">The content of the context.</param>
internal EvaluationContext(string? targetingKey, Structure content)
/// <param name="content"></param>
toddbaert marked this conversation as resolved.
Show resolved Hide resolved
internal EvaluationContext(Structure content)
{
this.TargetingKey = targetingKey;
this._structure = content;
}


/// <summary>
/// Private constructor for making an empty <see cref="EvaluationContext"/>.
/// </summary>
private EvaluationContext()
{
this._structure = Structure.Empty;
this.TargetingKey = string.Empty;
}

/// <summary>
Expand Down Expand Up @@ -89,7 +93,14 @@ public IImmutableDictionary<string, Value> AsDictionary()
/// <summary>
/// Returns the targeting key for the context.
/// </summary>
public string? TargetingKey { get; }
public string? TargetingKey
{
get
{
this._structure.TryGetValue(TargetingKeyIndex, out Value? targetingKey);
return targetingKey?.AsString;
}
}

/// <summary>
/// Return an enumerator for all values
Expand Down
23 changes: 2 additions & 21 deletions src/OpenFeature/Model/EvaluationContextBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ public sealed class EvaluationContextBuilder
{
private readonly StructureBuilder _attributes = Structure.Builder();

internal string? TargetingKey { get; private set; }

/// <summary>
/// Internal to only allow direct creation by <see cref="EvaluationContext.Builder()"/>.
/// </summary>
Expand All @@ -28,7 +26,7 @@ internal EvaluationContextBuilder() { }
/// <returns>This builder</returns>
public EvaluationContextBuilder SetTargetingKey(string targetingKey)
{
this.TargetingKey = targetingKey;
this._attributes.Set(EvaluationContext.TargetingKeyIndex, targetingKey);
return this;
}

Expand Down Expand Up @@ -138,23 +136,6 @@ public EvaluationContextBuilder Set(string key, DateTime value)
/// <returns>This builder</returns>
public EvaluationContextBuilder Merge(EvaluationContext context)
{
string? newTargetingKey = "";

if (!string.IsNullOrWhiteSpace(this.TargetingKey))
{
newTargetingKey = this.TargetingKey;
}

if (!string.IsNullOrWhiteSpace(context.TargetingKey))
{
newTargetingKey = context.TargetingKey;
}

if (!string.IsNullOrWhiteSpace(newTargetingKey))
{
this.TargetingKey = newTargetingKey;
}

foreach (var kvp in context)
{
this.Set(kvp.Key, kvp.Value);
Expand All @@ -169,7 +150,7 @@ public EvaluationContextBuilder Merge(EvaluationContext context)
/// <returns>An immutable <see cref="EvaluationContext"/></returns>
public EvaluationContext Build()
{
return new EvaluationContext(this.TargetingKey, this._attributes.Build());
return new EvaluationContext(this._attributes.Build());
}
}
}
52 changes: 51 additions & 1 deletion test/OpenFeature.Tests/OpenFeatureEvaluationContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public void TryGetValue_WhenCalledWithExistingKey_ReturnsTrueAndExpectedValue()
var key = "testKey";
var expectedValue = new Value("testValue");
var structure = new Structure(new Dictionary<string, Value> { { key, expectedValue } });
var evaluationContext = new EvaluationContext("targetingKey", structure);
var evaluationContext = new EvaluationContext(structure);

// Act
var result = evaluationContext.TryGetValue(key, out var actualValue);
Expand All @@ -169,5 +169,55 @@ public void TryGetValue_WhenCalledWithExistingKey_ReturnsTrueAndExpectedValue()
Assert.True(result);
Assert.Equal(expectedValue, actualValue);
}

[Fact]
public void GetValueOnTargetingKeySetWithTargetingKey_Equals_TargetingKey()
{
// Arrange
var value = "my_targeting_key";
var evaluationContext = EvaluationContext.Builder().SetTargetingKey(value).Build();

// Act
var result = evaluationContext.TryGetValue(EvaluationContext.TargetingKeyIndex, out var actualFromStructure);
var actualFromTargetingKey = evaluationContext.TargetingKey;

// Assert
Assert.True(result);
Assert.Equal(value, actualFromStructure?.AsString);
Assert.Equal(value, actualFromTargetingKey);
}

[Fact]
public void GetValueOnTargetingKeySetWithStructure_Equals_TargetingKey()
{
// Arrange
var value = "my_targeting_key";
var evaluationContext = EvaluationContext.Builder().Set(EvaluationContext.TargetingKeyIndex, new Value(value)).Build();

// Act
var result = evaluationContext.TryGetValue(EvaluationContext.TargetingKeyIndex, out var actualFromStructure);
var actualFromTargetingKey = evaluationContext.TargetingKey;

// Assert
Assert.True(result);
Assert.Equal(value, actualFromStructure?.AsString);
Assert.Equal(value, actualFromTargetingKey);
}

[Fact]
public void GetValueOnTargetingKeySetWithNonStringValue_Equals_Null()
{
// Arrange
var evaluationContext = EvaluationContext.Builder().Set(EvaluationContext.TargetingKeyIndex, new Value(1)).Build();

// Act
var result = evaluationContext.TryGetValue(EvaluationContext.TargetingKeyIndex, out var actualFromStructure);
var actualFromTargetingKey = evaluationContext.TargetingKey;

// Assert
Assert.True(result);
Assert.Null(actualFromStructure?.AsString);
Assert.Null(actualFromTargetingKey);
}
}
}