11import { afterEach , describe , expect , it , vi } from 'vitest'
2- import { Peer , PeerManager , type ExtensionStatePort , type InstalledExtension } from '@inkcre/core'
2+ import {
3+ Cron ,
4+ Peer ,
5+ PeerManager ,
6+ Source ,
7+ SourceForm ,
8+ type ExtensionStatePort ,
9+ type InstalledExtension ,
10+ } from '@inkcre/core'
311import {
412 discoverCoreCandidates ,
513 OAuthTransactionSchema ,
14+ TwitterBookmarkSetup ,
615 TwitterSetupAPI ,
716 TwitterSetupStatusSchema ,
817} from '../../../extensions/twitter/src/setup-api'
918
1019const corePeerId = '00000000-0000-4000-8000-000000000002'
1120const installed : InstalledExtension = {
1221 name : 'inkcre/twitter' ,
13- version : '0.2.0 ' ,
22+ version : '0.2.1 ' ,
1423 enabled : [ corePeerId ] ,
1524 nickname : 'Twitter' ,
1625 config : { } ,
@@ -28,7 +37,7 @@ const corePeer = Peer.parse({
2837 inbound : { protocol : 'core.peer.protocol.http.v1' , parameters : { } } ,
2938 } ,
3039 {
31- id : 'inkcre.twitter.setup.v1' ,
40+ id : 'inkcre.twitter.setup.status. v1' ,
3241 inbound : { protocol : 'core.peer.protocol.http.v1' , parameters : { } } ,
3342 } ,
3443 ] ,
@@ -70,20 +79,14 @@ describe('Twitter Peer setup API', () => {
7079 handle : null ,
7180 scopes : [ ] ,
7281 reconnect_required : false ,
73- bookmark_source_id : null ,
74- bookmark_cron_id : null ,
75- bookmark_sources : [ ] ,
76- collect_at : { day_of_week : null , hour : 0 , minute : 0 } ,
77- bookmark_source_ready : false ,
78- ready : false ,
7982 } ,
8083 } )
8184
8285 await new TwitterSetupAPI ( corePeer ) . status ( )
8386
8487 expect ( delegate ) . toHaveBeenCalledWith (
85- 'inkcre.twitter.setup.v1' ,
86- { body : { action : 'get_status' } } ,
88+ 'inkcre.twitter.setup.status. v1' ,
89+ { body : { } } ,
8790 corePeerId
8891 )
8992 } )
@@ -100,12 +103,6 @@ describe('Twitter Peer setup API', () => {
100103 handle : null ,
101104 scopes : [ ] ,
102105 reconnect_required : false ,
103- bookmark_source_id : null ,
104- bookmark_cron_id : null ,
105- bookmark_sources : [ ] ,
106- collect_at : { day_of_week : null , hour : 0 , minute : 0 } ,
107- bookmark_source_ready : false ,
108- ready : false ,
109106 } )
110107 ) . toThrow ( 'HTTP or HTTPS' )
111108 expect ( ( ) =>
@@ -127,4 +124,49 @@ describe('Twitter Peer setup API', () => {
127124 } )
128125 ) . toThrow ( 'embedded credentials' )
129126 } )
127+
128+ it ( 'composes bookmark Source, Cron, and initial Job through ordinary database models' , async ( ) => {
129+ const source = Source . parse ( {
130+ id : 25 ,
131+ type : 'extensions.twitter.bookmark.Source' ,
132+ nickname : 'Bookmarks' ,
133+ config : { } ,
134+ state : { } ,
135+ storage : null ,
136+ block : null ,
137+ created_at : '2026-01-01T00:00:00Z' ,
138+ updated_at : '2026-01-01T00:00:00Z' ,
139+ } )
140+ const cron = Cron . parse ( {
141+ id : 9 ,
142+ schedule : '30 6 * * *' ,
143+ enabled : false ,
144+ job_type : 'core.source.collect.v1' ,
145+ job_parameters : { source : 25 , config : { full : false , result_limit : 40 } } ,
146+ job_timeout_seconds : null ,
147+ last_job : null ,
148+ last_scheduled_for : null ,
149+ created_at : '2026-01-01T00:00:00Z' ,
150+ updated_at : '2026-01-01T00:00:00Z' ,
151+ } )
152+ vi . spyOn ( Source , 'getAll' ) . mockResolvedValue ( [ source ] )
153+ vi . spyOn ( Cron , 'getBySource' ) . mockResolvedValue ( [ cron ] )
154+ vi . spyOn ( SourceForm . prototype , 'create' ) . mockResolvedValue ( source )
155+ const update = vi
156+ . spyOn ( Cron . prototype , 'update' )
157+ . mockImplementation ( async ( form ) =>
158+ Cron . parse ( { ...cron , ...form , id : cron . id , enabled : form . enabled } )
159+ )
160+ const runNow = vi . spyOn ( Cron . prototype , 'runNow' ) . mockResolvedValue ( { } as never )
161+
162+ await expect ( TwitterBookmarkSetup . read ( ) ) . resolves . toMatchObject ( { source, cron } )
163+ await expect ( TwitterBookmarkSetup . createSource ( 'Bookmarks' ) ) . resolves . toBe ( source )
164+ const scheduled = await TwitterBookmarkSetup . saveSchedule ( source , 7 , 15 )
165+ expect ( update ) . toHaveBeenLastCalledWith (
166+ expect . objectContaining ( { schedule : '15 7 * * *' , enabled : false } )
167+ )
168+ await TwitterBookmarkSetup . finish ( source , scheduled )
169+ expect ( update ) . toHaveBeenLastCalledWith ( expect . objectContaining ( { enabled : true } ) )
170+ expect ( runNow ) . toHaveBeenCalledOnce ( )
171+ } )
130172} )
0 commit comments