@@ -72,4 +72,36 @@ describe('POST /api/chat/messages validation', () => {
7272 expect ( mocks . userEq ) . toHaveBeenCalledWith ( 'auth_user_id' , 'auth-user-id' ) ;
7373 expect ( mocks . serviceFrom ) . toHaveBeenCalledTimes ( 1 ) ;
7474 } ) ;
75+
76+ it . each ( [
77+ [ 'non-string values' , { 'recipient-1' : { ciphertext : 'not-a-string' } } ] ,
78+ [ 'blank values' , { 'recipient-1' : ' ' } ]
79+ ] ) ( 'rejects encrypted_contents %s before participant lookup' , async ( _label , encrypted_contents ) => {
80+ mocks . serviceFrom . mockImplementation ( ( table ) => {
81+ if ( table === 'users' ) return createUsersQuery ( ) ;
82+ if ( table === 'conversation_participants' ) throw new Error ( 'Participant query should not run' ) ;
83+ throw new Error ( `Unexpected table: ${ table } ` ) ;
84+ } ) ;
85+
86+ const { POST } = await import ( './route.js' ) ;
87+ const response = await POST (
88+ new Request ( 'https://qrypt.chat/api/chat/messages' , {
89+ method : 'POST' ,
90+ headers : {
91+ cookie : 'sb-access-token=valid-token' ,
92+ 'content-type' : 'application/json'
93+ } ,
94+ body : JSON . stringify ( {
95+ conversation_id : 'conversation-1' ,
96+ encrypted_contents
97+ } )
98+ } )
99+ ) ;
100+ const body = await response . json ( ) ;
101+
102+ expect ( response . status ) . toBe ( 400 ) ;
103+ expect ( body . error ) . toBe ( 'encrypted_contents values must be non-empty strings' ) ;
104+ expect ( mocks . userEq ) . toHaveBeenCalledWith ( 'auth_user_id' , 'auth-user-id' ) ;
105+ expect ( mocks . serviceFrom ) . toHaveBeenCalledTimes ( 1 ) ;
106+ } ) ;
75107} ) ;
0 commit comments