@@ -65,7 +65,7 @@ describe('ObjectQLPlugin - Metadata Service Integration', () => {
6565 } ) ;
6666
6767 describe ( 'Service Registration' , ( ) => {
68- it ( 'should register objectql, data, and protocol services ' , async ( ) => {
68+ it ( 'should register manifest service ' , async ( ) => {
6969 // Arrange
7070 const plugin = new ObjectQLPlugin ( ) ;
7171 await kernel . use ( plugin ) ;
@@ -77,6 +77,7 @@ describe('ObjectQLPlugin - Metadata Service Integration', () => {
7777 expect ( kernel . getService ( 'objectql' ) ) . toBeDefined ( ) ;
7878 expect ( kernel . getService ( 'data' ) ) . toBeDefined ( ) ;
7979 expect ( kernel . getService ( 'protocol' ) ) . toBeDefined ( ) ;
80+ expect ( kernel . getService ( 'manifest' ) ) . toBeDefined ( ) ;
8081 } ) ;
8182
8283 it ( 'should respect existing metadata service' , async ( ) => {
@@ -146,8 +147,71 @@ describe('ObjectQLPlugin - Metadata Service Integration', () => {
146147 expect ( objectql . drivers ?. has ( 'mock-driver' ) ) . toBe ( true ) ;
147148 } ) ;
148149
149- it ( 'should discover and register apps from kernel services ' , async ( ) => {
150+ it ( 'should register apps via manifest service ' , async ( ) => {
150151 // Arrange
152+ const plugin = new ObjectQLPlugin ( ) ;
153+ await kernel . use ( plugin ) ;
154+
155+ // Plugin that uses the manifest service directly
156+ await kernel . use ( {
157+ name : 'mock-app-plugin' ,
158+ type : 'app' ,
159+ version : '1.0.0' ,
160+ dependencies : [ 'com.objectstack.engine.objectql' ] ,
161+ init : async ( ctx ) => {
162+ ctx . getService < { register ( m : any ) : void } > ( 'manifest' ) . register ( {
163+ id : 'test-app' ,
164+ name : 'test_app' ,
165+ version : '1.0.0' ,
166+ type : 'app' ,
167+ apps : [ { name : 'Test App' } ] ,
168+ } ) ;
169+ }
170+ } ) ;
171+
172+ // Act
173+ await kernel . bootstrap ( ) ;
174+
175+ // Assert
176+ const objectql = kernel . getService ( 'objectql' ) as any ;
177+ expect ( objectql . registry ) . toBeDefined ( ) ;
178+ const apps = objectql . registry . getAllApps ( ) ;
179+ expect ( apps . some ( ( a : any ) => a . name === 'Test App' ) ) . toBe ( true ) ;
180+ } ) ;
181+
182+ it ( 'should register manifests from start() phase via manifest service' , async ( ) => {
183+ // Arrange — simulates SetupPlugin's pattern (registers in start, not init)
184+ const plugin = new ObjectQLPlugin ( ) ;
185+ await kernel . use ( plugin ) ;
186+
187+ await kernel . use ( {
188+ name : 'late-registerer' ,
189+ type : 'standard' ,
190+ version : '1.0.0' ,
191+ dependencies : [ 'com.objectstack.engine.objectql' ] ,
192+ init : async ( ) => { } ,
193+ start : async ( ctx ) => {
194+ ctx . getService < { register ( m : any ) : void } > ( 'manifest' ) . register ( {
195+ id : 'late-app' ,
196+ name : 'late_app' ,
197+ version : '1.0.0' ,
198+ type : 'plugin' ,
199+ apps : [ { name : 'Late App' } ] ,
200+ } ) ;
201+ }
202+ } ) ;
203+
204+ // Act
205+ await kernel . bootstrap ( ) ;
206+
207+ // Assert
208+ const objectql = kernel . getService ( 'objectql' ) as any ;
209+ const apps = objectql . registry . getAllApps ( ) ;
210+ expect ( apps . some ( ( a : any ) => a . name === 'Late App' ) ) . toBe ( true ) ;
211+ } ) ;
212+
213+ it ( 'should still discover apps registered via legacy app.* convention' , async ( ) => {
214+ // Arrange — legacy pattern for backward compatibility
151215 const mockApp = {
152216 manifest : {
153217 id : 'test-app' ,
@@ -172,9 +236,8 @@ describe('ObjectQLPlugin - Metadata Service Integration', () => {
172236 // Act
173237 await kernel . bootstrap ( ) ;
174238
175- // Assert
239+ // Assert — legacy pattern still works
176240 const objectql = kernel . getService ( 'objectql' ) as any ;
177- // App should be registered (check via registry or apps list)
178241 expect ( objectql . registry ) . toBeDefined ( ) ;
179242 } ) ;
180243 } ) ;
0 commit comments