fix: preserve capture geoip override#240
Conversation
posthog-dotnet Compliance ReportDate: 2026-06-22 09:33:17 UTC
|
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ❌ | 44ms |
| Request Payload.Flags Request Uses V2 Query Param | ❌ | 24ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ❌ | 5ms |
| Request Payload.Flags Request Omits Authorization Header | ❌ | 5ms |
| Request Payload.Token In Flags Body Matches Init | ❌ | 4ms |
| Request Payload.Groups Round Trip | ❌ | 5ms |
| Request Payload.Groups Default To Empty Object | ❌ | 5ms |
| Request Payload.Person Properties Distinct Id Auto Populated When Caller Omits It | ❌ | 5ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ❌ | 5ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ❌ | 4ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ❌ | 5ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 3ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 181ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ❌ | 6ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ❌ | 4ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ❌ | 5ms |
Failures
request_payload.request_with_person_properties_device_id
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.flags_request_uses_v2_query_param
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.flags_request_hits_flags_path_not_decide
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.flags_request_omits_authorization_header
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.token_in_flags_body_matches_init
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.groups_round_trip
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.groups_default_to_empty_object
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.person_properties_distinct_id_auto_populated_when_caller_omits_it
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.disable_geoip_false_propagates_as_geoip_disable_false
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.disable_geoip_omitted_defaults_to_false
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_payload.flag_keys_to_evaluate_contains_only_requested_key
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_lifecycle.two_flag_calls_produce_two_remote_requests
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
request_lifecycle.mock_response_value_is_returned_to_caller
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
side_effect_events.get_feature_flag_captures_feature_flag_called_event
404, message='Not Found', url='http://sdk-adapter:8080/get_feature_flag'
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
tests/UnitTests/PostHogClientTests.cs:418-445
The team prefers parameterised tests. This `[Fact]` only exercises one direction: a global super property of `true` overridden to `false` per-capture. It leaves the symmetric case (super=`false`, per-capture=`true`) untested; if the restore logic were accidentally inverted or only applied under a specific condition, that gap would go undetected. Converting to `[Theory]` / `[InlineData]` lets both directions live in one test body.
```suggestion
[Theory]
[InlineData(true, false)]
[InlineData(false, true)]
public async Task CapturePropertiesOverrideConfiguredGeoIpDisable(bool superValue, bool perCaptureValue)
{
var container = new TestContainer(services => services.Configure<PostHogOptions>(options =>
{
options.SuperProperties["$geoip_disable"] = superValue;
}));
var requestHandler = container.FakeHttpMessageHandler.AddBatchResponse();
var client = container.Activate<PostHogClient>();
client.Capture(
"test-user",
"geoip-event",
new Dictionary<string, object>
{
["$geoip_disable"] = perCaptureValue,
["$ip"] = "203.0.113.42"
});
await client.FlushAsync();
using var document = JsonDocument.Parse(requestHandler.GetReceivedRequestBody(indented: false));
var properties = document.RootElement
.GetProperty("batch")[0]
.GetProperty("properties");
Assert.Equal(perCaptureValue, properties.GetProperty("$geoip_disable").GetBoolean());
Assert.Equal("203.0.113.42", properties.GetProperty("$ip").GetString());
}
```
Reviews (1): Last reviewed commit: "fix: preserve capture geoip override" | Re-trigger Greptile |
💡 Motivation and Context
Fixes #95.
$geoip_disablecan be configured globally through super properties, but callers also need to opt individual capture calls back into GeoIP enrichment by passing$geoip_disable: falsealongside$ip. The existing capture path merged super properties after constructing the event, so the global value overwrote the per-capture override.💚 How did you test it?
📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Implemented with pi. The issue was reproduced with a regression test and fixed by preserving the per-capture override following super property merging. Reviewer feedback was addressed by parameterizing the regression test to cover both override directions. Added a patch changeset for the
PostHogpackage.