@@ -12,7 +12,8 @@ describe("scheduleAdminMessage util", () => {
1212 test ( "schedules a job and handles no event" , ( ) => {
1313 // Mock node-cron
1414 jest . mock ( "node-cron" , ( ) => ( {
15- schedule : ( expr , fn ) => {
15+ schedule : ( expr , fn , options ) => {
16+ expect ( options ) . toEqual ( { timezone : "Asia/Tehran" } ) ;
1617 fn ( ) ; // call immediately for test
1718 return { destroy : jest . fn ( ) } ;
1819 } ,
@@ -26,15 +27,18 @@ describe("scheduleAdminMessage util", () => {
2627 // Mock config
2728 jest . mock ( "../../bot/config/config" , ( ) => ( { ADMIN_GROUP_ID : 123 } ) ) ;
2829
29- const { scheduleAdminMessage } = require ( "../../bot/utils/scheduleMessage" ) ;
30+ const {
31+ scheduleAdminMessage,
32+ } = require ( "../../bot/utils/scheduleMessage" ) ;
3033
3134 expect ( ( ) => scheduleAdminMessage ( bot ) ) . not . toThrow ( ) ;
3235 expect ( mockSendMessage ) . not . toHaveBeenCalled ( ) ;
3336 } ) ;
3437
35- test ( "when event exists, calls sendMessage" , ( ) => {
38+ test ( "when event exists, calls sendMessage with correct formatting " , ( ) => {
3639 jest . mock ( "node-cron" , ( ) => ( {
37- schedule : ( expr , fn ) => {
40+ schedule : ( expr , fn , options ) => {
41+ expect ( options ) . toEqual ( { timezone : "Asia/Tehran" } ) ;
3842 fn ( ) ;
3943 return { destroy : jest . fn ( ) } ;
4044 } ,
@@ -46,20 +50,74 @@ describe("scheduleAdminMessage util", () => {
4650
4751 jest . mock ( "../../bot/config/config" , ( ) => ( { ADMIN_GROUP_ID : 123 } ) ) ;
4852
49- const { scheduleAdminMessage } = require ( "../../bot/utils/scheduleMessage" ) ;
53+ const {
54+ scheduleAdminMessage,
55+ } = require ( "../../bot/utils/scheduleMessage" ) ;
5056
5157 scheduleAdminMessage ( bot ) ;
5258
5359 expect ( mockSendMessage ) . toHaveBeenCalledWith (
5460 123 ,
5561 expect . stringContaining ( "TestTitle" ) ,
62+ expect . objectContaining ( { parse_mode : "MarkdownV2" } )
63+ ) ;
64+ } ) ;
65+
66+ test ( "handles initial sendMessage error and sends error notification" , async ( ) => {
67+ const errorMessage = "sendMessage failed" ;
68+ const firstSendError = new Error ( errorMessage ) ;
69+ let sendMessageCallCount = 0 ;
70+
71+ jest . mock ( "node-cron" , ( ) => ( {
72+ schedule : ( expr , fn , options ) => {
73+ expect ( options ) . toEqual ( { timezone : "Asia/Tehran" } ) ;
74+ return fn ( ) ; // call immediately
75+ } ,
76+ } ) ) ;
77+
78+ jest . mock ( "../../bot/utils/getTodayEvent" , ( ) => ( {
79+ getTodayEvent : ( ) => ( { hasEvent : true , title : "TestTitle" } ) ,
80+ } ) ) ;
81+
82+ jest . mock ( "../../bot/config/config" , ( ) => ( { ADMIN_GROUP_ID : 123 } ) ) ;
83+
84+ // Mock bot that fails first message but succeeds error notification
85+ const botWithRecoverableError = {
86+ telegram : {
87+ sendMessage : jest . fn ( ( ) => {
88+ sendMessageCallCount ++ ;
89+ if ( sendMessageCallCount === 1 ) {
90+ throw firstSendError ;
91+ }
92+ return Promise . resolve ( ) ;
93+ } ) ,
94+ } ,
95+ } ;
96+
97+ const {
98+ scheduleAdminMessage,
99+ } = require ( "../../bot/utils/scheduleMessage" ) ;
100+
101+ expect ( ( ) =>
102+ scheduleAdminMessage ( botWithRecoverableError )
103+ ) . not . toThrow ( ) ;
104+
105+ expect (
106+ botWithRecoverableError . telegram . sendMessage
107+ ) . toHaveBeenCalledTimes ( 2 ) ;
108+ expect (
109+ botWithRecoverableError . telegram . sendMessage
110+ ) . toHaveBeenLastCalledWith (
111+ 123 ,
112+ expect . stringContaining ( errorMessage ) ,
56113 expect . objectContaining ( { parse_mode : "Markdown" } )
57114 ) ;
58115 } ) ;
59116
60- test ( "handles sendMessage error gracefully " , async ( ) => {
117+ test ( "handles both initial and error notification failures " , async ( ) => {
61118 jest . mock ( "node-cron" , ( ) => ( {
62- schedule : ( expr , fn ) => {
119+ schedule : ( expr , fn , options ) => {
120+ expect ( options ) . toEqual ( { timezone : "Asia/Tehran" } ) ;
63121 return fn ( ) ; // call immediately
64122 } ,
65123 } ) ) ;
@@ -70,17 +128,20 @@ describe("scheduleAdminMessage util", () => {
70128
71129 jest . mock ( "../../bot/config/config" , ( ) => ( { ADMIN_GROUP_ID : 123 } ) ) ;
72130
73- // Mock bot.telegram.sendMessage to throw error
74- const botWithError = {
131+ // Mock bot where both messages fail
132+ const botWithTotalError = {
75133 telegram : {
76134 sendMessage : jest . fn ( ( ) => {
77- throw new Error ( "sendMessage failed " ) ;
135+ throw new Error ( "Complete failure " ) ;
78136 } ) ,
79137 } ,
80138 } ;
81139
82- const { scheduleAdminMessage } = require ( "../../bot/utils/scheduleMessage" ) ;
140+ const {
141+ scheduleAdminMessage,
142+ } = require ( "../../bot/utils/scheduleMessage" ) ;
83143
84- expect ( ( ) => scheduleAdminMessage ( botWithError ) ) . not . toThrow ( ) ;
144+ expect ( ( ) => scheduleAdminMessage ( botWithTotalError ) ) . not . toThrow ( ) ;
145+ expect ( botWithTotalError . telegram . sendMessage ) . toHaveBeenCalledTimes ( 2 ) ;
85146 } ) ;
86147} ) ;
0 commit comments