@@ -112,7 +112,8 @@ final class FormbricksSDKTests: XCTestCase {
112112
113113 wait ( for: [ trackExpectation] )
114114
115- XCTAssertTrue ( Formbricks . surveyManager? . isShowingSurvey ?? false )
115+ // In headless test environment, presentation fails (no key window), so flag should reset to false
116+ XCTAssertFalse ( Formbricks . surveyManager? . isShowingSurvey ?? true )
116117
117118 // "Dismiss" the webview.
118119 Formbricks . surveyManager? . dismissSurveyWebView ( )
@@ -161,7 +162,8 @@ final class FormbricksSDKTests: XCTestCase {
161162
162163 wait ( for: [ thirdTrackExpectation] )
163164
164- XCTAssertTrue ( Formbricks . surveyManager? . isShowingSurvey ?? false )
165+ // In headless test environment, presentation fails (no key window), so flag should reset to false
166+ XCTAssertFalse ( Formbricks . surveyManager? . isShowingSurvey ?? true )
165167
166168 // Test the cleanup
167169 Formbricks . cleanup ( )
@@ -242,7 +244,8 @@ final class FormbricksSDKTests: XCTestCase {
242244 SurveyLanguage ( enabled: true , isDefault: true , language: LanguageDetail ( id: " 1 " , code: " en " , alias: " english " , projectId: " p1 " ) ) ,
243245 SurveyLanguage ( enabled: true , isDefault: false , language: LanguageDetail ( id: " 2 " , code: " de " , alias: " german " , projectId: " p1 " ) ) ,
244246 SurveyLanguage ( enabled: false , isDefault: false , language: LanguageDetail ( id: " 3 " , code: " fr " , alias: nil , projectId: " p1 " ) )
245- ]
247+ ] ,
248+ projectOverwrites: nil
246249 )
247250 // No language provided
248251 XCTAssertEqual ( manager. getLanguageCode ( survey: survey, language: nil ) , " default " )
@@ -257,4 +260,53 @@ final class FormbricksSDKTests: XCTestCase {
257260 // Alias not found
258261 XCTAssertNil ( manager. getLanguageCode ( survey: survey, language: " spanish " ) )
259262 }
263+
264+ func testWebViewDataUsesSurveyOverwrites( ) {
265+ // Setup SDK with mock service loading Environment.json (which now includes projectOverwrites)
266+ let config = FormbricksConfig . Builder ( appUrl: appUrl, environmentId: environmentId)
267+ . setLogLevel ( . debug)
268+ . service ( mockService)
269+ . build ( )
270+ Formbricks . setup ( with: config)
271+
272+ // Force refresh and wait briefly for async fetch
273+ Formbricks . surveyManager? . refreshEnvironmentIfNeeded ( force: true )
274+ let expectation = self . expectation ( description: " Env loaded " )
275+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + 0.5 ) { expectation. fulfill ( ) }
276+ wait ( for: [ expectation] )
277+
278+ guard let env = Formbricks . surveyManager? . environmentResponse else {
279+ XCTFail ( " Missing environmentResponse " )
280+ return
281+ }
282+
283+ // Build the view model to produce WEBVIEW_DATA
284+ let vm = FormbricksViewModel ( environmentResponse: env, surveyId: surveyID)
285+ guard let html = vm. htmlString else {
286+ XCTFail ( " Missing htmlString " )
287+ return
288+ }
289+
290+ // Extract the JSON payload between backticks in `const json = `...``
291+ guard let markerRange = html. range ( of: " const json = ` " ) else {
292+ XCTFail ( " Marker not found " )
293+ return
294+ }
295+ let start = markerRange. upperBound
296+ guard let end = html [ start... ] . firstIndex ( of: " ` " ) else {
297+ XCTFail ( " End backtick not found " )
298+ return
299+ }
300+ let jsonSubstring = html [ start..< end]
301+ let jsonString = String ( jsonSubstring)
302+ guard let data = jsonString. data ( using: . utf8) ,
303+ let object = try ? JSONSerialization . jsonObject ( with: data) as? [ String : Any ] else {
304+ XCTFail ( " Invalid JSON in WEBVIEW_DATA " )
305+ return
306+ }
307+
308+ // placement should come from survey.projectOverwrites (center), and darkOverlay true
309+ XCTAssertEqual ( object [ " placement " ] as? String , " center " )
310+ XCTAssertEqual ( object [ " darkOverlay " ] as? Bool , true )
311+ }
260312}
0 commit comments