Skip to content

Commit

Permalink
Improve unit test coverage of LoggingHook
Browse files Browse the repository at this point in the history
Signed-off-by: Kyle Julian <38759683+kylejuliandev@users.noreply.github.com>
  • Loading branch information
kylejuliandev committed Jan 9, 2025
1 parent c8b563e commit 0b46216
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 4 deletions.
5 changes: 3 additions & 2 deletions src/OpenFeature/Hooks/LoggingHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public override string ToString()
stringBuilder.Append('\t');
stringBuilder.Append(kvp.Key);
stringBuilder.Append(':');
stringBuilder.Append(GetValueString(kvp.Value) ?? "missing");
stringBuilder.Append(GetValueString(kvp.Value));
stringBuilder.Append(Environment.NewLine);
}
}
Expand All @@ -167,8 +167,9 @@ public override string ToString()

if (value.IsNumber)
{
// Value.AsDouble will attempt to cast other numbers to double
// There is an implicit conversation for int/long to double
if (value.AsDouble != null) return value.AsDouble.ToString();
if (value.AsInteger != null) return value.AsInteger.ToString();
}

Check warning on line 173 in src/OpenFeature/Hooks/LoggingHook.cs

View check run for this annotation

Codecov / codecov/patch

src/OpenFeature/Hooks/LoggingHook.cs#L173

Added line #L173 was not covered by tests

if (value.IsDateTime)
Expand Down
171 changes: 169 additions & 2 deletions test/OpenFeature.Tests/Hooks/LoggingHookTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,7 @@ public async Task With_Structure_Type_In_Context_Returns_Qualified_Name_Of_Value
var record = logger.LatestRecord;

// Raw string literals will convert tab to spaces (the File index style)
var tabSize = 4;
var message = record.Message.Replace("\t", new string(' ', tabSize));
var message = NormalizeLogRecord(record);

Assert.Equal(
"""
Expand All @@ -500,4 +499,172 @@ public async Task With_Structure_Type_In_Context_Returns_Qualified_Name_Of_Value
message
);
}

[Fact]
public async Task Without_Domain_Returns_Missing()
{
// Arrange
var logger = new FakeLogger<LoggingHookTests>();

var clientMetadata = new ClientMetadata(null, "1.0.0");
var providerMetadata = new Metadata("provider");
var evaluationContext = EvaluationContext.Builder()
.Set("key_1", true)
.Build();

var context = new HookContext<bool>("test", false, FlagValueType.Object, clientMetadata,
providerMetadata, evaluationContext);

var details = new FlagEvaluationDetails<bool>("test", true, ErrorType.None, reason: null, variant: null);

var hook = new LoggingHook(logger, includeContext: true);

// Act
await hook.AfterAsync(context, details);

// Assert
var record = logger.LatestRecord;
var message = NormalizeLogRecord(record);

Assert.Equal(
"""
After Flag Evaluation Domain:missing
ProviderName:provider
FlagKey:test
DefaultValue:False
Context:
key_1:True
""",
message
);
}

[Fact]
public async Task Without_Provider_Returns_Missing()
{
// Arrange
var logger = new FakeLogger<LoggingHookTests>();

var clientMetadata = new ClientMetadata("client", "1.0.0");
var providerMetadata = new Metadata(null);
var evaluationContext = EvaluationContext.Builder()
.Set("key_1", true)
.Build();

var context = new HookContext<bool>("test", false, FlagValueType.Object, clientMetadata,
providerMetadata, evaluationContext);

var details = new FlagEvaluationDetails<bool>("test", true, ErrorType.None, reason: null, variant: null);

var hook = new LoggingHook(logger, includeContext: true);

// Act
await hook.AfterAsync(context, details);

// Assert
var record = logger.LatestRecord;
var message = NormalizeLogRecord(record);

Assert.Equal(
"""
After Flag Evaluation Domain:client
ProviderName:missing
FlagKey:test
DefaultValue:False
Context:
key_1:True
""",
message
);
}

[Fact]
public async Task Without_DefaultValue_Returns_Missing()
{
// Arrange
var logger = new FakeLogger<LoggingHookTests>();

var clientMetadata = new ClientMetadata("client", "1.0.0");
var providerMetadata = new Metadata("provider");
var evaluationContext = EvaluationContext.Builder()
.Set("key_1", true)
.Build();

var context = new HookContext<string>("test", null!, FlagValueType.Object, clientMetadata,
providerMetadata, evaluationContext);

var details = new FlagEvaluationDetails<string>("test", "true", ErrorType.None, reason: null, variant: null);

var hook = new LoggingHook(logger, includeContext: true);

// Act
await hook.AfterAsync(context, details);

// Assert
var record = logger.LatestRecord;
var message = NormalizeLogRecord(record);

Assert.Equal(
"""
After Flag Evaluation Domain:client
ProviderName:provider
FlagKey:test
DefaultValue:missing
Context:
key_1:True
""",
message
);
}

[Fact]
public async Task Without_EvaluationContextValue_Returns_Nothing()
{
// Arrange
var logger = new FakeLogger<LoggingHookTests>();

var clientMetadata = new ClientMetadata("client", "1.0.0");
var providerMetadata = new Metadata("provider");
var evaluationContext = EvaluationContext.Builder()
.Set("key_1", (string)null!)
.Build();

var context = new HookContext<bool>("test", false, FlagValueType.Object, clientMetadata,
providerMetadata, evaluationContext);

var details = new FlagEvaluationDetails<bool>("test", true, ErrorType.None, reason: null, variant: null);

var hook = new LoggingHook(logger, includeContext: true);

// Act
await hook.AfterAsync(context, details);

// Assert
var record = logger.LatestRecord;
var message = NormalizeLogRecord(record);

Assert.Equal(
"""
After Flag Evaluation Domain:client
ProviderName:provider
FlagKey:test
DefaultValue:False
Context:
key_1:
""",
message
);
}

private static string NormalizeLogRecord(FakeLogRecord record)
{
// Raw string literals will convert tab to spaces (the File index style)
const int tabSize = 4;

return record.Message.Replace("\t", new string(' ', tabSize));
}
}

0 comments on commit 0b46216

Please sign in to comment.