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 #288

Merged
merged 2 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>
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(TargetingKey))
{
newTargetingKey = 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());
}
}
}
68 changes: 68 additions & 0 deletions test/OpenFeature.Tests/OpenFeatureEvaluationContextTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using AutoFixture;
using FluentAssertions;
using OpenFeature.Model;
Expand Down Expand Up @@ -151,5 +152,72 @@ public void Should_Be_Able_To_Get_All_Values()

context.Count.Should().Be(count);
}

[Fact]
public void TryGetValue_WhenCalledWithExistingKey_ReturnsTrueAndExpectedValue()
{
// Arrange
var key = "testKey";
var expectedValue = new Value("testValue");
var structure = new Structure(new Dictionary<string, Value> { { key, expectedValue } });
var evaluationContext = new EvaluationContext(structure);

// Act
var result = evaluationContext.TryGetValue(key, out var actualValue);

// Assert
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);
}
}
}