@@ -220,6 +220,114 @@ describe("onMessagePublished", () => {
220220 expect ( result ) . to . deep . equal ( { test : "data" } ) ;
221221 } ) ;
222222
223+ describe ( "event.data.message wrapping (POJO -> Message instance)" , ( ) => {
224+ const rawMessagePOJO = {
225+ messageId : "pojo-msg-id" ,
226+ data : Buffer . from ( JSON . stringify ( { regression : "test" } ) ) . toString ( "base64" ) ,
227+ attributes : { env : "test" } ,
228+ orderingKey : "key1" ,
229+ publishTime : new Date ( ) . toISOString ( ) ,
230+ } ;
231+
232+ function makeRawEvent (
233+ message : any ,
234+ subscription = "projects/aProject/subscriptions/aSub"
235+ ) : CloudEvent < any > {
236+ return {
237+ specversion : "1.0" ,
238+ source : "//pubsub.googleapis.com/projects/aProject/topics/topic" ,
239+ id : "raw-event-id" ,
240+ type : EVENT_TRIGGER . eventType ,
241+ time : rawMessagePOJO . publishTime ,
242+ data : { message, subscription } ,
243+ } ;
244+ }
245+
246+ it ( "should convert a raw POJO message into a Message instance on event.data.message" , async ( ) => {
247+ let capturedMessage : any ;
248+ const func = pubsub . onMessagePublished ( "topic" , ( event ) => {
249+ capturedMessage = event . data . message ;
250+ } ) ;
251+
252+ // Pass a raw POJO, NOT a Message instance — this is what the runtime delivers
253+ await func ( makeRawEvent ( { ...rawMessagePOJO } ) ) ;
254+
255+ expect ( capturedMessage ) . to . be . an . instanceOf ( pubsub . Message ) ;
256+ } ) ;
257+
258+ it ( "should provide a working .json getter on event.data.message when input is a raw POJO" , async ( ) => {
259+ let json : unknown ;
260+ const func = pubsub . onMessagePublished ( "topic" , ( event ) => {
261+ json = event . data . message . json ;
262+ } ) ;
263+
264+ await func ( makeRawEvent ( { ...rawMessagePOJO } ) ) ;
265+
266+ expect ( json ) . to . deep . equal ( { regression : "test" } ) ;
267+ } ) ;
268+
269+ it ( "should preserve all Message fields when wrapping a raw POJO" , async ( ) => {
270+ let msg : any ;
271+ const func = pubsub . onMessagePublished ( "topic" , ( event ) => {
272+ msg = event . data . message ;
273+ } ) ;
274+
275+ await func ( makeRawEvent ( { ...rawMessagePOJO } ) ) ;
276+
277+ expect ( msg . messageId ) . to . equal ( "pojo-msg-id" ) ;
278+ expect ( msg . data ) . to . equal ( rawMessagePOJO . data ) ;
279+ expect ( msg . attributes ) . to . deep . equal ( { env : "test" } ) ;
280+ expect ( msg . orderingKey ) . to . equal ( "key1" ) ;
281+ expect ( msg . publishTime ) . to . equal ( rawMessagePOJO . publishTime ) ;
282+ } ) ;
283+
284+ it ( "should not re-wrap if event.data.message is already a Message instance" , async ( ) => {
285+ const original = new pubsub . Message ( rawMessagePOJO ) ;
286+ let capturedMessage : any ;
287+ const func = pubsub . onMessagePublished ( "topic" , ( event ) => {
288+ capturedMessage = event . data . message ;
289+ } ) ;
290+
291+ await func ( makeRawEvent ( original ) ) ;
292+
293+ expect ( capturedMessage ) . to . equal ( original ) ; // same reference
294+ expect ( capturedMessage . json ) . to . deep . equal ( { regression : "test" } ) ;
295+ } ) ;
296+
297+ it ( "should throw on a malformed event without a message property" , async ( ) => {
298+ const func = pubsub . onMessagePublished ( "topic" , ( ) => undefined ) ;
299+ const badEvent : CloudEvent < any > = {
300+ specversion : "1.0" ,
301+ source : "//pubsub.googleapis.com/projects/aProject/topics/topic" ,
302+ id : "bad-event" ,
303+ type : EVENT_TRIGGER . eventType ,
304+ time : new Date ( ) . toISOString ( ) ,
305+ data : { subscription : "sub" } , // no message!
306+ } ;
307+
308+ try {
309+ await func ( badEvent ) ;
310+ expect . fail ( "should have thrown" ) ;
311+ } catch ( err : any ) {
312+ expect ( err . message ) . to . match ( / m i s s i n g ' m e s s a g e ' p r o p e r t y / i) ;
313+ }
314+ } ) ;
315+
316+ it ( "should make event.data.message.json and event.message.json return the same value" , async ( ) => {
317+ let v2Json : unknown ;
318+ let v1Json : unknown ;
319+ const func = pubsub . onMessagePublished ( "topic" , ( event ) => {
320+ v2Json = event . data . message . json ;
321+ v1Json = ( event as any ) . message . json ;
322+ } ) ;
323+
324+ await func ( makeRawEvent ( { ...rawMessagePOJO } ) ) ;
325+
326+ expect ( v2Json ) . to . deep . equal ( { regression : "test" } ) ;
327+ expect ( v1Json ) . to . deep . equal ( { regression : "test" } ) ;
328+ } ) ;
329+ } ) ;
330+
223331 describe ( "v1-compatible getters" , ( ) => {
224332 let capturedEvent : any ;
225333 const messageData = {
0 commit comments