@@ -13,12 +13,15 @@ type SupabaseQuery = {
1313}
1414
1515function makeQuery ( result : any ) {
16- const query = {
16+ const resolved = Promise . resolve ( result )
17+ const query : any = {
1718 select : vi . fn ( ) . mockReturnThis ( ) ,
1819 eq : vi . fn ( ) . mockReturnThis ( ) ,
19- order : vi . fn ( ) . mockResolvedValue ( result ) ,
20+ order : vi . fn ( ) . mockReturnThis ( ) ,
21+ then : resolved . then . bind ( resolved ) ,
22+ catch : resolved . catch . bind ( resolved ) ,
23+ finally : resolved . finally . bind ( resolved ) ,
2024 }
21-
2225 return query as unknown as SupabaseQuery
2326}
2427
@@ -218,4 +221,54 @@ describe('getInitialData — partial failures', () => {
218221 changeDate : '2024-02-01T12:00:00Z' ,
219222 } )
220223 } )
224+
225+ it ( 'returns real consolidation suggestions when subscriptions share a flaggable category' , async ( ) => {
226+ const subscriptionsResult = {
227+ data : [
228+ {
229+ id : 1 , name : 'ChatGPT Plus' , category : 'ai_tools' , price : 20 ,
230+ icon : '🤖' , renews_in : 30 , status : 'active' , color : '#000000' ,
231+ renewal_url : null , tags : [ ] , date_added : '2024-01-01T00:00:00Z' ,
232+ email_account_id : null , last_used_at : null , has_api_key : false ,
233+ is_trial : false , trial_ends_at : null , price_after_trial : null ,
234+ source : 'manual' , manually_edited : false , edited_fields : [ ] ,
235+ pricing_type : 'fixed' , billing_cycle : 'monthly' , cancelled_at : null ,
236+ active_until : null , paused_at : null , resumes_at : null ,
237+ price_range : null , price_history : [ ] ,
238+ } ,
239+ {
240+ id : 2 , name : 'Gemini Advanced' , category : 'ai_tools' , price : 20 ,
241+ icon : '✨' , renews_in : 15 , status : 'active' , color : '#000000' ,
242+ renewal_url : null , tags : [ ] , date_added : '2024-01-01T00:00:00Z' ,
243+ email_account_id : null , last_used_at : null , has_api_key : false ,
244+ is_trial : false , trial_ends_at : null , price_after_trial : null ,
245+ source : 'manual' , manually_edited : false , edited_fields : [ ] ,
246+ pricing_type : 'fixed' , billing_cycle : 'monthly' , cancelled_at : null ,
247+ active_until : null , paused_at : null , resumes_at : null ,
248+ price_range : null , price_history : [ ] ,
249+ } ,
250+ ] ,
251+ error : null ,
252+ }
253+
254+ const fromMock = vi . fn ( ( table : string ) => {
255+ if ( table === 'subscriptions' ) return makeQuery ( subscriptionsResult )
256+ return makeQuery ( { data : [ ] , error : null } )
257+ } )
258+
259+ vi . mocked ( createClient ) . mockResolvedValue ( {
260+ auth : { getUser : vi . fn ( ) . mockResolvedValue ( { data : { user : mockUser } , error : null } ) } ,
261+ from : fromMock ,
262+ } as any )
263+
264+ const result = await getInitialData ( )
265+
266+ expect ( result . consolidationSuggestions ) . toHaveLength ( 1 )
267+ expect ( result . consolidationSuggestions [ 0 ] ) . toMatchObject ( {
268+ id : 'consolidation_ai_tools' ,
269+ category : 'ai tools' ,
270+ services : expect . arrayContaining ( [ 'ChatGPT Plus' , 'Gemini Advanced' ] ) ,
271+ suggestedBundle : 'one AI subscription' ,
272+ } )
273+ } )
221274} )
0 commit comments