chore: deduplicate dry4swift findings#618
Conversation
posthog-ios Compliance ReportDate: 2026-06-05 07:08:00 UTC
|
| Test | Status | Duration |
|---|---|---|
| Format Validation.Event Has Required Fields | ✅ | 2233ms |
| Format Validation.Event Has Uuid | ✅ | 2214ms |
| Format Validation.Event Has Lib Properties | ✅ | 2288ms |
| Format Validation.Distinct Id Is String | ✅ | 2185ms |
| Format Validation.Token Is Present | ✅ | 2239ms |
| Format Validation.Custom Properties Preserved | ✅ | 2252ms |
| Format Validation.Event Has Timestamp | ✅ | 2227ms |
| Retry Behavior.Retries On 503 | ❌ | 7307ms |
| Retry Behavior.Does Not Retry On 400 | ✅ | 4260ms |
| Retry Behavior.Does Not Retry On 401 | ✅ | 4452ms |
| Retry Behavior.Respects Retry After Header | ✅ | 7216ms |
| Retry Behavior.Implements Backoff | ✅ | 17272ms |
| Retry Behavior.Retries On 500 | ✅ | 7290ms |
| Retry Behavior.Retries On 502 | ✅ | 7276ms |
| Retry Behavior.Retries On 504 | ✅ | 7253ms |
| Retry Behavior.Max Retries Respected | ❌ | 17389ms |
| Deduplication.Generates Unique Uuids | ✅ | 2394ms |
| Deduplication.Preserves Uuid On Retry | ✅ | 7299ms |
| Deduplication.Preserves Uuid And Timestamp On Retry | ❌ | 12195ms |
| Deduplication.Preserves Uuid And Timestamp On Batch Retry | ✅ | 7319ms |
| Deduplication.No Duplicate Events In Batch | ✅ | 2509ms |
| Deduplication.Different Events Have Different Uuids | ✅ | 2328ms |
| Compression.Sends Gzip When Enabled | ✅ | 2364ms |
| Batch Format.Uses Proper Batch Structure | ✅ | 2267ms |
| Batch Format.Flush With No Events Sends Nothing | ✅ | 2225ms |
| Batch Format.Multiple Events Batched Together | ❌ | 2539ms |
| Error Handling.Does Not Retry On 403 | ✅ | 4218ms |
| Error Handling.Does Not Retry On 413 | ❌ | 4238ms |
| Error Handling.Retries On 408 | ✅ | 7412ms |
Failures
retry_behavior.retries_on_503
Expected at least 3 requests, got 2
retry_behavior.max_retries_respected
Expected 4 requests, got 3
deduplication.preserves_uuid_and_timestamp_on_retry
Expected at least 3 requests, got 2
batch_format.multiple_events_batched_together
Expected 1 requests, got 3
error_handling.does_not_retry_on_413
Expected 1 requests, got 2
Feature_Flags Tests
View Details
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ❌ | 2422ms |
| Request Payload.Flags Request Uses V2 Query Param | ✅ | 2355ms |
| Request Payload.Flags Request Hits Flags Path Not Decide | ✅ | 2201ms |
| Request Payload.Flags Request Omits Authorization Header | ✅ | 2240ms |
| Request Payload.Token In Flags Body Matches Init | ✅ | 2266ms |
| Request Payload.Groups Round Trip | ✅ | 2419ms |
| Request Payload.Groups Default To Empty Object | ❌ | 2233ms |
| Request Payload.Person Properties Distinct Id Auto Populated When Caller Omits It | ❌ | 2337ms |
| Request Payload.Disable Geoip False Propagates As Geoip Disable False | ❌ | 2393ms |
| Request Payload.Disable Geoip Omitted Defaults To False | ❌ | 2325ms |
| Request Payload.Flag Keys To Evaluate Contains Only Requested Key | ❌ | 2252ms |
| Request Lifecycle.No Flags Request On Init Alone | ✅ | 113ms |
| Request Lifecycle.No Flags Request On Normal Capture | ✅ | 2227ms |
| Request Lifecycle.Two Flag Calls Produce Two Remote Requests | ✅ | 4362ms |
| Request Lifecycle.Mock Response Value Is Returned To Caller | ✅ | 2284ms |
| Side Effect Events.Get Feature Flag Captures Feature Flag Called Event | ✅ | 4276ms |
Failures
request_payload.request_with_person_properties_device_id
Expected distinct_id='test_user_123', got '019E969B-9D95-79BC-BF7A-4CFBB0B2F3E8'
request_payload.groups_default_to_empty_object
Field 'group_properties' not found in /flags request body at path 'group_properties'. Available keys: ['groups', 'timezone', '$device_id', 'api_key', 'person_properties', '$anon_distinct_id', 'distinct_id']
request_payload.person_properties_distinct_id_auto_populated_when_caller_omits_it
Field 'distinct_id' not found in /flags request body at path 'person_properties.distinct_id'. Available keys: ['$os_name', '$os_version', 'email', '$lib_version', '$lib', '$app_namespace', '$device_type']
request_payload.disable_geoip_false_propagates_as_geoip_disable_false
Field 'geoip_disable' not found in /flags request body at path 'geoip_disable'. Available keys: ['$device_id', '$anon_distinct_id', 'groups', 'timezone', 'api_key', 'distinct_id', 'person_properties']
request_payload.disable_geoip_omitted_defaults_to_false
Field 'geoip_disable' not found in /flags request body at path 'geoip_disable'. Available keys: ['timezone', 'person_properties', '$device_id', 'distinct_id', 'groups', 'api_key', '$anon_distinct_id']
request_payload.flag_keys_to_evaluate_contains_only_requested_key
Field 'flag_keys_to_evaluate' not found in /flags request body at path 'flag_keys_to_evaluate'. Available keys: ['api_key', 'timezone', '$device_id', 'person_properties', 'groups', 'distinct_id', '$anon_distinct_id']
|
@ioannisj @turnipdabeets wdyt? this could be in CI as well |
Had me at installIfNeeded() |
|
No familiar at all with dry4swift and can't find it online? Is this under github.com/dryproject? |
https://github.com/marandaneto/dry4swift i have made a similar pr for python PostHog/posthog-python#623 |
|
Reviews (1): Last reviewed commit: "fix: resolve survey build failures" | Re-trigger Greptile |
turnipdabeets
left a comment
There was a problem hiding this comment.
Nice cleanup — this is behavior-preserving as far as I can tell. LGTM!
💡 Motivation and Context
PoC for using
dry4swiftto identify structural duplicate Swift code and apply low-risk deduplication in the iOS SDK.This PR intentionally focuses on mechanical/refactor-only changes where shared helpers reduce duplicate implementation patterns without changing public behavior.
Key examples:
The initial dry4swift candidate count was reduced from 203 to 120 after the POC refactors.
💚 How did you test it?
make formatmake test— 559 tests passeddry4swiftlocally to compare duplicate candidate counts📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file