Skip to content

Conversation

@gazreese
Copy link
Contributor

Cache Functionality Fixes and Comprehensive Test Suite

Overview

This PR addresses critical cache functionality issues in the Flagsmith iOS SDK and adds a comprehensive test suite to ensure cache behavior works correctly across all scenarios.

Problem Statement

The SDK's caching mechanism was not functioning as expected when skipAPI=true was configured. Specifically:

  • Requests were always served via HTTP even when skipAPI=true was set
  • Cache responses were not being properly stored after successful API calls
  • The SDK would fall back to HTTP requests even when valid cached data should have been available

Key Changes

1. APIManager Cache Fixes (FlagsmithClient/Classes/Internal/APIManager.swift)

  • Fixed cache storage: Added ensureResponseIsCached() method to manually store successful responses when URLSession's automatic caching fails
  • Improved cache policy handling: When caching is disabled, responses are no longer cached (returns nil instead of proposed response)
  • Session cache configuration: Properly updates URLSession configuration when cache settings change
  • Cache fallback mechanism: Ensures successful API responses are cached even if URLSession's delegate caching fails

2. SSE Manager Crash Fix (FlagsmithClient/Classes/Internal/SSEManager.swift)

  • Fixed potential crash where completion handler could be nil
  • Added proper null checking before invoking completion handlers in reconnection logic

3. Comprehensive Test Suite

Added over 1,600 lines of thorough cache testing:

CacheTests.swift (737 lines)

  • Unit tests for cache configuration behavior
  • Tests for cache TTL, skipAPI, and useCache settings
  • Validation of cache policy combinations

FlagsmithCacheIntegrationTests.swift (521 lines)

  • Black-box integration tests using only public API
  • End-to-end cache workflow testing
  • TTL behavior validation
  • Multiple identity caching scenarios
  • Real-time updates cache invalidation
  • Analytics with caching interaction

CustomerCacheUseCaseTests.swift (398 lines)

  • Reproduces exact customer-reported issues
  • Tests specific customer configuration (180s TTL, skipAPI=true)
  • Validates session-long cache behavior
  • Edge case testing with multiple identities

CachedURLResponseTests.swift (183 lines)

  • Tests custom cache response expiration logic
  • Validates TTL calculations and cache headers

APIManagerTests.swift (197 lines)

  • Unit tests for APIManager cache behavior
  • Tests manual cache fallback mechanism
  • Validates cache storage for different response types

4. Testing Infrastructure

  • TestConfig.swift: Centralized test configuration with environment variable support for API keys
  • README_Testing.md: Documentation for running cache tests
  • Tests now properly fail when cache functionality is broken (no silent passes)
  • Added requirements for real API keys in integration tests

5. Example App Improvements (Example/FlagsmithClient/SwiftUIView.swift)

  • Enhanced UI for testing cache functionality
  • Added controls for testing skipAPI, cache TTL, and other cache settings
  • Improved visibility into cache behavior for manual testing

Testing

All tests have been updated to:

  • Add proper assertions that fail when functionality doesn't work
  • Require FLAGSMITH_TEST_API_KEY environment variable for integration tests
  • Properly detect and report cache failures

Impact

  • Fixes customer-reported issue where cache wasn't working with skipAPI=true
  • Ensures reliable offline functionality when cache is configured
  • Prevents unnecessary network requests when valid cached data exists
  • Improves SDK reliability with proper null checking in SSE manager

Breaking Changes

None - all changes are backward compatible.

Verification

Run tests with:

export FLAGSMITH_TEST_API_KEY="your-api-key"
swift test

The comprehensive test suite ensures cache functionality works correctly across all supported scenarios.

  • New Features

    • Interactive example app UI for flag testing with identity input, cache controls, and in-app debug logs.
  • Bug Fixes

    • More reliable caching (TTL handling, manual cache fallback, skip-API semantics) and safer realtime reconnection handling.
  • Chores

    • Upgraded project/tooling and deployment targets, podspec version bumped, CI consolidated to a cross-OS Swift matrix, and test config file excluded from VCS to protect real API keys.
  • Tests

    • Extensive new unit and integration tests covering caching, TTLs, skip-API, identity scenarios, and customer repro cases.
  • Documentation

    • Added test guide explaining running tests with real API keys and setup options.

  that expired cache entries are not returned when using
   .returnCacheDataDontLoad policy
The concurrent request test was failing and this solves this issue
@matthewelwell matthewelwell changed the base branch from main to fix/cache-http-header-dependency September 24, 2025 13:01
@matthewelwell matthewelwell requested a review from a team as a code owner September 24, 2025 13:01
@matthewelwell matthewelwell requested review from Zaimwa9 and removed request for a team September 24, 2025 13:01
@matthewelwell matthewelwell merged commit 318fb0d into Flagsmith:fix/cache-http-header-dependency Sep 24, 2025
1 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants