@@ -4,7 +4,11 @@ import { beforeEach, describe, expect, it, jest } from '@jest/globals';
4
4
import fs from 'fs/promises' ;
5
5
import path from 'path' ;
6
6
7
- import { modifyAppDelegateAsync , modifyObjcAppDelegate } from '../src/ios/appDelegate' ;
7
+ import {
8
+ modifyAppDelegateAsync ,
9
+ modifyObjcAppDelegate ,
10
+ modifySwiftAppDelegate ,
11
+ } from '../src/ios/appDelegate' ;
8
12
9
13
describe ( 'Config Plugin iOS Tests' , function ( ) {
10
14
beforeEach ( function ( ) {
@@ -74,17 +78,52 @@ describe('Config Plugin iOS Tests', function () {
74
78
) ;
75
79
} ) ;
76
80
77
- it ( "doesn't support Swift AppDelegate" , async function ( ) {
78
- jest . spyOn ( fs , 'writeFile' ) . mockImplementation ( async ( ) => { } ) ;
81
+ it ( 'supports Swift AppDelegate' , async function ( ) {
82
+ // Use MockedFunction to properly type the mock
83
+ const writeFileMock = jest
84
+ . spyOn ( fs , 'writeFile' )
85
+ . mockImplementation ( async ( ) => { } ) as jest . MockedFunction < typeof fs . writeFile > ;
86
+
87
+ const swiftContents = `import Expo
88
+ import React
89
+
90
+ @UIApplicationMain
91
+ class AppDelegate: ExpoAppDelegate {
92
+ override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
93
+ // Initialize the factory
94
+ let factory = ExpoReactNativeFactory(delegate: delegate)
95
+ factory.startReactNative(withModuleName: "main", in: window, launchOptions: launchOptions)
96
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
97
+ }
98
+ }` ;
79
99
80
100
const appDelegateFileInfo : AppDelegateProjectFile = {
81
- path : '. ' ,
101
+ path : '/app/ios/App/AppDelegate.swift ' ,
82
102
language : 'swift' ,
83
- contents : 'some dummy content' ,
103
+ contents : swiftContents ,
84
104
} ;
85
105
86
- await expect ( modifyAppDelegateAsync ( appDelegateFileInfo ) ) . rejects . toThrow ( ) ;
87
- expect ( fs . writeFile ) . not . toHaveBeenCalled ( ) ;
106
+ await modifyAppDelegateAsync ( appDelegateFileInfo ) ;
107
+
108
+ // Check if writeFile was called
109
+ expect ( writeFileMock ) . toHaveBeenCalled ( ) ;
110
+
111
+ // Get the modified content with explicit string type assertion
112
+ const modifiedContents = writeFileMock . mock . calls [ 0 ] [ 1 ] as string ;
113
+
114
+ // Verify import was added
115
+ expect ( modifiedContents ) . toContain ( 'import RNFBAppCheck' ) ;
116
+
117
+ // Verify initialization code was added
118
+ expect ( modifiedContents ) . toContain ( 'RNFBAppCheckModule.sharedInstance()' ) ;
119
+
120
+ // Verify Firebase.configure() was added
121
+ expect ( modifiedContents ) . toContain ( 'FirebaseApp.configure()' ) ;
122
+
123
+ // Verify the code was added before startReactNative (with explicit type assertion)
124
+ const codeIndex = ( modifiedContents as string ) . indexOf ( 'RNFBAppCheckModule.sharedInstance()' ) ;
125
+ const startReactNativeIndex = ( modifiedContents as string ) . indexOf ( 'factory.startReactNative' ) ;
126
+ expect ( codeIndex ) . toBeLessThan ( startReactNativeIndex ) ;
88
127
} ) ;
89
128
90
129
it ( 'does not add the firebase import multiple times' , async function ( ) {
@@ -104,4 +143,30 @@ describe('Config Plugin iOS Tests', function () {
104
143
expect ( twiceModifiedAppDelegate ) . toContain ( singleImport ) ;
105
144
expect ( twiceModifiedAppDelegate ) . not . toContain ( doubleImport ) ;
106
145
} ) ;
146
+
147
+ it ( 'does not add the swift import multiple times' , async function ( ) {
148
+ const swiftContents = `import Expo
149
+ import React
150
+
151
+ @UIApplicationMain
152
+ class AppDelegate: ExpoAppDelegate {
153
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
154
+ let factory = ExpoReactNativeFactory(delegate: delegate)
155
+ factory.startReactNative(withModuleName: "main", in: window, launchOptions: launchOptions)
156
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
157
+ }
158
+ }` ;
159
+
160
+ const onceModifiedContents = modifySwiftAppDelegate ( swiftContents ) ;
161
+ expect ( onceModifiedContents ) . toContain ( 'import RNFBAppCheck' ) ;
162
+
163
+ // Count occurrences of the import
164
+ const importCount = ( onceModifiedContents . match ( / i m p o r t R N F B A p p C h e c k / g) || [ ] ) . length ;
165
+ expect ( importCount ) . toBe ( 1 ) ;
166
+
167
+ // Modify a second time and ensure imports aren't duplicated
168
+ const twiceModifiedContents = modifySwiftAppDelegate ( onceModifiedContents ) ;
169
+ const secondImportCount = ( twiceModifiedContents . match ( / i m p o r t R N F B A p p C h e c k / g) || [ ] ) . length ;
170
+ expect ( secondImportCount ) . toBe ( 1 ) ;
171
+ } ) ;
107
172
} ) ;
0 commit comments