Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,40 @@ private void Extract(string key, LdValue value, Func<bool, ContextBuilder> sette
_log.Error(InvalidTypeMessage(key, "bool"));
}

/// <summary>
/// Extract private attributes and log an error if they are not a list of strings.
/// </summary>
/// <param name="value">The value to extract</param>
/// <param name="builder">The context builder to add the private attributes to</param>
private void ExtractPrivateAttributes(LdValue value, ContextBuilder builder)
{
if (value.IsNull)
{
// Ignore null values.
return;
}

if (value.Type != LdValueType.Array)
{
_log.Error(InvalidTypeMessage("privateAttributes", "array"));
return;
}

var items = value.AsList(LdValue.Convert.Json);
var privateAttributes = items.Where(item => item.IsString).Select(item => item.AsString).ToArray();

if (privateAttributes.Length != items.Count)
{
_log.Error("'privateAttributes' must be an array of only string values. The non-string" +
" values have been dropped and the remaining values have been applied.");
}

if (privateAttributes.Length != 0)
{
builder.Private(privateAttributes);
}
}

/// <summary>
/// Extract a value and add it to a context builder.
/// </summary>
Expand All @@ -108,7 +142,7 @@ private void ProcessValue(string key, Value value, ContextBuilder builder)
Extract(key, ldValue, builder.Anonymous);
break;
case "privateAttributes":
builder.Private(ldValue.AsList(LdValue.Convert.String).ToArray());
ExtractPrivateAttributes(ldValue, builder);
break;
default:
// Was not a built-in attribute.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,58 @@ public void ItUsesTheTargetingKeyInFavorOfKey()
Assert.Equal("targeting-key", _converter.ToLdContext(evaluationContext).Key);
}

[Fact]
public void ItLogsAnErrorWhenPrivateAttributesIsNotAnArray()
{
var evaluationContext = EvaluationContext.Builder()
.Set("targetingKey", "my-key")
.Set("myCustomAttribute", "myCustomValue")
.Set("privateAttributes", "myCustomAttribute")
.Build();

var expectedContext = Context.Builder("my-key")
.Set("myCustomAttribute", "myCustomValue")
.Build();

Assert.Equal(expectedContext, _converter.ToLdContext(evaluationContext));
Assert.True(_logCapture.HasMessageWithText(LogLevel.Error,
"The attribute 'privateAttributes' must be of type array"));
}

[Fact]
public void ItOmitsNonStringPrivateAttributes()
{
var evaluationContext = EvaluationContext.Builder()
.Set("targetingKey", "my-key")
.Set("privateAttributes", new Value(new List<Value>
{
new Value("myCustomAttribute"),
new Value(17)
}))
.Build();

var expectedContext = Context.Builder("my-key")
.Private("myCustomAttribute")
.Build();

Assert.Equal(expectedContext, _converter.ToLdContext(evaluationContext));
Assert.True(_logCapture.HasMessageWithText(LogLevel.Error,
"'privateAttributes' must be an array of only string values. The non-string" +
" values have been dropped and the remaining values have been applied."));
}

[Fact]
public void ItAllowsEmptyPrivateAttributes()
{
var evaluationContext = EvaluationContext.Builder()
.Set("targetingKey", "my-key")
.Set("privateAttributes", new Value(new List<Value>()))
.Build();

Assert.Equal(Context.Builder("my-key").Build(), _converter.ToLdContext(evaluationContext));
Assert.Empty(_logCapture.GetMessages());
}

[Fact]
public void ItCanBuildASingleContext()
{
Expand Down
Loading